The settlement rail is the money surface of shteg.ai: a hash-chained WORM double-entry ledger, a deterministic six-condition gate that is the sole authorizer of any instruction, and an 835 reconciliation waterfall that allocates every remittance in conserving integer cents. These endpoints let you evaluate the gate, read a PHI-free disposition, execute a signed instruction, submit a banking-partner batch wire, and post an ERA into the ledger.
This is the sandbox surface — the real gate and reconciliation logic at zero advance. No live money or live patient data is reachable from this tier; production access is a separate approval. Every endpoint fails closed — an unconfigured transport returns a typed 503 with zero network calls and never a fabricated confirmation.
Every request is JSON over HTTPS against your sandbox origin. Every API request is authenticated before it reaches a handler; authorization is scope-checked per request.
Requests are automatically scoped to your organization from your credentials — you never pass an organization or clinic identifier in the body or a param. One organization can never read or execute against another’s instructions.
Reads require shtegpay:read ; money writes require shtegpay:write — the same scope the operator console executes under.
Every amount is a conserving integer-cent value (advanceAmountCents, availableCents). Floating dollars never cross the boundary; the waterfall preserves the cent total exactly.
One encounter = one instruction (keyed on encounterId). Execution is idempotent on the canonical WORM key. An unconfigured rail returns a typed 503, never a simulated success.
Provider legitimacy lives inside the money path. The gate evaluates six conditions in conjunction; if any one fails, the instruction halts. A kill-switch and a database-level halt sit above all of it.
Manually run the deterministic gate for an encounter. The gate disposes: PASS moves the instruction to GATED, a failed condition HALTS it into the review queue. It never fabricates a pass.
Scope shtegpay:write
| Name | Type | In | Required | Description |
|---|---|---|---|---|
encounterId | string | path | Required | The signed encounter to evaluate. The gate is always scoped to your tenant. |
force | boolean | body | Optional | Bypass the same-visit debounce on a deliberate re-run. Defaults to false. |
| Field | Type | Description |
|---|---|---|
code | string | DISPOSED when the gate ran; ENCOUNTER_NOT_FOUND on a missing encounter. |
passed | boolean | True only when all six conditions held in conjunction. |
status | string | Resulting instruction status — GATED on pass, HALTED on any failure. |
firstFailed | string | null | The identifier of the first failed condition, or null when passed. |
# Evaluate the settlement gate for an encounter
curl -X POST "https://your-sandbox-origin.example/api/settlement/gate/enc_9f2a41" \
-H "Content-Type: application/json" \
-H "Cookie: $SHTEG_SESSION" \
-d '{"force": false}'const res = await fetch(
`/api/settlement/gate/${encounterId}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ force: false }),
},
);
const disposition = await res.json();
// { code, passed, status, firstFailed }{
"code": "DISPOSED",
"passed": false,
"status": "HALTED",
"firstFailed": "provider_screening"
}| Status | Meaning |
|---|---|
401 | Request is not authenticated. |
403 | Session lacks the shtegpay:write scope. |
404 | No such encounter in your organization — the gate never fabricates a pass. |
503fail-closed | A gate dependency (e.g. the screening source) is unconfigured; the gate refuses with zero network calls. |
Evaluate the six-condition gate for an encounter. This example shows a HALTED disposition — provider screening returned indeterminate, so the instruction never advances.
curl -X POST https://api.shteg.ai/api/settlement/gate/[encounterId] \
-H "Authorization: Bearer $SHTEG_TOKEN" \
-H "Content-Type: application/json" \
-H "Cookie: $SHTEG_SESSION" \
-d '{
"force": false
}'Read the PHI-free gate disposition for an encounter. Only gateway-minimized fields (codes, statuses, reasons) leave the boundary — never a patient name, DOB, or note.
Scope shtegpay:read
| Field | Type | Description |
|---|---|---|
instructionId | string | The settlement instruction derived from this encounter. |
encounterId | string | The originating encounter. |
status | string | Current instruction status (e.g. GATED, HALTED, SIGNED, DISBURSED). |
version | number | Monotonic version of the instruction. |
disposedAt | string | null | ISO-8601 timestamp of the disposition, or null if undisposed. |
gate | object | null | The PHI-free gate section of the disposition payload. |
curl "https://your-sandbox-origin.example/api/settlement/gate/enc_9f2a41" \
-H "Cookie: $SHTEG_SESSION"const res = await fetch(`/api/settlement/gate/${encounterId}`, {
credentials: "include",
});
const { instructionId, status, gate } = await res.json();{
"instructionId": "si_7c1e",
"encounterId": "enc_9f2a41",
"status": "GATED",
"version": 2,
"disposedAt": "2026-07-14T18:02:11.004Z",
"gate": {
"passed": true,
"conditions": [
{ "id": "ledger_balanced", "passed": true },
{ "id": "scrubber_clearance", "passed": true },
{ "id": "coding_validation", "passed": true },
{ "id": "signature_immutable", "passed": true },
{ "id": "dup_claim_276_277", "passed": true },
{ "id": "provider_screening", "passed": true }
]
}
}| Status | Meaning |
|---|---|
403 | Session lacks the shtegpay:read scope. |
404 | No settlement instruction exists for this encounter yet. |
503fail-closed | Fail-closed: a required dependency is unconfigured; no data is fabricated. |
Read the PHI-free disposition. Only minimized fields — codes, statuses, reasons, and illustrative ids — leave the boundary; never a patient name, DOB, or note.
curl -X GET https://api.shteg.ai/api/settlement/gate/[encounterId] \
-H "Authorization: Bearer $SHTEG_TOKEN" \
-H "Cookie: $SHTEG_SESSION"Read the settlement instruction derived from an encounter — the durable object the gate disposes and the console executes against.
Scope shtegpay:read
| Name | Type | In | Required | Description |
|---|---|---|---|---|
encounterId | string | path | Required | The encounter whose settlement instruction you want to read. |
| Field | Type | Description |
|---|---|---|
instruction | object | The clinic-scoped settlement instruction (status, version, advance amount in cents, and disposition metadata). |
curl "https://your-sandbox-origin.example/api/settlement/instructions/enc_9f2a41" \
-H "Cookie: $SHTEG_SESSION"const res = await fetch(
`/api/settlement/instructions/${encounterId}`,
{ credentials: "include" },
);
const { instruction } = await res.json();| Status | Meaning |
|---|---|
403 | Session lacks the shtegpay:read scope. |
404 | No encounter or instruction in your tenant. |
503fail-closed | Fail-closed: a required dependency is unconfigured; nothing is synthesized. |
Record the execution of a settlement instruction — the money authorizer. It halts on any failed gate condition and only ever disburses a SIGNED, KMS-signed, non-expired instruction with a positive advance funded from the advance pool (the FBO is never touched at origination).
Scope shtegpay:write
SIGNED → DISBURSED compare-and-swap, so an instruction executes at most once.| Name | Type | In | Required | Description |
|---|---|---|---|---|
instructionId | string | path | Required | The settlement instruction to execute (must belong to your tenant). |
railReference | string | body | Required | The banking-partner transfer reference. Operator-supplied; never fabricated. |
note | string | body | Optional | Optional operator note. Kept in the internal audit log only, never placed on the rail. |
| Field | Type | Description |
|---|---|---|
ok | boolean | True when the request was accepted. |
executed | boolean | True on a fresh disbursement; false on an idempotent replay. |
status | string | The resulting instruction status (DISBURSED on success). |
advanceAmountCents | number | The advance booked, in integer cents. |
ledgerEntryId | string | The WORM ledger entry id for the booked advance. |
entryHash | string | The hash-chain entry hash of the booking. |
curl -X POST \
"https://your-sandbox-origin.example/api/settlement/console/si_7c1e/execute" \
-H "Content-Type: application/json" \
-H "Cookie: $SHTEG_SESSION" \
-d '{"railReference": "WIRE-2026-071401", "note": "advance disbursement"}'const res = await fetch(
`/api/settlement/console/${instructionId}/execute`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ railReference: "WIRE-2026-071401" }),
},
);
const result = await res.json();{
"ok": true,
"executed": true,
"alreadyExecuted": false,
"instructionId": "si_7c1e",
"encounterId": "enc_9f2a41",
"status": "DISBURSED",
"advanceAmountCents": 42350,
"rail": "BANK_WIRE",
"disbursementRef": "WIRE-2026-071401",
"ledgerEntryId": "le_5d8a",
"entryHash": "sha256:9b1c..."
}| Status | Meaning |
|---|---|
400 | Missing or invalid railReference. |
403 | Session lacks the shtegpay:write scope. |
404 | No such instruction in your tenant. |
409 | Instruction is not executable — wrong status, past TTL, non-positive advance, or an inactive/insufficient advance pool. |
422 | Instruction is not KMS-signed; an unsigned instruction never disburses. |
503fail-closed | Fail-closed: settlement is globally or clinic-halted (kill-switch); nothing is posted. |
Record a disbursement against a SIGNED instruction. Requires a step-up header and an operator-supplied rail reference — no reference is ever synthesized. No live money is reachable from this tier; production access is a separate approval.
curl -X POST https://api.shteg.ai/api/settlement/console/[instructionId]/execute \
-H "Authorization: Bearer $SHTEG_TOKEN" \
-H "Content-Type: application/json" \
-H "Cookie: $SHTEG_SESSION" \
-H "x-shtegmed-step-up: $STEP_UP" \
-d '{
"railReference": "WIRE-2026-071401",
"note": "advance disbursement"
}'/api/settlement/consoleshtegpay:writeList the operator queue — SIGNED settlement instructions awaiting execution, ordered highest-priority first then FIFO, always scoped to your organization.
Generate, validate, and queue a banking-partner batch-wire file from approved instructions — the file-transmission upgrade over the manual console. GET lists the files generated for your clinic.
Scope shtegpay:write
The file is generated and validated (control totals, field shapes, PHI scan) and rejected with 422 on any failure. On success it is queued via a balanced WORM memo anchor that nets to zero — no cash moves at generation; the advance books only when an ack confirms. Transmission fails closed: without sFTP/PGP/signing credentials nothing is sent and the route returns 503 with the queued file, never a fabricated confirmation.
# Build + queue a batch-wire file from approved instructions
curl -X POST "https://your-sandbox-origin.example/api/settlement/batch-wire" \
-H "Content-Type: application/json" \
-H "Cookie: $SHTEG_SESSION" \
-d '{}'const res = await fetch("/api/settlement/batch-wire", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({}),
});
// 503 with the queued file if transport creds are unconfigured
const result = await res.json();| Status | Meaning |
|---|---|
403 | Session lacks the shtegpay:write scope. |
422 | File validation failed (control totals, field shapes, or PHI scan) — nothing queued. |
503fail-closed | Fail-closed: no sFTP/PGP/signing transport configured — the file is queued but not sent, and no confirmation is fabricated. |
Ingest a payer 835 remittance into the settlement rail and run the reconciliation waterfall — immutable archive, three-tier match, variance state machine, then an atomic pool → fee → reserve → residual post to the WORM ledger in conserving integer cents.
Two authenticated entry paths:
X-Shteg-Signature = hex HMAC-SHA256 of the raw body under your shared webhook secret. The clinic scope comes only from the signed body, so it cannot be tampered independently.claims:write) uploads a raw 835, or passes { clearinghouseTransactionId } to pull the raw X12 from the connected clearinghouse network.# Clearinghouse-of-record posts the raw 835, signed
SIG=$(printf '%s' "$EDI835" | openssl dgst -sha256 -hmac "$SHTEG_WEBHOOK_SECRET" -hex | sed 's/^.* //')
curl -X POST "https://your-sandbox-origin.example/api/settlement/era-post" \
-H "Content-Type: text/plain" \
-H "X-Shteg-Signature: $SIG" \
--data-binary "$EDI835"const res = await fetch("/api/settlement/era-post", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ clearinghouseTransactionId: "chc_txn_4471" }),
});
const result = await res.json();| Status | Meaning |
|---|---|
401 | Webhook signature absent or invalid. |
403 | Manual path: session lacks the claims:write scope. |
422 | An empty or unresolvable 835 — nothing is posted and no id is synthesized. |
503fail-closed | Fail-closed: the webhook secret or the clearinghouse transport is unconfigured; the route refuses with zero network calls. |
This is the sandbox surface — the real gate, WORM ledger, and reconciliation logic at zero advance. No live money or live patient data is reachable from this tier; production access is a separate approval. Where a rail is unconfigured, the endpoint returns a typed refusal, not a fabricated confirmation.