There is no standalone /api/credentialing endpoint, and that is deliberate. Provider legitimacy is not a report you fetch on the side — it is enforced inside the money path as condition 6 of the deterministic settlement gate. Every instruction that could move a dollar is screened against live government registries and a credentialing composite before the gate will ever pass. This page documents the three real routes through which that screen is run, read, and resolved.
Condition 6 is a composite screener: OIG-LEIE NPPES credentialing / primary-source verification (license, DEA, sanction, enrollment). It fails closed on any excluded, inactive, indeterminate, stale, or no-screener result — a provider is never reported clear when the screen could not affirmatively run. This is the sandbox surface — the screener runs on real logic against zero live data.
The gate evaluates six conditions in conjunction. Provider screening is the last of them, and it sits inside the same atomic evaluation that authorizes money — there is no path that disburses around it.
CLEAR result from the composite screener. A confirmed OIG-LEIE exclusion is EXCLUDED; a non-active NPPES record is INACTIVE; any unreachable source, error, or timeout is INDETERMINATE; an expired cached verdict is STALE; and a total absence of a configured screener is NO_PROVIDER_SCREENER. Every one of those blocks the gate.Canon note: the gate is six conditions per lib/settlement/gate.ts. One route docstring still reads “5-condition” — that is stale wording; trust the six-condition canon and the checklist above.
Runs the deterministic settlement gate for an encounter. Condition 6 (provider_screening) is a composite screener: OIG-LEIE NPPES credentialing / PSV (license / DEA / sanction / enrollment). It fails closed on EXCLUDED, INACTIVE, INDETERMINATE, STALE, or no configured screener. The gate disposes the instruction: a full pass moves it forward, any failed condition halts it into review. It never fabricates a pass. Every request is automatically scoped to your organization from your credentials — you never pass a clinic in the body or path.
INDETERMINATE and the gate halts — it is never silently treated as clear.| Name | Type | In | Required | Description |
|---|---|---|---|---|
encounterId | string | path | Required | The encounter to evaluate. 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 | First failed condition id (e.g. 'provider_screening'), or null when passed. |
conditions[].reason | string | Machine-stable reason code — e.g. PROVIDER_SCREEN_EXCLUDED, PROVIDER_SCREEN_INDETERMINATE, PROVIDER_SCREEN_STALE. |
# Evaluate the settlement gate; condition 6 screens the provider
curl -X POST "https://app.shteg.ai/api/settlement/gate/enc_9f2a41" \
-H "Content-Type: application/json" \
--cookie "$SHTEG_SESSION" \
-d '{ "force": false }'const res = await fetch(
`https://app.shteg.ai/api/settlement/gate/${encounterId}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ force: false }),
},
);
// { code, passed, status, firstFailed, conditions: [...] }
const disposition = await res.json();
if (disposition.firstFailed === "provider_screening") {
// provider blocked — read the reason code from conditions[]
}{
"code": "DISPOSED",
"passed": false,
"status": "HALTED",
"firstFailed": "provider_screening",
"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": false,
"reason": "PROVIDER_SCREEN_INDETERMINATE",
"source": "oig-leie+nppes"
}
]
}| Status | Meaning |
|---|---|
401 | Request is not authenticated. |
403 | Session is not authorized for this tenant. |
404 | No such encounter in your tenant — the gate never fabricates a pass. |
503fail-closed | Fail-closed: a required gate dependency (e.g. the screening source) is unconfigured; the gate refuses with zero network calls, never a fabricated clear. |
Read the current gate disposition for an encounter, including the named condition-6 provider-screening verdict. Only gateway-minimized fields — condition ids, pass flags, machine-stable reason codes, and the screen source — leave the boundary. No patient name, DOB, or clinical note is ever returned. Scoped to your organization from your credentials.
| 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). |
gate.passed | boolean | Whether all six conditions held. |
gate.conditions | object[] | The six conditions; condition 6 carries the provider-screening verdict. |
gate.conditions[5].reason | string | The condition-6 machine-stable reason code (OK, PROVIDER_SCREEN_EXCLUDED, …). |
curl "https://app.shteg.ai/api/settlement/gate/enc_9f2a41" \
--cookie "$SHTEG_SESSION"const res = await fetch(
`https://app.shteg.ai/api/settlement/gate/${encounterId}`,
{ credentials: "include" },
);
const { gate } = await res.json();
const screen = gate.conditions.find(
(c) => c.id === "provider_screening",
);
// screen.reason ∈ { OK, PROVIDER_SCREEN_EXCLUDED,
// PROVIDER_SCREEN_INACTIVE, PROVIDER_SCREEN_INDETERMINATE,
// PROVIDER_SCREEN_STALE, PROVIDER_SCREEN_NO_NPI }{
"instructionId": "si_7c1e",
"encounterId": "enc_9f2a41",
"status": "GATED",
"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,
"reason": "OK",
"source": "oig-leie+nppes"
}
]
}
}| Status | Meaning |
|---|---|
401 | Request is not authenticated. |
403 | Session is not authorized for this tenant. |
404 | No settlement instruction exists for this encounter yet. |
503fail-closed | Fail-closed: a required dependency is unconfigured; nothing is synthesized. |
A PHI-free directory of the active providers for your clinic — the NPI identities the condition-6 screener resolves against. Returns billing/rendering identity fields only (no patient data). Requires an authenticated staff session and the appointments:read permission. Reads only — no provider record is ever synthesized.
| Field | Type | Description |
|---|---|---|
count | number | Number of active providers returned. |
providers | object[] | Active providers scoped to your clinic. |
providers[].npi | string | The provider NPI the screener resolves against OIG-LEIE + NPPES. |
providers[].name | string | Provider display name (no patient PHI). |
providers[].active | boolean | Whether the provider is active in your clinic. |
curl "https://app.shteg.ai/api/providers" \
--cookie "$SHTEG_SESSION"const res = await fetch("https://app.shteg.ai/api/providers", {
credentials: "include",
});
// { count, providers: [{ npi, name, active, ... }] }
const { providers } = await res.json();| Status | Meaning |
|---|---|
401 | Request is not authenticated. |
403 | Session lacks the appointments:read permission. |
503fail-closed | Fail-closed: a required dependency is unconfigured; no directory is fabricated. |
The differentiator is the honesty of the register. We separate the sources that are live and free inside the money path from the credentialing adapters that are code-complete but unconfigured — and we never let the second group fabricate a clear.
OIG-LEIE (oig.hhs.gov/exclusions/iapi) and CMS NPPES (npiregistry.cms.hhs.gov/api) are live, free, public government APIs — no API key, fixed hosts — queried inside the money path. A provider is reported CLEAR only on an affirmative clean OIG exclusion check an active NPPES record. An unreachable OIG or NPPES is never treated as clean; it resolves to INDETERMINATE and blocks.
FSMB (license), NPDB (adverse actions), CAQH ProView (enrollment), DEA, and SAM.gov debarment adapters are code-complete but unconfigured. Each returns configured: false ⇒ INDETERMINATE upstream — never a fabricated clear. When these gate on named vendor credentials, the composite tightens from OIG+NPPES to full PSV without changing the fail-closed contract.
EXCLUDED > INACTIVE > INDETERMINATE > STALE. A single confirmed exclusion halts the whole instruction. A cached verdict past its TTL is STALE and re-screens rather than trusting stale data.Machine-stable codes returned on the provider_screening condition. They are stable across releases so you can branch on them programmatically.
| Field | Type | Description |
|---|---|---|
OK | clear | Affirmative clean OIG exclusion check ∧ active NPPES record across all NPIs. The only passing code. |
PROVIDER_SCREEN_EXCLUDED | block | A confirmed OIG-LEIE exclusion cross-referenced to the NPI. Highest severity. |
PROVIDER_SCREEN_INACTIVE | block | A non-active NPPES record for the NPI. |
PROVIDER_SCREEN_INDETERMINATE | block | A source errored, timed out, or was unreachable — the screen could not affirmatively clear. |
PROVIDER_SCREEN_STALE | block | A cached verdict past its TTL; re-screens rather than trusting stale data. |
PROVIDER_SCREEN_NO_NPI | block | No NPI to resolve on the instruction — nothing to screen, so it cannot clear. |
NO_PROVIDER_SCREENER | block | No screener is configured at all — condition 6 fails closed rather than skipping. |
Provider screening is condition 6 of the settlement gate, not a bolt-on report. OIG-LEIE and NPPES are queried live and free inside the gate; the FSMB / NPDB / CAQH / DEA / SAM adapters are not yet available until their credentials are configured, returning INDETERMINATE in the meantime. A provider clears only on an affirmative result, never by default. This is the sandbox surface — the screener runs on real logic against zero live data.