<!-- https://missblue.dev/docs/errors -->

Reference

# Errors

One shape, always. The `code` is stable and meant to be switched on; the `message` is for a human reading a log and may change.

```json
{
  "error": {
    "code": "bad_request",
    "message": "recipient must not be empty"
  }
}
```

| Status | What it means |
| --- | --- |
| 400 | The request is wrong in a way you can fix. The message says how. invalid\_recipient: the recipient is written as a phone number nobody can have — a +1 number without ten digits, an area code or exchange starting with 0 or 1, an N11 service code, or a fictional 555-0100 to 555-0199. Nothing was written or sent; fix the number. |
| 401 | No key, an unknown key, or a revoked one. |
| 404 | No such thing — or one your key may not see. We do not distinguish, because doing so would confirm it exists. |
| 409 | duplicate\_send: the same text went to the same person moments ago — pass allow\_duplicate if you meant it. agent\_offline: the number is temporarily unavailable for a live action (a reaction, an edit, an unsend, a typing indicator); nothing was done, so retry shortly. conflict: a message you asked to cancel is already on its way. |
| 413 | The upload is over the size limit. |
| 422 | The JSON parsed but a required field was missing or the wrong type. recipient\_undeliverable: the number cannot get texts — its carrier said it is a landline or not in service, or the check before a first text found a landline or no such number — so your text-message numbers do not text it again unless it writes in. reason says which: landline, not\_in\_service, invalid or other. Fix the number on the contact rather than retrying. |
| 429 | Over 600 requests a minute. Retry-After says how long, in seconds. |
| 503 | agent\_busy: the number is busy right now. Nothing was done; retry in a moment. |
| 504 | command\_timeout or command\_unconfirmed: the number did not confirm in time. It may still have happened — check before repeating it. |

## Sending while a number is unavailable

Not an error. A send to a number that is temporarily unavailable is accepted and queued: `201`, status `pending`, `queued: true`, and a `notice` whose code is `number_unavailable`. It goes out automatically as soon as the number is back, so do not send it again. Until it goes, you can call it off with `POST /v1/messages/{id}/cancel`.

```json
{
  "id": "0b5ed7e8-f7a1-4f6e-9c2a-2a1f0d9e8b77",
  "status": "pending",
  "queued": true,
  "notice": {
    "code": "number_unavailable",
    "message": "This number is temporarily unavailable. Your message is queued and will be sent automatically as soon as it's back."
  }
}
```

A notice of `send_retrying` means the send was turned down for now and will be tried again automatically. Each number says whether it can send in its `availability`, so you can tell before you send.

## What to retry

`429`, `503`, and `409 agent_offline`, after a delay. Never a `504` blindly: the number may already have done it. A `4xx` otherwise will fail the same way forever — the request is the problem, and repeating it only uses your rate limit.

Any other `5xx` is ours and safe to retry. If you can make one happen with a request that is not obviously nonsense, we would like to know: that is a bug, not a limit. We fuzz the API for exactly this, and the last one it found was a null byte in a text field, which Postgres cannot store — it came back as `500` when it should always have been `400`.

## Not here yet

Listed so you find out now rather than halfway through building.

The remaining Messages controls

Expressive text styles and effects, editing a sent message, and leaving a group are not supported customer API operations yet. They will appear here only after their readback and failure states are reliable.

Provisioning numbers

Numbers are provisioned by a person, usually within 48–72 hours of purchase. There is no self-serve API for it, because there is no self-serve process behind it to expose.

[Next Back to the introduction Authentication, limits, and the full list.](https://missblue.dev/docs)
