> ## 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.

# Most recent decisions for the org, newest first. Ephemeral in-memory

> analytics — billing truth lives in the metering pipeline. **Required scope:** read

analytics — billing truth lives in the metering pipeline.

**Required scope:** `read`

### Response

`RecentDecisionsResponse`

<ResponseField name="has_more" type="boolean">
  True when more records exist beyond this page, so a caller knows to keep going rather than guessing from a short page.
</ResponseField>

<ResponseField name="limit" type="integer" required>
  The effective limit applied to this page.
</ResponseField>

<ResponseField name="offset" type="integer">
  The offset this page started at.
</ResponseField>

<ResponseField name="records" type="DecisionRecord[]" required>
  <Expandable title="DecisionRecord">
    <ResponseField name="batch" type="boolean" required>
      True when the decision came through `/v1/decisions/batch`.
    </ResponseField>

    <ResponseField name="billable" type="boolean" required />

    <ResponseField name="cited_rules" type="string[]" required>
      Rule ids cited in the proof chain.
    </ResponseField>

    <ResponseField name="confidence" type="number (double)">
      The confidence the decision reported, in \[0, 1]. Stored so calibration can bucket decisions by what they claimed and compare against what actually happened (see `outcome`).
    </ResponseField>

    <ResponseField name="cost_micros" type="integer (int64)" required />

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

    <ResponseField name="decision_id" type="string">
      The `decision_id` returned in the API response and carried by the `outcome.produced` webhook — the correlation key for audits.
    </ResponseField>

    <ResponseField name="dropped_citations" type="string[]">
      Org rules that fired during hydration but were dropped from the proof as unrelated — the audit record of standing-rule noise per decision.
    </ResponseField>

    <ResponseField name="external_ref" type="string">
      Optional client-supplied correlation key (their order id, case id, claim number…). This is what closes the outcome loop from REAL events: a chargeback or override webhook knows the order id, not our `decision_id`, so `POST /v1/decisions/outcome-by-ref` records the outcome by this key. `None` when the caller didn't supply one.
    </ResponseField>

    <ResponseField name="latency_ms" type="integer (int64)" required />

    <ResponseField name="missing_predicates" type="string[]">
      Deduped predicate names from a refused decision's `refusal.missing_facts` — the KB coverage gaps that blocked it. Empty for approvals/denials and safety-gated refusals (which carry none).
    </ResponseField>

    <ResponseField name="outcome" type="string">
      The real-world outcome, recorded AFTER the fact via `POST /v1/decisions/&#123;id&#125;/outcome`: `honored` (the decision held up), `reversed` (e.g. an approved refund was charged back), `overridden` (a human changed it), or `escalated`. `None` until reported. This is the ground truth that turns confidence from a heuristic into a calibrated, measurable number.
    </ResponseField>

    <ResponseField name="query" type="string" required>
      The decision query, truncated to 200 chars for memory hygiene.
    </ResponseField>

    <ResponseField name="request" type="object">
      <Expandable title="request">
        <ResponseField name="action" type="string" />

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

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

        <ResponseField name="facts" type="RecursiveChatFactInput[]" />

        <ResponseField name="hydrate_org_context" type="boolean" />

        <ResponseField name="max_depth" type="integer" />

        <ResponseField name="mode" type="string" />

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

        <ResponseField name="rules" type="RecursiveChatRuleInput[]" />
      </Expandable>
    </ResponseField>

    <ResponseField name="request_policy_hash" type="string">
      `sha256:&lt;hex>` over the request-scoped policy the decision was evaluated against (see `DecisionProof::request_policy_hash`) — lets an audit confirm a replay uses the same policy inputs.
    </ResponseField>

    <ResponseField name="timestamp" type="string (date-time)" required />
  </Expandable>
</ResponseField>

### Status codes

| Code  | Meaning                                            |
| ----- | -------------------------------------------------- |
| `200` | Recent decision records                            |
| `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 GET \
    --url 'https://api.nsr.stateset.com/v1/decisions/recent' \
    --header 'X-API-Key: YOUR_API_KEY'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "has_more": true,
    "limit": 20,
    "offset": 1,
    "records": [
      {
        "batch": true,
        "billable": true,
        "cited_rules": [],
        "confidence": 7.5,
        "cost_micros": 1,
        "decision": "string",
        "decision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "dropped_citations": [],
        "external_ref": "string",
        "latency_ms": 250,
        "missing_predicates": [],
        "outcome": "string",
        "query": "string",
        "request": {
          "action": null,
          "authorization_goal": null,
          "confidence_threshold": null,
          "facts": null,
          "hydrate_org_context": null,
          "max_depth": null,
          "mode": null,
          "query": null,
          "rules": null
        },
        "request_policy_hash": "string",
        "timestamp": "2026-08-31T14:22:05Z"
      }
    ]
  }
  ```
</ResponseExample>
