POST
/v1/vector_storesVector Stores
Managed RAG indexes. Create a store, attach files (single or batched), watch their ingest status, run queries through file_search inside an Assistants Run, and (later) migrate the whole store to a different embedding model. Wire shape mirrors OpenAI /v1/vector_stores. Cross-tenant access returns 404 (not 403) so customer IDs stay non-enumerable.
Request
- HTTP
- POST
- URL
- /v1/vector_stores
- Auth
- api_key
Try it
# Stores ─────────────────────────────────────────────────────────
# Create
curl https://api.fightclub.pro/v1/vector_stores \
-H "Authorization: Bearer $FC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"acme-handbook","embedding_model":"text-embedding-3-small"}'
# Create with GraphRAG on (or PATCH graphrag_enabled later). file_search then
# returns a "facts" array of graph relationships next to the chunk citations:
# { "results": [...], "facts": [{"subject":"PartX","predicate":"supplied_by","object":"Acme"}] }
curl https://api.fightclub.pro/v1/vector_stores \
-H "Authorization: Bearer $FC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"acme-handbook","embedding_model":"text-embedding-3-small","graphrag_enabled":true}'
# List (paginated by created_at desc)
curl https://api.fightclub.pro/v1/vector_stores \
-H "Authorization: Bearer $FC_API_KEY"
# Retrieve one
curl https://api.fightclub.pro/v1/vector_stores/vs_abc \
-H "Authorization: Bearer $FC_API_KEY"
# Update (name and/or metadata)
curl -X PATCH https://api.fightclub.pro/v1/vector_stores/vs_abc \
-H "Authorization: Bearer $FC_API_KEY" \
-d '{"metadata":{"owner":"support-team"}}'
# Delete (soft — flips status to deleting; janitor reaps the Weaviate tenant)
curl -X DELETE https://api.fightclub.pro/v1/vector_stores/vs_abc \
-H "Authorization: Bearer $FC_API_KEY"
# Files ──────────────────────────────────────────────────────────
# Attach a previously uploaded file (idempotent on (store, file))
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/files \
-H "Authorization: Bearer $FC_API_KEY" \
-d '{"file_id":"file_xyz"}'
# List files
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/files \
-H "Authorization: Bearer $FC_API_KEY"
# Retrieve one (poll for status=completed before querying)
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/files/file_xyz \
-H "Authorization: Bearer $FC_API_KEY"
# Detach
curl -X DELETE https://api.fightclub.pro/v1/vector_stores/vs_abc/files/file_xyz \
-H "Authorization: Bearer $FC_API_KEY"
# Cancel a still-pending ingest, or retry a failed/cancelled one
curl -X POST https://api.fightclub.pro/v1/vector_stores/vs_abc/files/file_xyz/cancel \
-H "Authorization: Bearer $FC_API_KEY"
curl -X POST https://api.fightclub.pro/v1/vector_stores/vs_abc/files/file_xyz/retry \
-H "Authorization: Bearer $FC_API_KEY"
# File batches ───────────────────────────────────────────────────
# Create a batch (≤ 500 file_ids)
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/file_batches \
-H "Authorization: Bearer $FC_API_KEY" \
-d '{"file_ids":["file_1","file_2","file_3"]}'
# Retrieve / cancel a batch
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/file_batches/vsfb_xyz \
-H "Authorization: Bearer $FC_API_KEY"
curl -X POST https://api.fightclub.pro/v1/vector_stores/vs_abc/file_batches/vsfb_xyz/cancel \
-H "Authorization: Bearer $FC_API_KEY"
# Observability ──────────────────────────────────────────────────
# Query log (cursor pagination via after=…; since=ISO-8601)
curl "https://api.fightclub.pro/v1/vector_stores/vs_abc/queries?limit=50" \
-H "Authorization: Bearer $FC_API_KEY"
# Aggregated stats (window = 24h | 7d | 30d, default 24h)
curl "https://api.fightclub.pro/v1/vector_stores/vs_abc/stats?window=7d" \
-H "Authorization: Bearer $FC_API_KEY"
# Embedding-model migrations ─────────────────────────────────────
# Start a migration (background re-embed against cached parses; atomic index swap)
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/migrate \
-H "Authorization: Bearer $FC_API_KEY" \
-d '{"embedding_model":"text-embedding-3-large"}'
# List / retrieve / rollback migrations
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/migrations \
-H "Authorization: Bearer $FC_API_KEY"
curl https://api.fightclub.pro/v1/vector_stores/vs_abc/migrations/mig_xyz \
-H "Authorization: Bearer $FC_API_KEY"
curl -X POST https://api.fightclub.pro/v1/vector_stores/vs_abc/migrations/mig_xyz/rollback \
-H "Authorization: Bearer $FC_API_KEY"Example response
{
"id": "vs_abc123",
"object": "vector_store",
"name": "acme-handbook",
"embedding_model": "text-embedding-3-small",
"embedding_dimensions": null,
"graphrag_enabled": false,
"encryption": "none",
"vector_sealing": "none",
"vector_index": "auto",
"status": "active",
"file_counts": { "total": 0 },
"bytes": 0,
"metadata": {},
"created_at": 1782300000
}A representative 200 body. Ids and timestamps are illustrative.
Body parameters
| Name | Type | Default | Description |
|---|---|---|---|
| name* | string | — | Store display name. Max 256 bytes. |
| embedding_model* | string | — | One of: text-embedding-3-small | text-embedding-3-large | text-embedding-ada-002 | embed-english-v3.0 | embed-multilingual-v3.0 | voyage-3-large | voyage-3-lite | mistral-embed | text-embedding-004. Fixed at create time, change via POST /v1/vector_stores/{id}/migrate. |
| dimensions | integer | optional | Optional embedding-dimension override for models that support it. Positive integer. |
| graphrag_enabled | boolean | false | Opt this store into GraphRAG. When true, ingest also builds a knowledge graph of the entities across your files; file_search then returns a "facts" array of {subject, predicate, object} relationships next to the chunk citations, surfacing answers spread across documents that nearest-chunk vector search misses. Settable at create or via PATCH; if the graph has nothing relevant you get normal vector results. Bills as its own per-GB-day storage line (first 1 GB-day per store per day free) — leave it off and you pay nothing extra. |
| encryption | string | none | none | managed | byok. managed = Ringside holds the data key. byok = you supply a passphrase (see key) and we never persist it; the store locks when no key lease is active. Sealed stores keep chunk text + vectors encrypted at rest. |
| vector_sealing | string | full | For a sealed (managed/byok) store: none | source | full. source seals the original chunk text only; full also seals the vectors. Defaults to full when encryption is set; ignored when encryption is none. |
| vector_index | string | auto | auto | flat | ivf. ivf (inverted-file, faster cold search on big sealed stores) requires encryption to be set. auto picks flat unless the store is large. |
| key | object | optional | Required when encryption=byok: { type:"passphrase", passphrase:"<>=12 chars>" }. The passphrase is used to derive the data key and is never stored. |
| metadata | object | optional | Free-form JSON metadata. Max 4 KiB serialized. |
* required.
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 20 | Page size on GET /v1/vector_stores. |
| after | string | optional | Cursor: last store id from the previous page. |
| window | string | 7d | On GET .../stats: 24h | 7d | 30d aggregation window. |
| since | string | optional | On GET .../queries: ISO-8601 lower bound on the query log. |
Headers
| Header | Dir | Description |
|---|---|---|
| FC-Vector-Store-Key | req → | For a byok store: the passphrase, presented to take a short-lived key lease so ingest/query can run. Never persisted. |
Response fields
| Name | Type | Description |
|---|---|---|
| id | string | Store ID (vs_*). |
| object | string | Always "vector_store". |
| name | string | Display name. |
| embedding_model | string | Embedding model in use. |
| embedding_dimensions | integer | null | Dimension override if set at create time. |
| graphrag_enabled | boolean | Whether this store has GraphRAG opted in. |
| encryption | string | none | managed | byok. |
| vector_sealing | string | none | source | full (the sealing level in effect). |
| vector_index | string | auto | flat | ivf. |
| status | string | active | suspended | deleting | deleted (a byok store also reports locked when no key lease is active). |
| file_counts | object | { total } file count. |
| bytes | integer | Total bytes stored across all attached files. |
| metadata | object | Free-form metadata. |
| created_at | integer | Unix timestamp. |
Errors
- 401
missing_tokenNo Authorization header was sent. - 401
invalid_auth_schemeThe scheme was neither Bearer nor Client. - 401
invalid_token_formatA Bearer token not prefixed ko_. - 401
invalid_tokenThe API key is unknown, revoked or expired. - 403
insufficient_scopeThe key is valid but lacks the required scope. - 400
invalid_namename is empty. - 400
name_too_longname exceeds 256 bytes. - 400
invalid_embedding_modelembedding_model not in the supported set. - 400
invalid_dimensionsdimensions must be a positive integer. - 400
invalid_encryptionencryption must be none, managed or byok. - 400
invalid_vector_sealingvector_sealing must be none, source or full. - 400
invalid_vector_indexvector_index must be auto, flat or ivf. - 400
ivf_requires_encryptionvector_index=ivf needs a sealed (encrypted) store. - 400
byok_key_requiredencryption=byok without a key object. - 400
byok_passphrase_too_shortbyok passphrase under 12 chars. - 400
byok_kms_unavailablebyok KMS backend is not configured/available. - 400
invalid_metadatametadata must be a JSON object (not array or primitive). - 400
metadata_too_largemetadata exceeds 4096 bytes when serialized. - 404
vector_store_not_foundNo such store (also returned for cross-tenant access). - 409
vector_store_unavailableStore is in deleting or deleted state. - 400
not_a_byok_storeLock and unlock apply to byok stores only. - 402
vector_store_suspendedStore is suspended for non-payment. - 404
vector_store_file_not_foundFile row not attached to this store. - 404
file_not_foundReferenced file_id does not belong to you. - 409
file_not_cancellablePOST .../cancel against a file that is not pending or in_progress. - 409
file_not_retryablePOST .../retry against a file that is not failed or cancelled. - 400
invalid_file_idsfile_batches POST: file_ids must be a non-empty array. - 400
too_many_filesfile_batches POST: at most 500 files per batch. - 404
file_batch_not_foundUnknown batch_id under the given store. - 400
missing_embedding_modelPOST .../migrate without embedding_model.
See the full error reference.
Related routes
| GET | /v1/vector_stores | List stores (cursor pagination by created_at desc). |
| GET | /v1/vector_stores/{id} | Retrieve one store. |
| PATCH | /v1/vector_stores/{id} | Update name, metadata or graphrag_enabled. |
| DELETE | /v1/vector_stores/{id} | Soft-delete (status -> deleting; the janitor reaps the tenant). |
| POST | /v1/vector_stores/{id}/lock | byok: drop the key lease and lock the store now. |
| POST | /v1/vector_stores/{id}/unlock | byok: present the passphrase to take a key lease. |
| POST | /v1/vector_stores/{id}/files | Attach a file (idempotent on (store, file)). |
| GET | /v1/vector_stores/{id}/files | List attached files + ingest status. |
| GET | /v1/vector_stores/{id}/files/{fileId} | Retrieve one file row (poll for status=completed). |
| DELETE | /v1/vector_stores/{id}/files/{fileId} | Detach a file. |
| POST | /v1/vector_stores/{id}/files/{fileId}/cancel | Cancel a pending/in-progress ingest. |
| POST | /v1/vector_stores/{id}/files/{fileId}/retry | Retry a failed/cancelled ingest. |
| POST | /v1/vector_stores/{id}/file_batches | Attach up to 500 files in one batch. |
| GET | /v1/vector_stores/{id}/file_batches/{batchId} | Retrieve a batch. |
| POST | /v1/vector_stores/{id}/file_batches/{batchId}/cancel | Cancel a batch. |
| GET | /v1/vector_stores/{id}/queries | Query log (cursor: after; since=ISO-8601; limit default 50, max 200). |
| GET | /v1/vector_stores/{id}/stats | Aggregated stats (window 24h|7d|30d). |
| POST | /v1/vector_stores/{id}/migrate | Re-embed the whole store to a new embedding_model (atomic index swap). |
| GET | /v1/vector_stores/{id}/migrations | List migrations. |
| GET | /v1/vector_stores/{id}/migrations/{migration_id} | Retrieve one migration. |
| POST | /v1/vector_stores/{id}/migrations/{migration_id}/rollback | Roll back to the prior embedding model. |
Notes
- ·File ingest is async: attach a file, then poll its row until status=completed (pending | in_progress | completed | failed | cancelled) before querying.
- ·You query a store via file_search inside an Assistants Run, not a direct query endpoint: attach it with tool_resources.file_search.vector_store_ids.
- ·embedding_model is fixed at create; change it by running a migration, which re-embeds against cached parses and swaps the index atomically (rollback available).
- ·Sealed stores (encryption=managed|byok) keep chunk text and (with vector_sealing=full) vectors encrypted at rest. byok never persists your passphrase: take a lease via /unlock or the FC-Vector-Store-Key header, and the store idle-locks otherwise.
- ·Cross-tenant access returns 404, not 403, so store ids are not enumerable.