Documents & Jobs
Uploading a document starts an asynchronous ingestion job. These endpoints use the project’s API key.
Upload a document
POST /v1/projects/{id}/documents
multipart/form-data with a single file field.
curl -X POST https://api.your-host/v1/projects/$PROJECT_ID/documents \
-H "Authorization: Bearer $API_KEY" \
-F "file=@handbook.pdf"
Response
{ "document_id": "…", "job_id": "…", "status": "pending" }
Supported formats: PDF, DOCX, PPTX, XLSX, ODF, RTF, EPUB, CSV, HTML, Markdown, plain text. Max size: 50 MB. Scanned / image-only PDFs are refused — OCR them first.
Poll job status
GET /v1/jobs/{id}
{
"id": "…", "project_id": "…", "document_id": "…",
"status": "processing", "error_code": null, "error": null,
"created_at": "…", "updated_at": "…"
}
Job status values
| status | meaning |
|---|---|
queued | waiting for a worker |
processing | being ingested |
succeeded | ingested and searchable |
retryable_failed | transient failure; will be retried |
terminal_failed | gave up; see error_code |
On a terminal failure, error_code is a stable, safe-to-branch-on code (the raw error never leaks
internal infrastructure detail).
Retry a failed document
POST /v1/documents/{id}/retry
Re-queues a document whose job reached terminal_failed. Retrying a permanent parse failure (e.g. a
scanned PDF) is allowed but pointless — it will fail again quickly.
Delete a document
DELETE /v1/documents/{id} → 204
Removes the document, its chunks and its uploaded bytes, and frees the content for re-upload. The operation is idempotent and safe to retry. Shared entities are intentionally left in place.