# Errors and status codes

> Every status both surfaces return, and what to do about each one.

Read this one first if something is failing. `401` and `403` are the two that catch people out, and they mean different things.

## The error body

Every refusal from the read surface carries the same envelope. The `message` is meant to be read by a person, not matched on.

```json
{ "error": { "code": "forbidden", "message": "missing scope: read" } }
```

## Every status

| | |
|---|---|
| 202 | Accepted and stored. Parsing and scoring happen after this, so this is not a promise that the payload was readable |
| 400 | The connector's platform does not accept webhooks |
| 401 | No usable credential. The key is missing, revoked, or the webhook signature did not match |
| 403 | A real credential that may not do this. Wrong scope, or a client-limited key naming another client |
| 404 | Unknown webhook token, a disabled connector, or a client id this workspace does not have |
| 413 | Over the ceiling. 8 MiB for an event batch, 200 MiB for an import file |
| 422 | A field is missing or malformed |

## The two that catch people out

| | |
|---|---|
| 401 on /ingest/v1/events | The key does not carry the ingest scope. A read key cannot send |
| 403 on /v1/threads | The key does not carry the read scope. An ingest key cannot read |
| 403 on any other /v1 route | That route is not part of the published read surface. Only conversations, metrics, findings and scores are |

> **Note:** A `202` is not a success signal for the payload. We answer before anything parses, so a body we cannot read still got one. The connector screen counts what failed after the answer went back.

---

Source: https://evidova.com/docs/api/errors
