Skip to main content
Use this when a task needs a decision you can defend — refunds, eligibility, policy compliance, safety approvals — or a machine-checkable proof rather than a guess. It drives the NSR reasoning API at api.nsr.stateset.com directly over HTTP or through the stateset-nsr-mcp MCP server. NSR returns one of exactly three accountable outcomes — approved, denied, or refused — with cited rules, a replayable derivation, and a sha256 policy pin. There is no path from an ungrounded model answer to a confident approval.

Connect

Base URL: https://api.nsr.stateset.com. On every call send X-API-Key: nsr_… and X-Org-ID: <your org> (a Authorization: Bearer nsr_… header is accepted in place of the API-key header). Get a key in the console: nsr.stateset.com → API setup → Organization API keys; the secret is shown once. Prefer MCP if your harness speaks it — 36 typed tools, retry-safe, with client-side validation:
nsr_decide is the flagship tool; nsr_verify_proof, nsr_record_outcome and nsr_calibration close the proof and outcome loops.

Make a verified decision

POST /v1/decisions
Read from the response:
  • decisionapproved | denied | refused. Treat refused as “stop and verify”, never as a soft yes.
  • proof.cited_rules, proof.derivation — the rules and replayed steps the verdict stands on. proof.request_policy_hash pins the exact policy inputs.
  • refusal.missing_facts — unsatisfied premises [{predicate, args, needed_by_rule}]. Look each one up with your tools, assert it, and retry. Absent on safety-gated refusals; those need a human, not a retry.
  • verifiable_bundle — present only on approvals that declared an authorization_goal; see below.

Verify the proof independently

An approval’s verifiable_bundle ({facts, rules, proof, org_id}) is self-contained. POST it verbatim to POST /v1/proofs/verify — a stateless kernel that reads no tenant state — and require {"verified": true} before acting on a high-stakes approval. A failure returns the located reason and step.

Report what actually happened

Send external_ref (your order or ticket id) on the decide, then close the loop:
Outcomes: honored | reversed | overridden | escalated. This feeds GET /v1/decisions/calibration — ECE and reliability bins — which tells you whether NSR’s stated confidence can be trusted at each level.

Teach durable policy

  • POST /api/v1/rules — store an org rule. Shape: head_predicate, head_args, body: [{predicate, args, negated?}]. Intent comes from head naming (may_* permits, *_blocked denies, *_requires_review) or an explicit effect.
  • POST /api/v1/rules/lint before install; POST /api/v1/rules/batch to load a book. Decide with hydrate_org_context: true to use stored policy.
  • POST /api/v1/facts and entities for org knowledge; POST /api/v1/backward-chain proves against the stored org KB only.

Two encodings that trip agents up

  1. Facts are an envelope: {"predicate": {"name": "…", "args": […]}} — not a flat atom.
  2. Request-scoped rules use if / then atoms keyed by name; stored rules use head_predicate / head_args / body atoms keyed by predicate. The error messages do not always say which one was expected.

Guardrail

Before any consequential action — refund, access grant, data change — decide first, act only on approved, and log decision_id and proof.request_policy_hash with the action. On refused, gather the named missing facts and retry. On requires_human_review, escalate.

Further reading