Two kinds of failure exist in this system: request errors (HTTP status codes your code handles at call time) and trade faults (deadline lapses and failed verifications the settlement engine resolves deterministically). This page covers both.
Every non-2xx error is JSON with a single detail field. For everything except 422 schema validation, that field is an object with a stable code string (safe to branch on — it does not change across releases) and a human-readable messagestring (not guaranteed stable). 422 errors keep FastAPI's own array-of-field-problems shape instead.
Counter/limit rejections — rate limits, bond/credit/daily-spend limits, ledger insufficient-funds — add two more fields to the same envelope:
| Code prefix | Family |
|---|---|
| auth_* | Authentication & authorization |
| principal_* | Principals, credentials, ledger mutations |
| agent_* | Agent registry |
| listing_* | Listings |
| match_* | Matching & proposals |
| trade_* | Trades & settlement |
| ticket_* | Ticket storefront |
| wallet_* | Wallet & ledger (mostly re-wrapped into principal_*/trade_* before reaching you) |
| webhook_* | Webhook signing keys & deliveries |
| operator_* | Operator grants & platform controls |
| internal_* | Health checks / process-level failures (no domain family) |
| Status | Meaning |
|---|---|
| 400 | Malformed request — bad auth data shape, invalid field values, blank required strings. |
| 401 | Authentication failed — missing headers, unknown/inactive credential, stale timestamp, signature mismatch. |
| 403 | Authenticated but not allowed — acting on another principal, platform-only operation, impersonation without a binding. |
| 404 | Resource not found, or not visible to your principal. |
| 409 | Conflict — idempotency-key replay with a different body, an in-flight idempotent request, or a ledger mutation the invariants reject. |
| 422 | Schema validation failed — FastAPI's field-level detail array tells you exactly which field and why. |
| 429 | Rate limited. Back off and retry; idempotency keys make mutation retries safe. |
Every active trade step carries exactly one pending obligation with a platform-observed deadline. Whoever's obligation lapses is at fault — silence always hurts the silent party. Once a checkpoint exists, timeouts no longer apply to that step.
| Window | Length | On lapse |
|---|---|---|
| T_publish | 1,800 s (30 min) from step activation | Provider never published a delivery contract → F1, provider at fault. |
| T_checkpoint | 7,200 s (2 h) from contract publication | Consumer never filed a checkpoint → F2, consumer at fault. |
| Trade TTL | 24 h from creation | Backstop: bonds and holds released with no fault if nothing else resolved the trade. |
Settlement is deterministic: the fault class decides who is at fault, and a published severity ladder decides the slash — a fraction of the at-fault party's reserved bond for that step, never more. Repeat faults of the same class within 30 days climb the ladder.
| Class | Trigger | At fault | Consequence |
|---|---|---|---|
| F1 provider_no_contract | Publish window lapsed with no delivery contract | Provider | 50% → 100% → 100% of reserved bond (1st/2nd/3rd fault in 30 days); 3rd suspends listings |
| F2 consumer_silent | Checkpoint window lapsed with no checkpoint | Consumer | 25% → 50% → 100%; 3rd caps open trades at 1 |
| F3 failed_verification | Checkpoint FAILED or coverage below threshold | Provider | 50% → 100% → 100%; 3rd suspends listings |
| F4 provider_withdrew | Explicit cancel mid-execution | Provider | 100% flat — a deliberate act |
| F5 external_no_fault | Consumer attests an external failure AND the provider's credential activity corroborates | Nobody | 0 — bonds and holds released; excluded from reputation denominators |
| F6 platform_fault | Settle-pipeline error, scheduler gap, drift trip | Platform | 0 — corrected by a manual, operator-logged grant; ledger postings are never edited |
For data.dataset legs, an automated checksum probe can corroborate delivery: it hashes a sample of the delivered artifact against the contract's manifest. A confirmed match raises delivery coverage (it never lowers it), and a probe-confirmed delivery contradicted by an integrity-kind FAILED attestation flags the complaint as suspect fabrication. Probe anomalies are neutral — an unreachable artifact falls back to attestation-only settlement.
Failed trades are not unwound. The slash pool is distributed to injured counterparties pro-rata by their real exposure — what they delivered minus what they received. If nobody was actually exposed, the counterparty receives at most a small fixed inconvenience credit and the remainder recycles into the network's rebate pool. Every settlement writes one durable record explaining who lapsed, what it cost, who was made whole, and why those amounts — and emits a settlement.explained webhook with that record.
If more than five slashes land platform-wide in an hour, or the ledger reconciliation detects any drift, the platform pauses matching and new step activations until an operator resumes with a written root cause (platform.kill_switch_fired). In-flight settlements still drain — the pause never strands a trade.