# Errors

Application-level errors are returned as **RFC 7807 Problem Details** with
`Content-Type: application/problem+json`:

```json
{
  "type": "about:blank",
  "title": "Case ID not found",
  "status": 404,
  "detail": "No case exists for the given ID.",
  "instance": "/api/v1/upload-service/job-status/7c2f1e4a-…"
}
```

| Field | Description |
| --- | --- |
| `type` | A URI identifying the problem type, or `about:blank`. |
| `title` | Short, human-readable summary. |
| `status` | The HTTP status code, repeated in the body. |
| `detail` | Human-readable explanation for this occurrence. |
| `instance` | The request path that produced the error. |

Some problems add extra fields. A `413` carries the configured limits, for example:

```json
{
  "type": "https://accessful.de/problems/upload/payload-too-large",
  "title": "Payload Too Large",
  "status": 413,
  "detail": "Maximum upload size exceeded.",
  "maxFileSize": "200MB",
  "maxRequestSize": "815MB",
  "maxFileCount": "1000",
  "limitExceeded": "per-file"
}
```

## Common status codes

| Status | When |
| --- | --- |
| `400 Bad Request` | Malformed input — invalid webhook URL, non-PDF file, or a malformed request body. |
| `401 Unauthorized` | Missing, malformed, or revoked API key. |
| `403 Forbidden` | Valid key without permission for the action. |
| `404 Not Found` | Unknown or malformed `caseId`, or no result available yet. |
| `409 Conflict` | The request conflicts with current state. |
| `413 Payload Too Large` | File or request exceeds the [size limits](https://docs.accessful.de/limits/). |
| `500 Internal Server Error` | Unexpected server error — safe to retry later. |

:::note
**401** is produced at the gateway (a missing or invalid key), before the request reaches the
application — it does **not** carry a Problem Details body, so rely on the status code. **403** and
every other application error use the Problem Details body above.
:::

:::note[Quota is not a `429`]
An exhausted contract quota does **not** return an HTTP error. Uploads accept with `200`, then
the job ends in the `quota_exceeded` [status](https://docs.accessful.de/reference/job-status/). See [Limits](https://docs.accessful.de/limits/#rate-limits--concurrency).
:::