A global kill-switch and a per-tenant opt-in gate the document-extraction lane. A tenant that has not opted in receives
403. That answer comes before any storage or egress of document bytes.Enqueue a document for extraction
Upload a source document (PDF) to run deterministic + AI extraction. The resulting transaction candidates go into a review queue. Nothing reaches reconciliation yet.
202 Accepted) returns the queued review id, the candidate count, and a status that is always PENDING_REVIEW on enqueue:
The review queue
List reviews
Cursor-paginated list of extraction reviews for a context, optionally filtered by lifecycle status.status (PENDING_REVIEW, APPROVED, REJECTED), limit (1–200), and cursor.
Get one review
text_layer (PDF text, higher trust) or vision (OCR/vision model, lower trust). Field values are verbatim tokens. Money stays a string, never a parsed amount.
Approve or reject
Approve
Approving aPENDING_REVIEW review runs the single deterministic handoff into the normal ingestion pipeline (dedup + outbox + match-trigger) and links the resulting job to the review. This is the only path from an AI candidate to a reconciled transaction, and it runs only on explicit human approval.
Reject
Rejecting discards the candidates, so nothing enters ingestion. The body is optional. An empty body is a valid “reject with no reason”.Mapping proposals
Before you declare a field map by hand, ask the advisor to inspect a representative sample and propose a config-only mapping. It is advisory and side-effect-free: producing a proposal persists nothing. You confirm the result through the existing field-map declaration path.
Fetch from an external transport
Trigger a manual fetch-and-ingest that lists every object matching the supplied transport coordinates (SFTP today) and streams each into the trusted-content ingestion pipeline. The body carries connection coordinates plus an opaque credential reference, never a secret.
202 Accepted) returns a per-file outcome in fetch order. A per-file intake failure does not stop the batch. The response reports each one:
503.
Inspect job errors
After an import, list the stored per-row parse/normalization errors for a job (capped at 100 per job) to explain failed or partially-failed imports.
totalErrors holds the uncapped failure total. truncated is true when the total exceeds the stored (capped) set.

