Documents API
| Route | Method | Purpose |
|---|---|---|
/api/doc | GET | Signed document URL |
/api/doc-upload-session | POST | Allocate a document row and signed upload token |
/api/ingest-doc | POST | Enqueue extraction/embedding for an uploaded document |
/api/document-inventory | GET | Admin/lead inventory of indexed documents |
Upload flow
POST /api/doc-upload-sessionallocates thedocumentscatalog row and a signed upload token — the browser uploads directly to storage using that token, not through this API.POST /api/ingest-doc { document_id }then enqueues indexing.
{ "document_id": "document-uuid" }
This route is intentionally durable-only: extraction, embedding, and atomic publication all
run in Trigger.dev (sable.document.backfill-index-batch), not inline in the request handler —
the request only validates access and enqueues the work. Rate-limited via
SABLE_INGEST_RATE_LIMIT (default 12/min).
GET /api/doc
Returns a signed URL for one document. Enforced by the same access rules across every document surface:
- A valid Supabase session is required.
- Restricted documents (contracts, SOWs) require admin/lead.
- Non-leads must be a member of the document's project.
GET /api/document-inventory
Admin/lead only. Every indexed document plus contract/SOW extraction health flags —
buildDocumentInventory (in _deliverable_authoring.js) is shared with the deliverable-drafting
pipeline's evidence-collection step, so this inventory and what a deliverable draft can actually
cite are always the same list.
Where the code lives
sable-agents-demo/web/api/doc.js,doc-upload-session.js,ingest-doc.js,document-inventory.jssable-agents-demo/web/api/_doc_upload.js,_document_ingest.js,_ingestion_pipeline.js,_deliverable_authoring.jssable-agents-demo/trigger/documents.tssable-agents-demo/docs-site/docs/reference/search-indexing.md— the retrieval side of this pipeline