Review and Approval
Review model, approval semantics, concurrency control, and downstream eligibility for Numora documents.
Scope
This page explains how Numora handles human review after extraction completes.
It covers:
- The difference between
statusandreview_state - What the
approveaction means - When
rejectandretry-pushshould be used - How optimistic concurrency prevents stale approvals
Two Review Layers
The document resource uses two related but different concepts:
statustells you where the document is in the lifecycle.review_statetells you what a reviewer has explicitly confirmed.
For example, a document can still be in review_required while already carrying a partial review_state object that records confirmed fields.
The review_state Object
The public review_state value should be either null or a normalized object:
{
"version": 1,
"confirmed_general_field_names": ["invoice_number", "invoice_date"],
"confirmed_line_item_ids": ["li_1", "li_2"]
}Rules:
versionallows the shape to evolve without breaking clients.confirmed_general_field_namesstores normalized field names from the document result.confirmed_line_item_idsstores stable line item row identifiers returned by the result payload.- If both arrays are empty, the normalized value should be
null.
Current Review Semantics
The current Numora app already follows these review rules:
- Extraction completion moves the document into internal
for_review, which maps to publicreview_required. - Approving a document marks it as reviewed and finalized.
- Editing a previously approved document sends it back to review.
- Only reviewed and finalized documents are eligible for downstream push or manual workflow dispatch.
For the lifecycle mapping, see Document Lifecycle.
Approve Action
POST /v1/documents/{id}/actions/approve
Use this action when the extracted result is ready to become the confirmed source of truth.
Recommended request:
{
"expected_updated_at": "2026-03-21T14:20:00.000Z",
"review_state": {
"version": 1,
"confirmed_general_field_names": ["invoice_number", "invoice_date"],
"confirmed_line_item_ids": ["li_1"]
}
}Recommended response:
{
"id": "doc_01jpwq4q9m7q4q2k8dax1x1q5n",
"status": "reviewed",
"updated_at": "2026-03-21T14:20:03.119Z",
"review_state": {
"version": 1,
"confirmed_general_field_names": ["invoice_number", "invoice_date"],
"confirmed_line_item_ids": ["li_1"]
}
}Approval should be idempotent. Repeating the same request should not create duplicate downstream effects.
Reject and Retry-Push Actions
Numora reserves three action verbs on the public document resource:
approvefinalizes a reviewed result.rejectreopens the document for review, clears finalized state, and blocks new downstream delivery.retry-pushrequeues downstream delivery for a document that is already reviewed.
In the current developer preview:
approvefinalizes the extracted result and unlocks reviewed automation.rejectmoves the document back toreview_required.retry-pushqueues a new downstream workflow run and temporarily surfaces the document aspush_pending.
Concurrency Control
Clients should protect review actions with optimistic concurrency.
Recommended pattern:
- Read the latest document or result resource.
- Store the returned
updated_at. - Send that value back as
expected_updated_atwhen approving. - If the server returns
409 conflict, refetch the latest document before trying again.
Recommended conflict response:
{
"error": {
"code": "conflict",
"message": "approve conflict",
"request_id": "req_01jpwqkshg6x8j9k9j29m8n0n4"
},
"updated_at": "2026-03-21T14:21:12.000Z"
}Downstream Gating
Approval is not only a UI label. It is the gate that makes the document eligible for downstream execution.
For the initial CRM delivery path, this means a client may start from already reviewed documents and the delivery outbox rather than treating POST /v1/documents as a required first step.
Operationally, the recommended contract is:
review_requireddocuments can still be edited or corrected.revieweddocuments are treated as confirmed.- A later edit to a previously approved document should move it back to
review_required. - Downstream push and manual workflow dispatch should require the document to be both reviewed and finalized.