> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Decide over a batch of requests in one call — for enterprises scoring whole

> portfolios (e.g. refund-eligibility across 10k orders). Each item is metered independently (so quota/billing behave exactly as N single calls)…

portfolios (e.g. refund-eligibility across 10k orders). Each item is metered
independently (so quota/billing behave exactly as N single calls); a failing
item is reported in-place without aborting the rest.

**Required scope:** `write`

### Request body

`BatchDecisionRequest`

<ParamField body="items" type="DecisionRequest[]" required>
  Decision requests to evaluate. Each item is metered independently.
</ParamField>

### Response

`BatchDecisionResponse`

<ResponseField name="results" type="BatchDecisionItem[]" required>
  <Expandable title="BatchDecisionItem">
    <ResponseField name="decision" type="object">
      <Expandable title="decision">
        <ResponseField name="action" type="object" />

        <ResponseField name="confidence" type="number (double)" required />

        <ResponseField name="decision" type="string" required>
          `approved` | `denied` | `refused`.
        </ResponseField>

        <ResponseField name="decision_id" type="string" required />

        <ResponseField name="dropped_citations" type="string[]">
          Org rules the engine fired during hydration that were dropped from `proof.cited_rules` as unrelated to this decision. Persistently non-empty values mean a standing rule with permanently satisfied premises fires on every hydrated decision — scope or prune it.
        </ResponseField>

        <ResponseField name="evaluated_goal" type="string">
          Exact predicate evaluated as the permit target. Absent for legacy requests that relied on action/query inference.
        </ResponseField>

        <ResponseField name="grounding" type="DecisionGrounding" required />

        <ResponseField name="gss_machine" type="GssMachineGroundingSnapshot" required />

        <ResponseField name="plain_explanation" type="string" required>
          Deterministic, proof-derived, business-readable 'why' — distinct from `rationale` (engine narration): 'Approved to issue a refund for order 9412: the return for order 9412 was received and order 9412 passed inspection.' Always present.
        </ResponseField>

        <ResponseField name="proof" type="DecisionProof" required />

        <ResponseField name="rationale" type="string" required />

        <ResponseField name="refusal" type="object" />

        <ResponseField name="trace" type="RecursiveChatTraceStep[]">
          Full proof trace, when `include_trace` was set.
        </ResponseField>

        <ResponseField name="usage" type="DecisionUsage" required />

        <ResponseField name="verifiable_bundle" type="object">
          A self-contained, INDEPENDENTLY-VERIFIABLE proof bundle for an approved decision: the exact facts and rules plus a `RuleEngine::backward_chain` derivation of the authorization goal, in the `knowledge::ProofBundle` wire format. POST it verbatim to `/v1/proofs/verify` (or check it offline with the dependency-light `proof_check`) to confirm the verdict without trusting this server. Present only when the caller declared an `authorization_goal` AND the rule engine reproduces the proof; absent otherwise (the verdict still stands on its own derivation).
        </ResponseField>

        <ResponseField name="warnings" type="string[]">
          Non-fatal advisories about how the verdict was derived (e.g. the outcome rested on predicate-name inference rather than declared rule effects). Omitted when empty.
        </ResponseField>

        <ResponseField name="x_nsr" type="object" />
      </Expandable>
    </ResponseField>

    <ResponseField name="error" type="object">
      <Expandable title="error">
        <ResponseField name="code" type="string" required />

        <ResponseField name="message" type="string" required />
      </Expandable>
    </ResponseField>

    <ResponseField name="index" type="integer" required />
  </Expandable>
</ResponseField>

<ResponseField name="summary" type="BatchSummary" required>
  <Expandable title="BatchSummary">
    <ResponseField name="approved" type="integer" required />

    <ResponseField name="billable_decisions" type="integer" required>
      Items that consumed a billable outcome.
    </ResponseField>

    <ResponseField name="denied" type="integer" required />

    <ResponseField name="errored" type="integer" required />

    <ResponseField name="refused" type="integer" required />

    <ResponseField name="total" type="integer" required />

    <ResponseField name="total_cost_micros" type="integer (int64)" required>
      Aggregate charge for the batch, in microdollars.
    </ResponseField>
  </Expandable>
</ResponseField>

### Status codes

| Code  | Meaning                                            |
| ----- | -------------------------------------------------- |
| `200` | Per-item decisions with proofs + batch summary     |
| `400` | Empty or oversized batch                           |
| `401` | Unauthorized — missing or invalid credentials      |
| `403` | Forbidden — the key/token lacks the required scope |
| `429` | Rate limited — see Retry-After / X-RateLimit-Reset |

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.nsr.stateset.com/v1/decisions/batch' \
    --header 'X-API-Key: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
    "items": [
      {
        "action": "string",
        "authorization_goal": {
          "args": null,
          "name": null,
          "negated": null
        },
        "confidence_threshold": 7.5,
        "external_ref": "string",
        "facts": [],
        "hydrate_org_context": true,
        "include_trace": true,
        "kb_limits": {
          "max_entities": null,
          "max_properties_per_entity": null,
          "max_rules": null,
          "max_triples": null
        },
        "max_depth": 1,
        "max_iterations": 8,
        "mode": "string",
        "query": "string",
        "rules": [],
        "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      }
    ]
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "results": [
      {
        "decision": {
          "action": null,
          "confidence": null,
          "decision": null,
          "decision_id": null,
          "dropped_citations": null,
          "evaluated_goal": null,
          "grounding": null,
          "gss_machine": null,
          "plain_explanation": null,
          "proof": null,
          "rationale": null,
          "refusal": null,
          "trace": null,
          "usage": null,
          "verifiable_bundle": null,
          "warnings": null,
          "x_nsr": null
        },
        "error": {
          "code": null,
          "message": null
        },
        "index": 1
      }
    ],
    "summary": {
      "approved": 1,
      "billable_decisions": 1,
      "denied": 1,
      "errored": 1,
      "refused": 1,
      "total": 102,
      "total_cost_micros": 1
    }
  }
  ```
</ResponseExample>
