Skip to main content

Approve / Reject Result

Record a decision on a structuring result with POST /v1/structuring/approvals/:id/approve or /reject — gate-scoped, with optional notes for the audit trail.

POST /v1/structuring/approvals/{resultId}/approve and /reject record a human decision on a structuring result. Each call writes an approval decision row with status approved or rejected, the decision source api, and your optional notes — the durable audit record of who let a record through (or held it back) and why. The path parameter is the structuring result id, the same id the pending review queue exposes as result_id.

Both actions require a gate_id in the body, because decisions are scoped to one gate: when several gates govern the same schema, each gate's verdict on a record is independent, and your decision names which policy it satisfies. The platform verifies both sides before writing — the result must belong to your organization (checked through its run, not the gate) and the gate must too — so a foreign or dangling id yields a 404, never a cross-tenant write.

Decisions are unique per (result, gate) pair — the decision table enforces one row per combination. Treat approve/reject as a one-shot verdict per gate rather than a toggle you can flip repeatedly; decide once, and use notes to capture the reasoning.
POST/v1/structuring/approvals/{resultId}/approve

Body parameters

gate_id*uuidReview gate to record the decision against. Must be a valid UUID belonging to your organization.
notesstringOptional reviewer notes explaining the decision, stored on the decision row.
POST/v1/structuring/approvals/{resultId}/reject

curl

curl -s -X POST https://api.talonic.com/v1/structuring/approvals/9c2f6a1e-3b7d-4c58-9e21-8f4a5d6b7c80/approve \
  -H "Authorization: Bearer tlnc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "gate_id": "4014c518-7f75-425c-bf67-3052464b95a0",
    "notes": "Amount verified against the signed PO."
  }'

Response

Response fields

idstringDecision UUID.
dataspace_result_idstringUUID of the structuring result the decision applies to.
statusstringapproved or rejected, matching the route called.

Response

{
  "id": "e5f6a7b8-c9d0-1234-efab-345678901234",
  "dataspace_result_id": "9c2f6a1e-3b7d-4c58-9e21-8f4a5d6b7c80",
  "status": "approved"
}

Errors

Error responses

400VALIDATION_ERRORgate_id is missing or not a valid UUID ("gate_id must be a UUID"), or the resultId path parameter is malformed.
401unauthorizedMissing or invalid API key.
404RESOURCE_NOT_FOUNDThe result or the gate was not found in your organization. The message names which: "Result '...' not found." or "Approval gate '...' not found."
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.

Error (404)

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "error": "Not Found",
  "message": "Result '22222222-2222-4222-8222-222222222222' not found.",
  "retryable": false,
  "request_id": "req_7797aab291774896",
  "timestamp": "2026-08-29T11:35:43.680Z",
  "path": "/v1/structuring/approvals/22222222-2222-4222-8222-222222222222/approve"
}

Decisions recorded through this API sit alongside the automatic ones: gate evaluation writes auto_approved or pending decisions with source auto at structuring time, and your calls add approved/rejected decisions with source api. Reviewer identity is not attached to API decisions (the key, not a user, is the actor), so put the reviewer's name or ticket reference in notes when your compliance process needs attribution.

Approval is what separates delivered from held data: the structuring delivery pipeline exports approved results only, so rejected and undecided records never leave the platform through that channel. The review loop in full: poll the [pending review queue](pending-approvals), group items by result_id, inspect a record's full outcomes via [result checks](result-checks), record your decision here, and let delivery pick up the approved set for the run (see [Trigger Delivery](trigger-delivery)).

Frequently asked questions

What happens after I approve a result?+
The decision is recorded against the gate with source "api" and your notes. Approved results are the set the structuring delivery pipeline exports for a run — rejected and undecided records are excluded — so approval is the switch that clears a record for delivery.
Why is gate_id required in the body?+
Each decision is recorded against one gate, so several gates can independently govern the same result. Omitting gate_id or sending a non-UUID returns 400 VALIDATION_ERROR ("gate_id must be a UUID"); a gate that does not belong to your organization returns 404.
Can I change a decision after recording it?+
Not through this API — decisions are unique per (result, gate) pair, so a second call for the same combination conflicts with the existing row rather than overriding it. Decide deliberately, and use the notes field to document the rationale at decision time.
Does rejecting delete the result?+
No. The structured record and all its check outcomes remain readable; rejection only records a decision that excludes it from approved-only delivery. You can still export it through non-gated reads such as record sets if your integration chooses to.