- Upload a file and get a
file_id - Wait for embeddings to finish processing
- Search with a natural-language query
Step 1 — Upload a file
CallPOST /v1/files to register the file. You get back a file_id and a short-lived signed_url — use the signed URL to PUT the actual bytes directly to storage.
- curl
- Python
- Node.js
Init upload fields
Init upload response
400 on upload.
Step 2 — Wait for embeddings
After the PUT completes, the API automatically chunks and embeds your file (becauseembed: true). You can poll GET /v1/files/{file_id} to watch progress. Give the loop a deadline: if the PUT never lands, upload_status stays pending forever.
- curl
- Python
- Node.js
Status fields
Once
embedding_status is ready, the file is ready to search.
upload_status goes to failed when the uploaded file is over 50 MB or its
Content-Type doesn’t match the mime_type you registered. Register the file again. The status object also
carries file_name, file_type, mime_type, size_bytes, created_at,
updated_at, total_tokens, total_cost_usd and last_error_code.
Step 3 — Search your files
Send a natural-language query toPOST /v1/files/search. The API embeds your query, runs a hybrid search (dense vectors plus keyword matching, merged by reciprocal rank fusion), and returns the raw text with relevance scores. The query embedding is billed to your account like any embedding call.
- curl
- Python
- Node.js
Search fields
Search response
End-to-end: RAG chat
Combine search results with a chat completion to answer questions from your documents.- Python
- Node.js
Filtering by metadata
Tag files at upload time and filter at search time — useful when you have documents from different departments, clients, or time periods.Re-triggering embeddings
Ifembed was set to false at upload time, or if embedding failed, you can kick it off manually:
202 with a per-file status:
"wait": true to block until all embeddings finish (useful for small files in scripts).
Rules, per file:
file_idstakes 1 to 100 ids.- The file’s
upload_statusmust beready. - A file that is already embedded comes back as
completed; one still queued or processing comes back asprocessing. - After a failed embedding, the same file can’t be re-queued for 30 minutes. The entry comes back with
embedding_status: "error"and anerrorsaying when to retry.
List your files
files (array of file status objects), total, limit, and offset.
Delete a file
CallDELETE /v1/files/{file_id} to remove a file. Its chunks are dropped from
the search index and the stored file is deleted, so the document stops appearing
in POST /v1/files/search results.
- curl
- Python
- Node.js
204 No Content with an empty body — there is no
JSON response to parse.
Deleting is idempotent, so retrying is always safe and converges on a full
delete. Treat a file as deleted only once you have received a
204 — if a call
fails, repeat it until it succeeds rather than assuming it partly applied.
Usage records that reference the file stay available afterwards, so your billing
history and usage queries remain complete.