Skip to main content

Propose Corrections

Find a document's field-review handle in a Spec's latest run, then propose a correction to a captured field, singly or up to 500 at once, for a reviewer.

Resolving works on a field that is held in review. A correction proposal works on a field that is not: one that was captured and completed, which a person or an app believes is wrong. An app that re-reads a re-filed document, or a person reading the source, can reopen the field with a proposed value. The value in the output does not change, and no hold cell is written. The field moves into review with the proposal attached, and the output changes only when a reviewer resolves the item. Resolving with accept_proposal promotes the proposed value as a human correction; correct, approve and override stay available, as described under Resolve Field Review.

Three routes cover the flow. GET /v1/field-reviews/locate maps a workspace document and a Spec to the pipeline_document_id the other routes take. POST /v1/field-reviews/{docId}/{fieldKey}/reopen proposes a correction for one field. POST /v1/field-reviews/bulk-reopen runs the single-field reopen for up to 500 items. Reopen and bulk reopen need the write scope; locate needs read.

Find the Handle of a Document

A caller that holds a document id and a Spec does not hold the id of the document's row in a run. locate returns it: the document's row in the Spec's most recent completed, non-preview run. schema_id is the Spec's schema id (pipelines.schema_id). The route answers 404 when no completed run of that Spec holds the document. An app service key reaches the route under a spec grant at read covering schema_id; without one it receives the same 404, so the route is no existence check for documents the app cannot see.

GET/v1/field-reviews/locate

Query parameters

document_id*uuidThe workspace document.
schema_id*uuidThe Spec's schema id (pipelines.schema_id).

Response fields

pipeline_document_iduuidThe id the reopen and resolve routes take as docId.
pipeline_iduuidThe run the row belongs to.
run_created_atdate-timeWhen that run was created.

cURL: Locate the handle

curl "https://api.talonic.com/v1/field-reviews/locate?document_id=a3f9c1d2-0b7e-4c55-8d1a-90e2f4b6c7d8&schema_id=5b2e0d7a-3c11-4e0f-9a64-7f1c2d8e9b40" \
  -H "Authorization: Bearer $TALONIC_API_KEY"

Response: Handle

{
  "pipeline_document_id": "2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62",
  "pipeline_id": "1a0c681d-ea20-4bb4-8892-01a6d7f834da",
  "run_created_at": "2026-10-14T09:02:51.000Z"
}

Propose a Correction to One Field

The effect depends on the field's state. A completed field moves to pending_review with review_trigger: correction, and the response says reopened: true. A field already in review keeps its hold and gains the proposal; proposing the same value again changes nothing and returns reopened: false. A field still progressing or waiting_dependency answers 409: it is still being processed, so propose again when it settles. proposed_value is required unless clear is true, which proposes that the field should be empty. A number is accepted and stored as its text.

reason is required and tells the reviewer why the captured value is wrong. evidence_quote carries the document passage the proposal rests on, copied verbatim. source says who proposes: app (the default), an app acting on a person's correction, or human. app_slug names the proposing app, for example contracts, and is shown to the reviewer; it is kept only with source app. An app service key is admitted by a spec grant at act covering the Spec the item's run structures.

POST/v1/field-reviews/{docId}/{fieldKey}/reopen

Path parameters

docId*uuidThe pipeline document id (pipeline_document_id).
fieldKey*stringThe field to correct.

Body fields

reason*stringWhy the captured value is wrong, 1 to 2000 characters.
proposed_valuestringThe proposed value, up to 10,000 characters. A number is stored as its text. Required unless clear is true.
clearbooleanPropose clearing the field.
evidence_quotestringThe document passage the proposal rests on, copied verbatim, up to 4000 characters.
sourcestringapp or human. Default: app
app_slugstringThe proposing app, up to 100 characters. Kept only with source app.

Response fields (camelCase)

fieldKeystringThe field.
statusstringprogressing, blocked, waiting_dependency, pending_review, or completed.
currentPhaseId, blockedAtStageId, blockedByFieldstring | nullWhere the field is, and what blocks it, when it is blocked.
reviewTriggerstring | nullgate, declarative, pattern, correction, or agentic.
reviewRoutingstring | nullreview_queue or hold.
reviewRequestedAt, resolvedAt, deliveredAtdate-time | nullLifecycle timestamps.
resolveActionstring | nullapprove, correct, override, or demote, once resolved.
correctionProposalobject | nullThe attached proposal: value, clear, evidence_quote, source, app_slug, reason, requested_by, requested_at.
reopenedbooleanTrue when the call moved a completed field into review; false when the field was already in review.

cURL: Propose a corrected value

curl -X POST "https://api.talonic.com/v1/field-reviews/2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62/contract_end_date/reopen" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "proposed_value": "2027-06-30",
    "evidence_quote": "The agreement ends on 30 June 2027.",
    "source": "app",
    "app_slug": "contracts",
    "reason": "The re-filed amendment moves the end date."
  }'

Response: 201

{
  "fieldKey": "contract_end_date",
  "status": "pending_review",
  "currentPhaseId": null,
  "blockedAtStageId": null,
  "blockedByField": null,
  "reviewTrigger": "correction",
  "reviewRouting": "review_queue",
  "reviewRequestedAt": "2026-10-21T08:41:07.000Z",
  "resolveAction": null,
  "resolvedAt": null,
  "deliveredAt": null,
  "correctionProposal": {
    "value": "2027-06-30",
    "clear": false,
    "evidence_quote": "The agreement ends on 30 June 2027.",
    "source": "app",
    "app_slug": "contracts",
    "reason": "The re-filed amendment moves the end date.",
    "requested_by": "api:6e2b9c41-0d7a-4f13-8a55-b7c1e0d2f394",
    "requested_at": "2026-10-21T08:41:07.000Z"
  },
  "reopened": true
}

Propose Corrections in Bulk

POST /v1/field-reviews/bulk-reopen runs the single-field reopen for up to 500 items. A failed item never aborts the rest: each item reports its own outcome in results, and the response counts proposed (items that succeeded) and failed. source and app_slug apply to every item, while reason, proposed_value, clear and evidence_quote are per item. An app service key reaches this route and every item is checked individually: an item whose run belongs to a Spec the app does not hold at act is reported as { "ok": false, "error": "insufficient_grant" } and is not reopened. An item whose document does not exist reports Pipeline document not found.

POST/v1/field-reviews/bulk-reopen

Body fields

items*object[]1 to 500 items.
items[].pipeline_document_id*uuidThe pipeline document id.
items[].field_key*stringThe field to correct, up to 500 characters.
items[].reason*stringWhy the captured value is wrong, 1 to 2000 characters.
items[].proposed_valuestringUp to 10,000 characters. Required unless clear is true.
items[].clearbooleanPropose clearing the field.
items[].evidence_quotestringThe document passage the proposal rests on, up to 4000 characters.
sourcestringapp or human. Applies to every item. Default: app
app_slugstringThe proposing app, up to 100 characters. Applies to every item.

Response fields

results[]arrayPer item: pipeline_document_id, field_key, ok, reopened (on success), error (on failure).
proposedintegerItems that succeeded.
failedintegerItems that failed.

cURL: Propose two corrections

curl -X POST "https://api.talonic.com/v1/field-reviews/bulk-reopen" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "app",
    "app_slug": "contracts",
    "items": [
      { "pipeline_document_id": "2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62", "field_key": "contract_end_date", "proposed_value": "2027-06-30", "reason": "Amendment moves the end date." },
      { "pipeline_document_id": "2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62", "field_key": "notice_period", "clear": true, "reason": "The re-filed contract states no notice period." }
    ]
  }'

Response: 201 with one failed item

{
  "results": [
    { "pipeline_document_id": "2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62", "field_key": "contract_end_date", "ok": true, "reopened": true },
    { "pipeline_document_id": "2f6d1e8a-9c44-4b0d-a7f3-5e1c0d9b8a62", "field_key": "notice_period", "ok": false, "error": "insufficient_grant" }
  ],
  "proposed": 1,
  "failed": 1
}
A proposal asks a reviewer to decide; it does not change the output. Until the item is resolved, the captured value stays in the output. Do not treat a 201 from reopen as the correction having been applied.

Frequently asked questions

Does reopening a field change the value in my output?+
No. The value in the output stays as captured, and no hold cell is written. The field moves into review with the proposal attached, and the output changes only when a reviewer resolves the item, for example with accept_proposal, which promotes the proposed value as a human correction.
What happens if the field is already in review?+
It keeps its hold and gains the proposal. Proposing the same value again changes nothing and returns reopened: false. A field that is still progressing or waiting_dependency answers 409, because it is still being processed.
How do I get the pipeline_document_id for a document?+
Call GET /v1/field-reviews/locate with the document_id and the Spec's schema_id. It returns the document's row in the Spec's most recent completed, non-preview run, and answers 404 when no completed run of that Spec holds the document.
What happens to the other items when one bulk item fails?+
Nothing. Each item runs on its own, a failed item never aborts the rest, and the response reports ok or an error for every item, plus the counts proposed and failed.