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

# Use Industry Packs with the Decisions API

> Build a full Jev-backed NSR decision request from an industry scenario, submit it, inspect evidence and proof, and integrate the result.

**Outcome:** submit one industry case and explain the resulting decision using its model
readings, evidence admission, and policy proof. This walkthrough uses the retail pack;
the same request builder supports all [seven industries](/guides/jev-industry-packs).

## Choose the correct API

| Path                                                         | Request body                               | Credentials                                                        | Policy and evidence                                                    |
| ------------------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| Public demo: `POST /api/jev/decisions` on the console origin | `industry`, `scenario`, optional `message` | `X-Jev-Api-Key`                                                    | Fixed by the server's catalog                                          |
| Direct engine: `POST /v1/decisions` on your NSR origin       | Full decision request built below          | NSR key and organization, plus request-scoped Jev credentials      | Supplied by your authorized backend, subject to engine/tenant controls |
| Signed-in Playground                                         | UI constructs the full request             | Console session; saved organization Jev connection when configured | Editable in your workspace                                             |

The public response wraps the decision in `result`. The direct engine returns the decision
at the top level. A pack's `industry` and `scenario` identifiers alone are not a direct-engine
decision request. See [public first decision](/guides/jev-first-decision) for the shorter demo path.

## 1. Confirm your engine and credentials

Use Bash, curl, jq, and Node.js 20.20+. Set the variables below through your normal credential
mechanism. `NSR_BASE_URL` is the trusted engine origin without a `/v1` suffix; use HTTPS outside
local development. An NSR key authenticates your tenant access. A Jev key pays for the model
readings and is not interchangeable with the NSR key.

```bash theme={null}
: "${NSR_BASE_URL:?Set your trusted NSR engine origin}"
: "${NSR_API_KEY:?Set your NSR API key}"
: "${NSR_ORG_ID:?Set your authorized organization ID}"
curl --fail-with-body --silent --show-error \
  --connect-timeout 10 --max-time 30 \
  "${NSR_BASE_URL%/}/v1/integrations/jev/capabilities" \
  -H "X-API-Key: ${NSR_API_KEY}" \
  -H "X-Org-ID: ${NSR_ORG_ID}" \
  --output jev-capabilities.json
jq -e '.provider == "jev" and .request_scoped_credentials == true' jev-capabilities.json
```

Proceed only if that check succeeds. Capability discovery describes support; it does not
prove your Jev key is valid or that a provider call will succeed. Direct calls do not retrieve
the Jev key saved in the console. Use a test organization for these synthetic cases.

## 2. Build a complete request locally

Download the [retail pack](/examples/jev/packs/04_retail.json) as `04_retail.json` and the
[request builder](/examples/jev/build-request.mjs) as `build-request.mjs`. Inspect both files,
then run:

```bash theme={null}
node build-request.mjs 04_retail.json RT-4001 > jev-decision-request.json
jq '{query, action, authorization_goal, facts, rules, judgments, judgment_state,
     source_trust, premise_requirements, hydrate_org_context}' jev-decision-request.json
```

This step is offline. It preserves the pack's rules and trust requirements, replaces
`{subject}` in the model questions, and translates fixture `age_secs` values into
`provenance.observed_at`. Generate shortly before a test; keep the emitted JSON to preserve
what you submitted. Do not refresh real evidence timestamps this way.

The builder excludes `judge`, `expect`, and other test metadata. Jev must produce the readings
for the actual request. `hydrate_org_context: false` avoids adding the org knowledge base to
this example; it does not bypass authorization, tenant controls, or all organization policy.

## 3. Understand the request before sending it

| Field                           | Retail example                                           | Why it matters                                                             |
| ------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------- |
| `query`                         | Refund on a damaged-goods return for RT-4001?            | Human-readable question                                                    |
| `action`                        | `issue_refund`                                           | Operation whose permission is being evaluated                              |
| `authorization_goal`            | `{"name":"may_refund","args":["RT-4001"]}`               | Exact, grounded goal; no free variables                                    |
| `facts`                         | Order placed, amount 45, delivery state, with provenance | Evidence candidates rather than text the model must invent                 |
| `source_trust`                  | `order_system: authoritative`                            | Policy's trust classification, controlled by your backend                  |
| `premise_requirements`          | Authoritative amount; conflicting amounts escalate       | Admission conditions before claims support a proof                         |
| `judgments`                     | Damage plausibility, kind, abuse signal                  | Narrow typed questions that become policy premises                         |
| `judgment_state`                | Subject and customer message                             | Context sent for model evaluation; include only necessary data             |
| `rules`                         | Two permits and one deny                                 | Explicit policy, including caps and probability thresholds                 |
| `mode` / `confidence_threshold` | `safe` / `0.5`                                           | Reasoning settings; these do not replace the rule's `0.8` damage threshold |

Keep the authorization goal, evidence subjects, and judgment subjects aligned. For a real
integration, facts come from verified records and the policy comes from your controlled
configuration. Neither is supplied by an untrusted customer or generated to obtain approval.

## 4. Submit one decision

This step makes live model calls and may incur usage. It evaluates permission; it does not
execute the refund. Continue in the shell configured above:

```bash theme={null}
: "${JEV_API_KEY:?Set your Jev API key}"
curl --fail-with-body --silent --show-error \
  --connect-timeout 10 --max-time 120 \
  "${NSR_BASE_URL%/}/v1/decisions" \
  -H "X-API-Key: ${NSR_API_KEY}" \
  -H "X-Org-ID: ${NSR_ORG_ID}" \
  -H "X-NSR-Jev-Key: ${JEV_API_KEY}" \
  -H 'X-NSR-Jev-Model: jev-latest' \
  -H 'Content-Type: application/json' \
  --data-binary @jev-decision-request.json \
  --dump-header jev-decision-headers.txt \
  --output jev-decision-response.json
```

Inspect the curl exit status and HTTP status before treating the file as a decision. There
are no automatic retries in this example. A timeout leaves the outcome unknown; public-demo
idempotency capabilities do not establish the same behavior on the direct engine endpoint.

## 5. Read the decision, not just HTTP 200

```bash theme={null}
jq -e '.decision == "approved" or .decision == "denied" or .decision == "refused"' \
  jev-decision-response.json
jq '{decision_id, decision, plain_explanation, rationale, judgments, evidence,
     proof, routing, refusal}' jev-decision-response.json
```

| Inspect                                            | What to ask                                                                                   |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `decision`                                         | Did policy approve, explicitly deny, or refuse to establish permission?                       |
| `judgments.model` and `judgments.judgments`        | Which model resolved, what readings did it produce, and what agreement evidence is present?   |
| `evidence`                                         | Which claims were rejected, left unknown, or conflicted? Is human review required?            |
| `proof.cited_rules` and the returned proof details | Which rules and premises actually support this result?                                        |
| `routing.band`                                     | Is the result routed to `act`, `confirm`, or `escalate`? Routing does not change the verdict. |
| `refusal`                                          | Which missing premises or failed conditions explain non-approval?                             |

Treat `routing.band == "escalate"`, `evidence.requires_human_review`, and
`refusal.requires_human_review` as review signals. An `approved` result is not an instruction
to skip confirmation or execution controls. `denied` and `refused` are both non-authorizing
outcomes, but only a denial establishes an applicable blocking policy; a refusal may mean
missing evidence, uncertainty, or review is needed.

<div className="ss-checkpoint">
  **Complete when:** you can identify the subject and goal, explain the readings and admitted
  evidence, and point to the rule result or refusal reason. An approval is not required.
  Retain the exact request, response, and request/decision identifiers according to your data policy.
</div>

## 6. Compare a boundary or conflict

Build `RT-4010` to inspect contradictory authoritative amounts, or `RT-4013` to inspect the
amount above the transit-damage cap. Run each as a separate, deliberate call and save its
request and response under a distinct filename. Do not automatically loop over 106 live cases.

The fixture expects refusal for both, with human review in `RT-4010`. Compare the evidence and
proof, not just the verdict. For another industry, download its pack and use its scenario ID
with the same builder. The public demo catalog and this snapshot can differ.

## 7. Move from a test to an application

Keep four responsibilities explicit: your backend gathers authentic records, your policy
defines permission, NSR evaluates it with Jev readings where needed, and your executor carries
out an authorized operation. Recheck resource state and permission at execution time and use
the downstream service's idempotency contract. A decision ID or `external_ref` alone does not
deduplicate a payment.

When available, retain and verify the original `verifiable_bundle` using the
[proof-verification workflow](/stateset-nsr-decisions#verify-a-proof-without-trusting-us).
Do not rebuild a bundle from a few displayed fields. A valid derivation proves the relationship
between supplied premises and rules; it does not independently authenticate real-world records.
Record the actual outcome through the [outcome loop](/stateset-nsr-decisions#the-outcome-loop)
to evaluate policy performance rather than counting approvals as successful business actions.

## Troubleshooting

| Symptom                                   | Next step                                                                                                                |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Capability check fails                    | Confirm the engine origin, version, and tenant authentication; do not send a Jev secret to an unverified replacement URL |
| Invalid request                           | Check that you sent the built request, not a pack or public-demo body; preserve predicate argument types                 |
| Provider or engine error                  | Inspect the response and provider configuration; do not turn a missing reading into a fact or retry automatically        |
| Refusal on a fresh test                   | Inspect evidence sources, timestamps, missing conditions, conflicting values, and actual readings                        |
| Result differs from the fixture           | Fixture readings are controlled; inspect live readings and deployed policy behavior before changing a rule               |
| Approval with confirmation/review routing | Follow the required workflow before execution                                                                            |

Source basis: `nsr-app/src/industryPacks.ts`, `server/public-jev.mjs`, and
`stateset-nsr/src/api/handlers/decisions.rs` and `src/api/jev_credentials.rs`, reviewed 2026-09-21.
The downloadable builder is tested offline across all 106 cases; this guide does not claim
live provider verification.
