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

# Errors

> HTTP status codes and error response shapes

Clausum uses conventional HTTP status codes. `2xx` success, `4xx` client error, `5xx` server or availability error.

## Status codes

| Status | Meaning                                                          |
| ------ | ---------------------------------------------------------------- |
| `200`  | Success                                                          |
| `201`  | Resource created                                                 |
| `400`  | Validation error                                                 |
| `401`  | Unauthorized — missing, invalid, disabled, or revoked credential |
| `403`  | Forbidden — wrong key type or missing permission                 |
| `404`  | Not found                                                        |
| `409`  | Conflict — duplicate resource                                    |
| `429`  | Rate limit exceeded                                              |
| `500`  | Internal server error                                            |
| `503`  | Service unavailable — assess maintenance                         |
| `504`  | Gateway timeout — assess timeout                                 |

## Error shape

Partner and management endpoints return a structured object:

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "currency must be a 3-letter ISO code",
    "details": {}
  }
}
```

<Tip>
  Branch on `error.code`. On **429**, honor `X-RateLimit-Reset` and retry with backoff.
</Tip>

## Partner assess codes

| Code                     | HTTP  | Action                                                                                           |
| ------------------------ | ----- | ------------------------------------------------------------------------------------------------ |
| `ASSESS_MAINTENANCE`     | `503` | Fail-open to manual review or queue payment — see [Assess resilience](/guides/assess-resilience) |
| `ASSESS_TIMEOUT`         | `504` | Retry with same `order_id` / `Idempotency-Key` (exponential backoff)                             |
| `VALIDATION_ERROR`       | `400` | Fix payload — check `GET /api/v1/assess` field catalog                                           |
| `SECRET_KEY_REQUIRED`    | `401` | Use `clm_sk_*` (e.g. payout requires secret key)                                                 |
| `PUBLIC_KEY_NOT_ALLOWED` | `403` | Endpoint requires secret key                                                                     |
| `RATE_LIMIT_EXCEEDED`    | `429` | Back off and retry                                                                               |

## Common management codes

| Code           | Typical cause                  |
| -------------- | ------------------------------ |
| `UNAUTHORIZED` | No or bad JWT / key            |
| `FORBIDDEN`    | Role lacks permission          |
| `INVALID_TYPE` | Unsupported `list_type`        |
| `DUPLICATE`    | Blocklist entry already exists |
| `NOT_FOUND`    | Resource missing               |

## Handling errors

```ts theme={null}
const res = await fetch(url, options)

if (!res.ok) {
  const body = await res.json().catch(() => ({}))
  const err = body.error
  const code = typeof err === "object" ? err?.code : undefined
  const message = typeof err === "string" ? err : err?.message

  if (res.status === 503 && code === "ASSESS_MAINTENANCE") {
    return yourFailOpenPolicy()
  }
  if (res.status === 504 && code === "ASSESS_TIMEOUT") {
    return retryWithSameIdempotencyKey()
  }
  if (res.status === 429) return retryWithBackoff()

  throw new ClausumError(code, message)
}
```

<Note>
  Retry `5xx`, `503`, `504`, and `429`. For other `4xx`, fix the request before retrying.
</Note>
