> ## 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, then draft — one call.

> **Required scope:** write

**Required scope:** `write`

### Request body

JSON body of type `ReplyRequest`.

### Response

`ReplyResponse`

<ResponseField name="decision" type="DecisionResponse" required>
  <Expandable title="DecisionResponse">
    <ResponseField name="action" type="object">
      <Expandable title="action">
        <ResponseField name="confidence" type="number (float)" required />

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

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

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

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

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

    <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>
      <Expandable title="DecisionGrounding">
        <ResponseField name="cited_rule_count" type="integer" required />

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

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

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

    <ResponseField name="gss_machine" type="GssMachineGroundingSnapshot" required>
      <Expandable title="GssMachineGroundingSnapshot">
        <ResponseField name="authority" type="string" required />

        <ResponseField name="categories" type="string[]" required />

        <ResponseField name="classification_confidence" type="number (double)" required>
          Confidence of the GSS perception/classification stage.
        </ResponseField>

        <ResponseField name="domains" type="string[]" required />

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

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

        <ResponseField name="grounded_symbol" type="string">
          Best-aligned canonical symbol under the variance-aware alignment.
        </ResponseField>

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

        <ResponseField name="horn_clauses_fired" type="string[]" required />

        <ResponseField name="inferred_symbols" type="string[]" required />

        <ResponseField name="intents" type="string[]" required />

        <ResponseField name="machine_confidence" type="number (double)" required>
          Confidence that NSRMachine recognized and executed the supplied grounded symbols. This is not an end-to-end decision confidence.
        </ResponseField>

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

        <ResponseField name="machine_state_version" type="integer (int64)">
          Chat-mutation version of the org's NSRMachine this decision inferred against, alongside `request_policy_hash` in spirit: two runs of the same request stamped with the same version had the same machine view; differing stamps make cross-run drift auditable rather than silent (FINDING-nondeterministic-outcome, option 3).
        </ResponseField>

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

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

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

        <ResponseField name="symbol_alignment" type="number (double)">
          Variance-aware (isotropic Mahalanobis) alignment of the message composite to that symbol's centroid, in (0,1]: `exp(−d²/2σ²)` with σ² the symbol's learned seed variance. Use this to assess grounding uncertainty — unlike the classification mixture score, it reflects the symbol's observed spread, not lexical overlap.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <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>
      <Expandable title="DecisionProof">
        <ResponseField name="cited_rules" type="string[]" required>
          Org rules cited in the derivation (the audit trail).
        </ResponseField>

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

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

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

        <ResponseField name="proof_score" type="number (double)" required>
          0–1 proof strength from the engine's validation pass.
        </ResponseField>

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

        <ResponseField name="request_policy_hash" type="string">
          `sha256:&lt;hex>` over the canonicalized request-scoped facts and rules — pins this decision to the exact policy inputs it was evaluated against. Absent when the request carried no inline policy.
        </ResponseField>

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

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

    <ResponseField name="refusal" type="object">
      <Expandable title="refusal">
        <ResponseField name="missing_facts" type="MissingFact[]">
          Request-scoped premises that would unblock an authorization proof: body atoms on the dependency path to a positive policy conclusion that neither the supplied facts nor any derivable conclusion satisfies. Empty for safety-gated refusals, which must not invite resubmission.
        </ResponseField>

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

        <ResponseField name="requires_human_review" type="boolean" required />
      </Expandable>
    </ResponseField>

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

      <Expandable title="RecursiveChatTraceStep">
        <ResponseField name="description" type="string" required />

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

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

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

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

        <ResponseField name="task_id" type="string" />
      </Expandable>
    </ResponseField>

    <ResponseField name="usage" type="DecisionUsage" required>
      <Expandable title="DecisionUsage">
        <ResponseField name="billable" type="boolean" required />

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

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

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

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

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

    <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 title="x_nsr">
        <ResponseField name="action_results" type="ActionExecutionResult[]" required />

        <ResponseField name="action_runtime" type="RecursiveChatActionRuntime" required />

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

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

        <ResponseField name="audit_trace" type="RecursiveChatTraceStep[]" />

        <ResponseField name="context" type="RecursiveChatContextSummary" required />

        <ResponseField name="cost" type="RecursiveChatCost" required />

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

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

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

        <ResponseField name="mode" type="RecursiveChatMode" required />

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

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

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

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

        <ResponseField name="suggested_actions" type="SuggestedAction[]" required />

        <ResponseField name="tool_calls" type="ToolCall[]" required />

        <ResponseField name="trace" type="RecursiveChatTraceStep[]" />

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

        <ResponseField name="uncertainty" type="RecursiveChatUncertainty" required />

        <ResponseField name="validation" type="RecursiveChatValidation" />
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="reply" type="object">
  <Expandable title="reply">
    <ResponseField name="auto_send" type="boolean" required>
      True only when the macro is approved, fully filled, its tool call fully bound, and the macro itself armed for auto-send. Anything less is a draft for a human.
    </ResponseField>

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

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

    <ResponseField name="missing_slots" type="string[]" required>
      Merge fields with no value supplied. Non-empty blocks sending.
    </ResponseField>

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

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

<ResponseField name="requires_human" type="string[]">
  Why a human is needed, when one is. Empty means this can ship.
</ResponseField>

<ResponseField name="tool_blocked_on" type="string[]">
  Tool arguments that could not be bound. Non-empty means the tool was withheld — and so was the reply, if it announces that action.
</ResponseField>

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

### Status codes

| Code  | Meaning                                            |
| ----- | -------------------------------------------------- |
| `200` | Decision plus the macro and tool call it selects   |
| `401` | Unauthorized — missing or invalid credentials      |
| `402` | Quota exhausted                                    |
| `403` | Forbidden — the key/token lacks the required scope |
| `422` | Malformed decision request                         |
| `429` | Rate limited — see Retry-After / X-RateLimit-Reset |

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.nsr.stateset.com/api/v1/replies' \
    --header 'X-API-Key: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
    "action": "string",
    "authorization_goal": {
      "args": [
        "string"
      ],
      "name": "Two-Person Tent",
      "negated": true
    },
    "confidence_threshold": 7.5,
    "external_ref": "string",
    "facts": [
      {
        "confidence": 7.5,
        "predicate": {
          "args": null,
          "name": null,
          "negated": null
        },
        "source": "string"
      }
    ],
    "hydrate_org_context": true,
    "include_trace": true,
    "kb_limits": {
      "max_entities": 1,
      "max_properties_per_entity": 1,
      "max_rules": 1,
      "max_triples": 1
    },
    "max_depth": 1,
    "max_iterations": 8,
    "mode": "string",
    "query": "string",
    "rules": [
      {
        "category": "standard",
        "constraints": [],
        "description": "Two-person tent, green — replacement for damaged pole set.",
        "effect": {
          "0": "p",
          "1": "e",
          "2": "r",
          "3": "m",
          "4": "i",
          "5": "t"
        },
        "enabled": true,
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "if": [],
        "name": "Two-Person Tent",
        "priority": 1,
        "then": []
      }
    ],
    "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "context": {}
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "decision": {
      "action": {
        "confidence": 7.5,
        "name": "Two-Person Tent",
        "ready": true,
        "reason": "Two-person tent, green — replacement for damaged pole set.",
        "rule_conclusion": "string",
        "rule_name": "string"
      },
      "confidence": 7.5,
      "decision": "string",
      "decision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "dropped_citations": [
        "string"
      ],
      "evaluated_goal": "string",
      "grounding": {
        "cited_rule_count": 1,
        "grounded_entity_count": 1,
        "grounded_target_count": 1,
        "status": "pending"
      },
      "gss_machine": {
        "authority": "string",
        "categories": [],
        "classification_confidence": 7.5,
        "domains": [],
        "escalation_triggered": true,
        "explanation": "string",
        "grounded_symbol": "string",
        "gss_v3_shadow": {
          "candidate_rules": null,
          "matched_predicates": null,
          "matched_symbols": null,
          "org_scoped": null
        },
        "horn_clauses_fired": [],
        "inferred_symbols": [],
        "intents": [],
        "machine_confidence": 7.5,
        "machine_output": "string",
        "machine_state_version": 1,
        "safety_gate_triggered": true,
        "seed_grounded": true,
        "seed_source": "string",
        "symbol_alignment": 1.5
      },
      "plain_explanation": "string",
      "proof": {
        "cited_rules": [],
        "derivation": {
          "authorizing_predicate": null,
          "cited_org_rules": null,
          "org_facts_used": null,
          "replayable": null,
          "steps": null
        },
        "neural_steps": 1,
        "planner_steps": 1,
        "proof_score": 7.5,
        "proof_status": "string",
        "request_policy_hash": "string",
        "symbolic_steps": 1
      },
      "rationale": "string",
      "refusal": {
        "missing_facts": [],
        "reason": "Two-person tent, green — replacement for damaged pole set.",
        "requires_human_review": true
      },
      "trace": [
        {
          "description": null,
          "duration_ms": null,
          "input": null,
          "output": null,
          "step_type": null,
          "task_id": null
        }
      ],
      "usage": {
        "billable": true,
        "billing_tier": "string",
        "elapsed_ms": 250,
        "iterations": 8,
        "max_depth_reached": 1,
        "outcome_cost_microdollars": 1
      },
      "verifiable_bundle": null,
      "warnings": [
        "string"
      ],
      "x_nsr": {
        "action_results": [],
        "action_runtime": {
          "approved_action_types": null,
          "blocked_action_types": null,
          "executed_action_types": null,
          "execution_receipt": null,
          "lifecycle_stage": null,
          "prepared_action_types": null,
          "review_required_action_types": null
        },
        "answer": null,
        "assistant_message": "string",
        "audit_trace": [],
        "context": {
          "hydrated_entities": null,
          "hydrated_rules": null,
          "hydrated_triples": null,
          "request_facts": null,
          "request_rules": null,
          "skipped_rule_names": null,
          "skipped_rules": null
        },
        "cost": {
          "api_surface": null,
          "billable_outcome": null,
          "billing_tier": null,
          "elapsed_ms": null,
          "estimated_cost_units": null,
          "iterations": null,
          "max_depth_reached": null,
          "neural_steps": null,
          "outcome_cost_microdollars": null,
          "planner_steps": null,
          "symbolic_steps": null
        },
        "explanation": "string",
        "facts": [],
        "goal": "string",
        "mode": "fast",
        "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "proof": {
          "cited_rules": null,
          "completed_tasks": null,
          "neural_steps": null,
          "planner_steps": null,
          "symbolic_steps": null
        },
        "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "success": true,
        "suggested_actions": [],
        "tool_calls": [],
        "trace": [],
        "trace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "uncertainty": {
          "aleatoric": null,
          "epistemic": null,
          "mandatory_review": null,
          "requires_human_review": null,
          "total": null
        },
        "validation": {
          "action_execution_eligible": null,
          "action_execution_reason": null,
          "cited_rule_count": null,
          "grounded_entity_count": null,
          "grounded_target_count": null,
          "grounding_status": null,
          "llm_backend_live": null,
          "llm_provider": null,
          "proof_score": null,
          "proof_status": null,
          "symbolic_step_count": null,
          "validation_level": null
        }
      }
    },
    "reply": {
      "auto_send": true,
      "macro_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "macro_name": "string",
      "missing_slots": [
        "string"
      ],
      "rendered": "string",
      "rule_name": "string"
    },
    "requires_human": [
      "string"
    ],
    "tool_blocked_on": [
      "string"
    ],
    "tool_call": null
  }
  ```
</ResponseExample>
