Skip to main content
Use Files to upload documents once. Use Vector Stores to index those files for semantic search and retrieval. This is the standard pattern for document-backed assistants, retrieval workflows, and grounded responses.

Upload a file

Upload the file with multipart/form-data. The live OpenAPI spec requires file and purpose.
The response returns a 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.
This response returns a vector store ID such as vs_abc123.

Add more files later

You can add more files to an existing vector store without recreating it.
The vector store file can return status: "in_progress" while indexing runs. Check the Files and Vector Stores endpoints in the API Reference if you need to poll for status.

List files with pagination

File listings are sorted by created_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.
To page backwards, pass an item’s 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.
The response returns ranked matches with 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.
Filter evaluation follows these rules:
  • A file that does not have the filter’s key never matches — including for ne and nin. A filter only opts a file in on evidence, never by absence.
  • eq and ne are strict equality with no type coercion: the string "2" does not equal the number 2.
  • gt, gte, lt, and lte compare numbers only; a non-numeric attribute or filter value fails the comparison.
  • in and nin take an array value and test whether the file’s attribute is (or is not) one of its elements.
  • and and or compounds nest to any depth.
  • On graph stores (GraphRAG), filtering is applied after retrieval, so a filtered search can return fewer than max_num_results matches.

Typical workflow

Use this sequence for most retrieval setups:
  1. Upload the source file.
  2. Create a vector store with file_ids, or attach the file later.
  3. Wait for file processing to complete.
  4. Search the vector store when you need relevant context.
You can then feed the returned text into your own application logic or a Responses request.