> ## Documentation Index
> Fetch the complete documentation index at: https://docs.casepathiq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors and safe retries

> Handle typed Problem Details responses, safe retries, and concurrent writes.

Errors use RFC 9457 Problem Details.

```http theme={null}
Content-Type: application/problem+json
```

```json theme={null}
{
  "type": "https://api.casepathiq.com/problems/usable_address_required",
  "title": "Usable address required",
  "status": 400,
  "detail": "Each Party needs exactly one usable correspondence address that meets the letter minimum.",
  "code": "usable_address_required",
  "requestId": "6f2c1b8e-3a41-4f43-9a55-6b2f0b1b7c10",
  "errors": [
    {
      "pointer": "/parties/1/addresses",
      "code": "usable_address_required"
    }
  ]
}
```

The `type` URI identifies the problem and equals `https://api.casepathiq.com/problems/` plus the `code`. Branch client logic on the top-level `code`, the stable outcome code for the response; use the per-field `errors[].code` values (at most 50) to locate what to correct. Never branch on human-readable `title` or `detail`. The full list of codes is in the `ProblemDetails` schema of the API reference.

## Common outcomes

| Status | Meaning | Typical action |
| - | - | - |
| `400` | Invalid schema, field, enum, money, placement minimum, date window, card-number-like text, or transition | Fix the request; do not retry unchanged |
| `401` | Missing, invalid, expired, or revoked key, or an unaccepted network source | Restore valid environment credentials and check the key's IP ranges |
| `403` | Client scope denied | Verify the current grant and any Client restriction on the key |
| `404` | Resource or path missing, or not visible in the authenticated scope | Verify identity and scope; do not probe other identifiers |
| `405` | The route does not support the method (including `HEAD` and `OPTIONS`) | Use a method listed in the `Allow` header |
| `408` / `413` / `415` | Body not received in 10 seconds, over 256 KiB, or wrong `Content-Type` | Fix the request; nothing was changed |
| `409` | Source write, payment, balance, opening-correction, lifecycle, closed-Matter or Client set-up conflict | GET current state and reconcile |
| `412` | Stale `If-Match`, or `If-None-Match: *` on a Matter that already exists | GET current state and decide again; never replay the old body under a fresh tag |
| `422` | A data integrity rule rejected the write | Nothing was applied; check the data and contact support with the request id if it persists |
| `428` | A Matter write arrived without its required precondition | Resend with `If-None-Match: *` to create or `If-Match` to update |
| `429` | Per-key rate limit or capacity limit | Wait for `Retry-After`, then retry with backoff and jitter |
| `503` | Transient server or fenced transaction failure, or writes paused by the platform | Wait for `Retry-After`, then retry the same safe request with backoff and jitter |

Every response from the application includes `X-Request-Id`; the only exception is a `429` answered by the network edge before the request reaches the application, which carries `Retry-After` but no request id. Keep it with your integration telemetry for support correlation. A `429` or `503` always carries `Retry-After` in seconds. While the platform pauses Partner API writes, every write returns `503 partner_writes_paused` and reads keep working; retry the same request later.

## Retry decision guide

CasePath IQ v1 does not use a caller `Idempotency-Key`, `sourceRevision`, `sourceEventId`, or `predecessorSourceRevisionId`.

| Situation | Safe action |
| - | - |
| Lost Matter create response | Retry with `If-None-Match: *`. A `412` means a Matter already exists at that client reference ID, not necessarily yours — GET it and reconcile its ownership and content before continuing |
| Lost Matter update response | Retry identical content with the same `If-Match` tag. A `412` means the tag is no longer current — most often because your own update committed, otherwise because another writer intervened. GET and compare before re-sending |
| Lost Payment observation response | Retry the same external payment ID and identical content |
| Lost lifecycle response | Retry the same operation, `predecessorLifecycleId`, and identical command while the occurrence may still be current |
| `429` or `503` | Exponential backoff with jitter |
| `400`, `401`, `403`, or `404` | Correct configuration, access, identity, or input before retrying |
| `412` or `428` | Decide which operation you intended. To create, resend with `If-None-Match: *`. To update, read the current Matter and resend with its current `etag` as `If-Match` |
| `409` | GET current Matter or observation, reconcile, then decide the next command |

Identical Matter PUT or PATCH content returns `200` with no new `sourceRevisionId` and unchanged `updatedAt` only while that representation remains current — and only when its precondition still holds. A delayed retry that arrives after another write carries a tag that is no longer current, so it is refused `412` without mutation instead of reverting the Matter to older content.

An identical Payment observation retry returns the existing observation. The same external payment ID with different content returns `409 payment_observation_conflict`.

An exact lifecycle retry returns the accepted occurrence only while that occurrence is still the current lifecycle head. A stale or superseded command returns a typed `409`; read the Matter before choosing a new transition.

## Concurrent writes

Serialize writes per Matter and per external payment ID.

If different Matter PUT or PATCH requests race, CasePath IQ accepts at most one. The loser returns `412 precondition_failed` when its precondition was already superseded, or `409 source_write_conflict` when two writes reach the Matter lock together. Either way the server does not silently chain the losing request onto state it did not read.

Balance-changing Payment observations and lifecycle operations also lock the Matter while validating and applying their effects. A failed request does not leave a partial observation, balance, lifecycle, readiness, or audit change.

## Support correlation

When contacting support, include:

* `X-Request-Id`
* Environment
* Route template and HTTP method
* UTC timestamp
* Problem `type`, `status`, and field `code` values
* The `etag` you wrote against, for a `412` you cannot explain

Do not send API keys, raw personal data, request bodies, or personal identifiers embedded in URLs.

## Next

* [Review authentication and Client scope](https://docs.casepathiq.com/authentication.md)
* [Review Matter write semantics](https://docs.casepathiq.com/matters.md#put-or-patch)
* [Review Payment and lifecycle retries](https://docs.casepathiq.com/payments-and-lifecycle.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.