# Errors

Every error has a status code and a JSON body. Read the status first: it tells you what to do. The body comes in one of four shapes. The `vt()` helpers in the [Quickstart](https://vocatech.com/developers/guide/quickstart) read all four.

### From an endpoint

Most errors. The message says what to fix.

**Endpoint error400 Bad RequestCopy**

```json
{
  "error": {
    "code": 400,
    "type": "BAD_REQUEST",
    "message": "Ask for at most 366 days at a time (this request covers 400). For more history, walk it a year at a time."
  }
}
```

### From the router

An unknown path, a method the path does not take, some not-found answers, and faults we did not expect.

**Router error404 Not FoundCopy**

```json
{
  "statusCode": 404,
  "error": {
    "type": "RESOURCE_NOT_FOUND",
    "description": "Webhook not found."
  }
}
```

### From the key check

`401`, `403` for a scope or an IP allow-list, and `503` when a key cannot be checked. Examples are in [Authentication and keys](https://vocatech.com/developers/guide/keys).

**Key check error503 Service UnavailableCopy**

```json
{
  "error": "Service Unavailable",
  "message": "The API could not check this key just now. Retry in a few seconds."
}
```

### From a rate limit

`429`, with `retry_after` in the body and a `Retry-After` header. See [Rate limits](https://vocatech.com/developers/guide/rate-limits).

## Status codes

| Status | When | What to do |
| --- | --- | --- |
| `400` | A value is wrong or missing: a date, a number, a file, a window over 366 days, an end date before the start. | Fix the request. The message names the field. |
| `401` | No key, a wrong key, or a key that was turned off or regenerated. | Check the key. Retrying will not help. |
| `403` | The key's scope or IP allow-list refuses the request, or the action is not allowed: `from` is not your number, the recipient opted out, faxing is off. | Read the message. Do not retry as is. |
| `404` | Not found, not yours, or an unknown path. | Check the id and the path. |
| `405` | The path does not take that method. | Use the method in the reference. |
| `409` | A queued message is already sending or done, or a support ticket is busy (with `Retry-After: 60`). | Treat it as done, or wait and send again. |
| `410` | A message attachment is no longer available. | There is nothing to fetch. |
| `413` | A fax document over 20 MB. | Send a smaller file. |
| `422` | Validation: a webhook URL that is not public `https`, a missing event or message, WhatsApp sending, an AI agent call that cannot be placed. | Fix the request. The message says what. |
| `429` | A rate limit, a day allowance, or the monthly fax page limit. | Wait `Retry-After` seconds. |
| `500` | Something failed on our side, or the fax service refused a fax. | Retry later with backoff. If it repeats, tell us the time and the path. |
| `502` | A service behind the API answered and refused, or did not answer: the messaging service did not send, the support desk could not take it, or the agent platform did not answer and the call may have been placed. | Read the message. For an AI agent call, check for the placed-call tag before you retry, or retry with the same `Idempotency-Key`. Otherwise retry in a minute if it says so. |
| `503` | The key could not be checked (`Retry-After: 5`), a text could not reach the messaging service and was not sent, a desk is not available, or storage had trouble on our side. | Safe to retry after a pause. |
| `504` | A text send was not confirmed. It may have gone out. | Check `GET /v1/messages` before retrying. |
