# xAI Collections — RAG knowledge bases (management endpoints + `/v1/documents/search` + `file_search` tool) **Status:** `DOCUMENTED` · `ACCOUNT_RESTRICTED` on the documented base (management-api.x.ai → 401 "Invalid bearer token. Please ensure you use a valid management key." with our inference key) · **`LIVE_DISCOVERED` + `LIVE_VERIFIED`: the same `/v1/collections*` paths are served on `https://api.x.ai` with the inference key** (create/list/get/delete 200, add document 200, list/get document 200) · `/v1/documents/search` `FAILED_VERIFICATION` (404 while the only document was still indexing; no processed collection within the probe window). Machine-readable: `parameters/xai-files-collections-batches.json`, `endpoints/xai-inference.json`, `objects/xai-inference-objects.json` (Collection, Document, SearchMatch), `tools/xai-tools.json` (file_search). **Sources:** https://docs.x.ai/developers/rest-api-reference/collections/collection (Management API) · https://docs.x.ai/developers/rest-api-reference/collections/search · https://docs.x.ai/developers/files/collections · https://docs.x.ai/developers/files/collections/api · https://docs.x.ai/developers/files/collections/metadata · https://docs.x.ai/developers/tools/collections-search · OpenAPI `SearchRequest`, `SearchResponse`, `DocumentsSource`, `RetrievalMode` **Last verified:** 2026-09-19 ## Concepts Collection = group of Files-API files with an embedding index (`grok-embedding-small` default; chunking configurable; metadata `field_definitions` with `required`/`unique`/`inject_into_chunk`). One file may belong to several collections. Max file 100 MB (collections guide). Storage $0.10/GiB/day; downloads $0.20/GiB; `file_search`/`collections_search` tool $2.50 per 1k calls. Documents must reach `DOCUMENT_STATUS_PROCESSED` before search works. ## Management endpoints Documented base **`https://management-api.x.ai`** + **Management API key** (`AddFileToCollection` permission etc., created in Console → Management Keys). Live: every path below also answered on **`https://api.x.ai`** with the ordinary inference key, but with gRPC-gateway strictness — path ids must be **repeated in the JSON body**, and some documented-optional fields are required. | Method | Path | Body (live requirements on api.x.ai) | Live | |---|---|---|---| | POST | `/v1/collections` | `{collection_name, field_definitions: [] ← required (422 otherwise), collection_description?, index_configuration.model_name?, chunk_configuration?, metric_space?}`; each field definition needs `key, required, inject_into_chunk, unique` (+`description`) | 200 `collection_` | | GET | `/v1/collections` | `limit ≤100, order, sort_by, pagination_token, filter, team_id` | 200 `{collections[], pagination_token}` | | GET | `/v1/collections/{id}` | | 200 (many undocumented fields: `sharing`, `effective_privilege`, `is_owned`, `owner_team_id`, `total_file_size`, `disable_rag_lookup`, `enable_wiki_summary_generation`, `cloned_from_id`, …; `chunk_configuration.config.BytesConfiguration {4000, 800}`) | | PUT | `/v1/collections/{id}` | `{collection_id, collection_name?, collection_description?, chunk_configuration?, field_definition_updates: [{field_definition, operation: FIELD_DEFINITION_ADD\|DELETE}]}` — live needs `collection_id` AND `field_definition_updates` | 422 (not completed) | | DELETE | `/v1/collections/{id}` | | 200 `{}` | | POST | `/v1/collections/{id}/documents/{file_id}` | `{collection_id, file_id, fields?}` (both ids required in body live) | 200 `{}`; indexing async | | POST | `/v1/collections/{id}/documents` | guide-only multipart (`name`, `data`, `content_type`, `fields`) on management-api | api.x.ai → 405 | | GET | `/v1/collections/{id}/documents` | `limit, order, sort_by (NAME\|SIZE\|AGE), pagination_token, filter, name (deprecated)` | 200 | | GET | `/v1/collections/{id}/documents/{file_id}` | | 200 — **`status` returned as integer `1` (PROCESSING) instead of the documented string enum**; extra `chunk_count`, `chunks_processed_count`, `file_metadata.processing_status:"Processing"` | | PATCH | `/v1/collections/{id}/documents/{file_id}` | reindex | not called | | DELETE | `/v1/collections/{id}/documents/{file_id}` | | 200 `{}` — **hazard: the underlying file was deleted too** (`GET /v1/files/{id}` → 404), even when the document had never been added | | GET | `/v1/collections/{id}/documents:batchGet?file_ids=…` | | 400 (query encoding `file_ids=` "expected a sequence", `file_ids[]=` "missing field") | Document status enum (docs): `DOCUMENT_STATUS_UNKNOWN | PROCESSING | PROCESSED | FAILED`. Live a 208-byte txt was still processing after 75 s / 25 polls. ## Search: `POST /v1/documents/search` (api.x.ai, inference key) Body: `query` (required), `source.collection_ids[]` (required; `source.rag_pipeline` chroma_db\|es), `limit` (10), `filter` (AIP-160 over metadata: `author = "John"`, `year > 2020 AND …`, ranges `field:10..20`), `retrieval_mode` `{type: hybrid|semantic|keyword, reranker?: {model, instructions} | RRF {embedding_weight, text_weight, k}, search_multiplier?}`, `group_by {keys[], aggregate: min_k|max_k}`, `instructions`, `ranking_metric` (deprecated). Response `{matches[]: {file_id, chunk_id, chunk_content, score, collection_ids[], fields{}, page_number}}`. Live: fake id → 404 `not found or not accessible`; `[]` → 400 `Collection IDs cannot be empty`; fresh collection (document processing) → same 404. Default mode hybrid. ## Agentic search: `file_search` tool (Responses) `{"type":"file_search","vector_store_ids":["collection_…"],"max_num_results":10}` (alias `collections_search`, echoed as `file_search`; `vector_store_ids` required — 422 otherwise). Output item `file_search_call {queries[], results[] (with include:["file_search_call.results"]), status}`; citations `collections:///files/`. Live (un-indexed collection): `status:"failed"`, `results: []`, answer "No documents." — see [docs/tools/xai/collections-search.md](../tools/xai/collections-search.md). ## SDK xai-sdk: `Client(api_key, management_api_key)`, `client.collections.create/list/get/update/delete`, `upload_document(collection_id, name, data, fields)`, `get_document`, `remove_document`, `search(query, collection_ids)`; proto enum `collections_pb2.DOCUMENT_STATUS_PROCESSED`. Examples: `examples/xai/collections/` (create → add file → poll → search → cleanup; expects 404 on search until indexed).