Skip to main content

Gate Rules

Add rules to a review gate with POST /v1/structuring/gates/:id/rules or remove them with DELETE: min_confidence, validation_pass, field_value, and more.

Gate rules are the conditions a structuring result must meet for a review gate to auto-approve it. After validation checks run, every active rule on the gate is evaluated; the result auto-approves only when all rules pass, and a single failing rule records a pending decision that parks the record for manual review. Rules are attached one at a time with POST /v1/structuring/gates/{gateId}/rules and removed with DELETE /v1/structuring/gates/{gateId}/rules/{ruleId}.

Six rule types exist, each reading its own config keys:

  • min_confidence — the result's row-level confidence must be at least config.min (e.g. { "min": 0.85 }).
  • field_confidence — one field's confidence (or cell readiness, when available) must be at least config.min: { "field": "total_amount", "min": 0.9 }.
  • validation_pass — the result's failing check outcomes must not exceed config.max_failures (default 0). config.scope narrows which checks count: all (default), critical_only (only critical-severity checks), or specific with a check_ids array.
  • field_presence — every field in config.fields must have a non-null value.
  • field_value — one field must satisfy an operator test: { "field": "currency", "operator": "in", "value": ["EUR", "USD"] }. Operators: eq, neq, gt, lt, gte, lte, in, not_in, regex.
  • canonical_complete — passes only once every conflicting field on the result has a canonical selection; used for multi-document reconciliation flows. It always fails at initial evaluation and is re-checked when canonical selections complete.
Rules fail closed: an unknown rule type — or an unknown field_value operator — evaluates as a failure, flagging every result the gate sees. A typo like "min_confidance" therefore sends 100% of records to review. Equally important: min_confidence reads config.min, not config.threshold — a { "threshold": 0.85 } config leaves min at its default of 0, and the rule passes everything.
POST/v1/structuring/gates/{gateId}/rules

Body parameters

name*stringRule name, echoed in each decision's rule_results.
type*stringRule type: min_confidence, field_confidence, validation_pass, field_presence, field_value, or canonical_complete.
configobjectType-specific configuration (see the list above). Optional in the contract, but min_confidence without config.min defaults to 0 and always passes.
sort_orderintegerDisplay order. Defaults to 0. All active rules are evaluated regardless of order.

curl

curl -s -X POST https://api.talonic.com/v1/structuring/gates/4014c518-7f75-425c-bf67-3052464b95a0/rules \
  -H "Authorization: Bearer tlnc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Row confidence at least 0.85",
    "type": "min_confidence",
    "config": { "min": 0.85 }
  }'

Response

Response fields (POST)

idstringRule UUID.
gate_idstringParent gate UUID.
namestringRule name.
typestringRule type.
configobject | nullRule configuration as stored.
sort_orderintegerDisplay order.
is_activebooleanAlways true for newly created rules.
created_atstringISO 8601 creation timestamp.

Response (POST)

{
  "gate_id": "4014c518-7f75-425c-bf67-3052464b95a0",
  "name": "Row confidence at least 0.85",
  "type": "min_confidence",
  "config": { "min": 0.85 },
  "sort_order": 0,
  "id": "285aae61-8378-49e2-926a-ac54e4e54853",
  "is_active": true,
  "created_at": "2026-08-29T11:35:30.485Z"
}
DELETE/v1/structuring/gates/{gateId}/rules/{ruleId}

Path parameters

gateId*uuidParent review gate identifier.
ruleId*uuidRule identifier to remove.

Response (DELETE)

{
  "deleted": true
}

Errors

Error responses

400VALIDATION_ERRORA path parameter is not a valid UUID, or a required body field (name, type) is missing or has the wrong type.
401unauthorizedMissing or invalid API key.
404RESOURCE_NOT_FOUNDReview gate or rule not found, or the gate does not belong to your organization.
429rate_limitedToo many requests. Retry after the period indicated in the Retry-After header.

Rules compose with checks through validation_pass: checks record per-issue outcomes, and the rule aggregates them into a single go/no-go. The strictest useful policy is { "scope": "all", "max_failures": 0 } — any failing check flags the record. A more forgiving production pattern scopes to critical_only so advisory warning checks never block, or names specific contract-critical checks via { "scope": "specific", "check_ids": [...] }. Note that check outcomes with status skip and error do not count as failures here — only explicit fail verdicts do.

When a decision lands as pending, its rule_results array records each rule's verdict by rule_id, rule_name, type, and passed, so a review UI can show exactly which condition held a record back. Removing a rule is soft: past decisions keep the recorded verdicts of the deleted rule, while future evaluations simply no longer include it.

Frequently asked questions

Can I add multiple rules of the same type to a gate?+
Yes, and because rules are ANDed they all must pass. Two field_confidence rules on different fields is a normal pattern; two min_confidence rules with different thresholds is legal but redundant — only the stricter one matters.
What happens when I remove all rules from a gate?+
The gate passes vacuously and auto-approves every result — there is nothing left to fail. If you want to stop a gate from approving anything rather than approving everything, pause the gate itself with PUT { "is_active": false } instead of deleting its rules.
Does sort_order affect evaluation?+
No — every active rule is always evaluated and recorded in the decision's rule_results, regardless of order; nothing short-circuits. sort_order only controls display ordering in listings and UIs.
How is min_confidence different from field_confidence?+
min_confidence tests the result's row-level confidence — one number summarizing the whole record — against config.min. field_confidence tests a single named field's confidence (preferring the cell-readiness score where available). Use row confidence as a blanket floor and field_confidence to protect the one or two fields that matter contractually.