Skip to main content

talonic_submit_decision_task

Return the decision for a claimed task. The platform verifies three things transactionally before writing anything: the outcome against the task's output_contract, every evidence locator against the run's frozen input package, and the presence of a rationale. On success the task becomes submitted, the run resumes through the app's threshold checks and action layer, and the sealed record names decided_by.type: external_agent. Talonic writes the ledger; the agent never does.

ParameterTypeDescription
task_id *UUIDClaimed task ID.
execution_epoch *integerExact epoch from the current claim.
outcome *objectThe decision. For a plain contract, the object its JSON Schema validates. For a `verdict_matrix` contract, `{ subjects: [{ subject_key, rule_outcomes, auto?, detail? }] }`. For a `record_set` contract, its fields-and-rows envelope.
evidence *string[]Provenance locators the decision relied on, copied verbatim from the package (or `db:` / `ref:` locators the app holds a read grant on). Up to 10,000 entries of at most 512 characters. An empty array is accepted only when the app allows unevidenced decisions.
rationale *stringA short summary of why — never private chain-of-thought. At most 4,000 characters.
confidencenumberOptional confidence from 0 to 1; the app's confidence floor may route a low value to review.
service_versionstringOptional build identifier of the deciding service (at most 64 characters); recorded as `decided_by.label`.
Submit a decision
// talonic_submit_decision_task({
//   "task_id": "11111111-1111-4111-8111-111111111111",
//   "execution_epoch": 1,
//   "outcome": { "approve": true },
//   "evidence": [
//     "dp:pppppppp-pppp-4ppp-8ppp-pppppppppppp:rrrrrrrr-rrrr-4rrr-8rrr-rrrrrrrrrrrr:invoice_total",
//     "dp:pppppppp-pppp-4ppp-8ppp-pppppppppppp:rrrrrrrr-rrrr-4rrr-8rrr-rrrrrrrrrrrr:supplier_name"
//   ],
//   "rationale": "Total matches the purchase order and the supplier is on the approved list.",
//   "confidence": 0.93
// })
{
  "id": "11111111-1111-4111-8111-111111111111",
  "run_id": "22222222-2222-4222-8222-222222222222",
  "status": "submitted",
  "execution_epoch": 1,
  "submitted_at": "2026-09-22T10:02:10.000Z",
  "...": "remaining metadata as in the list"
}

A refused submission is HTTP 422 with the reason (Decision violates the output contract: …, An evidence block is required …, a locator outside the package, or a malformed matrix envelope), is journaled as rejected, and changes nothing: the task stays claimed under your epoch, so fix the payload and submit again before the lease ends. A stale epoch is HTTP 409. A successful submit is terminal — corrections happen downstream in review, not by a second submit.

The rationale is a summary for the ledger and for the humans who review it, not a transcript. For a rule-mining round driven from outside, the round's long summary travels in outcome.summary and the rationale is one line.

Frequently asked questions

Can the evidence cite something outside the input package?+
Only a db: or ref: locator naming a source connection or reference table the app holds a read grant on; those are accepted as attestations and journaled. Any other off-package locator, and the reserved api: prefix, is rejected. Everything else must appear verbatim in the package.
What if the app's thresholds disagree with my decision?+
The submit is still accepted. Thresholds — the confidence floor for auto-execution and value ceilings requiring approval — are enforced by the platform after the decision and before execution, for every mode. A breach routes the run to a human review; it never fails silently.