Upload a file
Upload the file withmultipart/form-data.
The live OpenAPI spec requires file and purpose.
Note: multipart file parts must include a nonblank filename. The lowercase WHATWG placeholder filename "blob" is treated as missing.
file object with an ID such as file-abc123.
Create a vector store
Create a vector store and attach one or more uploaded file IDs.vs_abc123.
Create a graph store
Setretrieval_mode to "graph" to get graph-aware retrieval instead of plain vector similarity.
On a graph store, entities and relations are extracted from every chunk at ingest to build a knowledge graph, and search traverses that graph to collect connected evidence rather than returning the nearest chunks alone.
The gains show up on questions that require linking facts across several documents.
Two options apply only to graph stores:
extraction_model— the model used for entity and relation extraction. It follows the same contract asembedding_model: optional, defaults toauto, and resolved to a concrete model at creation.max_hops— how far to expand through the graph on each query, from1to4. The default is2.
retrieval_mode, extraction_model, and max_hops back, with extraction_model resolved to the concrete model rather than auto.
You search a graph store with the same search call as any other vector store — the mode is a property of the store, not of the request.
What changes on a graph store
- The mode is frozen at creation. There is no way to convert a store between
vectorandgraphafterward; the update endpoint does not acceptretrieval_mode. Switching means creating a new store and re-attaching the files. - Extraction is metered against your usage. Entities and relations are extracted from every chunk at ingest, and each query also runs an extraction pass to identify the entities to expand from. Both are billed as normal model usage, so a graph store costs more to fill and more to query than a vector store over the same files.
- Graph search returns at most 20 results.
max_num_resultsaccepts up to 50, but graph queries clamp to 20. A higher value is truncated rather than rejected. - Attribute filters can under-fill. As noted under Filter search by file attributes, filtering on a graph store is partly applied after retrieval, so a filtered search can return fewer than
max_num_resultsmatches. extraction_modelandmax_hopsare graph-only. Sending either withoutretrieval_mode: "graph"returns400.
Add more files later
You can add more files to an existing vector store without recreating it.status: "in_progress" while indexing runs.
A file is not searchable until its status reaches "completed" — searching before then
succeeds but omits the file, so poll for "completed" rather than assuming a fixed wait.
Indexing usually finishes in seconds, but latency varies with file size and load.
Check the Files and Vector Stores endpoints in the API Reference for the polling endpoint.
List files with pagination
File listings are sorted bycreated_at (newest first by default) and return up to limit items per page.
When has_more is true, pass the last item’s id as after to fetch the next page.
id as before instead: the response is the page immediately preceding that item in the display order.
Files attached in the same batch can share a creation timestamp; the cursor accounts for this, so a full walk returns every file exactly once.
If a cursor’s file no longer exists — for example, it was removed from the vector store while you were paging — the API returns 400 Invalid pagination cursor. Restart the walk from the first page.
Search the vector store
Use semantic search to retrieve the most relevant chunks for a user question.file_id, filename, score data, chunk content, and the file’s current attributes.
Filter search by file attributes
Attributes are file-level key-value metadata — string, number, or boolean values — set when you attach a file (see Add more files later). You can change them after ingest with the update-file endpoint (POST /vector_stores/{vector_store_id}/files/{file_id}); search always evaluates the current values.
Pass filters in the search request to restrict results to files whose attributes match.
A filter is either a comparison — eq, ne, gt, gte, lt, lte, in, nin — or an and/or compound of nested filters.
- A file that does not have the filter’s
keynever matches — including forneandnin. A filter only opts a file in on evidence, never by absence. eqandneare strict equality with no type coercion: the string"2"does not equal the number2.gt,gte,lt, andltecompare numbers only; a non-numeric attribute or filter value fails the comparison.inandnintake an arrayvalueand test whether the file’s attribute is (or is not) one of its elements.andandorcompounds nest to any depth.- On graph stores, filtering is applied after retrieval, so a filtered search can return fewer than
max_num_resultsmatches.
Typical workflow
Use this sequence for most retrieval setups:- Upload the source file.
- Create a vector store with
file_ids, or attach the file later. - Wait for file processing to complete.
- Search the vector store when you need relevant context.