> For the complete documentation index, see [llms.txt](https://peoplescourt.ai/llms.txt). This page is also available as Markdown.

# Errors

API errors use `application/problem+json`. Branch on `code`: it is stable, while `detail` is written for people and can change.

```json
{
  "type": "https://peoplescourt.ai/problems/acceptance_required",
  "title": "Acceptance Required",
  "status": 409,
  "code": "acceptance_required",
  "detail": "The claimant must accept the prepared filing packet before the case can open.",
  "requestId": "req_9fe76389-b3c1-47cb-81a3-832478d2b8e9",
  "details": {
    "termsDigest": "fdf857fb83cd64c0535a8da6b4b5073fb0ce6839e99cd40dd95972937c635107"
  }
}
```

| Field | Description |
|---|---|
| `code` | Stable machine-readable error code |
| `status` | The HTTP status, repeated in the body |
| `detail` | Human-readable explanation |
| `requestId` | Also sent as the `x-request-id` header. Include it when you contact support. |
| `details` | Optional structured data for the specific error |

Log `requestId`. Never log bearer credentials, invitation links, party capabilities, wallet signatures, or evidence bytes.

## Status codes

| Status | Meaning | What to do |
|---|---|---|
| `400` | Malformed request or missing required header | Fix the request |
| `401` | Missing or invalid credential or proof | Reauthenticate |
| `403` | The credential lacks the role, side, membership, or authority | Do not retry unchanged |
| `404` | Not found, or hidden from this tenant | Check the tenant and identifier |
| `409` | State, digest, revision, idempotency, or phase conflict | Read the current state first |
| `413` | Request or evidence payload too large | Reduce the payload |
| `422` | Well-formed request that violates the contract | Fix the reported fields |
| `429` | Rate limit reached | Wait for `Retry-After`, then retry |
| `503` | Feature or dependency unavailable | Retry later with backoff |

## Common codes

| Code | Status | Meaning |
|---|---|---|
| `acceptance_required` | `409` | The claimant has not accepted this filing packet. `details.termsDigest` identifies it. An authorized claimant caller can also receive `details.reviewPacket` and, when a new link is issued, a show-once `details.hostedAcceptanceUrl` that replaces the previous link. Keep its fragment private. |
| `filing_packet_changed` | `409` | The packet changed after acceptance. Prepare a new packet and obtain acceptance again. |
| `case_revision_conflict` | `409` | The case changed while a settlement binding was being registered. Read the case, then retry with a new idempotency key. |
| `settlement_binding_registration_closed` | `409` | Settlement bindings can be registered only in `awaiting_submissions` or `awaiting_validation` and before an Award exists. |
| `fast_track_record_limit` | `422` | The filing would take the filing party past its Rule 4.12 allowance in an AI-only fast case: 16,000 characters of text, two text exhibits, ten extracted exhibit pages, or text only. Each party has its own allowance. `detail` names the limit and the party. Shorten the filing or keep only the best evidence. |
| `fast_track_counterclaim_not_available` | `422` | A fast case decides only the claimant's claim. Answer without requested relief, and file a separate case to claim against the claimant. |
| `message_channel_required` | `422` | The message `channel` query parameter is missing or invalid. Partner credentials send `channel=partner_notice`. |
| `rate_limited` | `429` | A request budget is exhausted. See [Rate limits](https://peoplescourt.ai/docs/api/rate-limits.md). |
| `message_rate_limit_exceeded` | `429` | One credential sent 20 messages to one case within a rolling hour. |

Replaying the original successful request with the same `Idempotency-Key` and body returns the stored response, even if the case has since moved on.

## Account OAuth errors

Account operations can instead return the OAuth envelope, with `error` and `error_description`. Handle it separately from `code`. A missing account session returns `login_required`. When consent has lapsed, send the person through authorization again. A canonical route that is disabled on a deployment returns an empty `404`, so check the status and `Content-Type` before parsing JSON.

## Retry an uncertain request

After a timeout or a retryable server error, resend the original body with the original `Idempotency-Key`. A new key would create a second, distinct operation.

For `409`, read the resource, resolve the conflict, and send the changed request with a new key. For `429`, wait for `Retry-After` when present; otherwise use bounded exponential backoff with jitter.
