# Errors

Every error the API answers has the same shape:

```json
{
  "success": false,
  "error": "Purpose of shipment can't be blank",
  "errors": ["Purpose of shipment can't be blank"]
}
```

- `error` is one sentence, ready to show a person.
- `errors` lists each reason separately, for your code. It is empty when there is a single cause, such as a missing record.

The status code says what kind of error it is.

| Status | Meaning | Example `error` |
|---|---|---|
| `400` | The body isn't valid JSON, or something failed on our side. | `Malformed request body` |
| `401` | The token is missing, expired or invalid. Sign in again. See [Authentication](/authentication). | `You need to sign in or sign up before continuing.` |
| `403` | Your login isn't allowed to do this. | `You are not authorized to perform that action` |
| `404` | The record doesn't exist, or belongs to another company. | `Couldn't find Order with 'id'=0` |
| `422` | We refused the request, and `errors` lists each reason. | `Purpose of shipment can't be blank` |
| `429` | Too many requests. Wait a minute and try again. | `Too many requests, please wait and try again` |

A `400` reading `Unexpected error occurred, please check inputs` means the request reached us but failed on our side. We are told about it automatically. If it keeps happening with the same request, tell us, with the time and the call you made.

## A refusal with several reasons

When a request breaks more than one rule, `errors` holds one entry per rule and `error` joins them into a sentence:

```json
{
  "success": false,
  "error": "Target url can't be blank and Target url is invalid",
  "errors": ["Target url can't be blank", "Target url is invalid"]
}
```

## What to retry

- `429`: wait until the minute is up, then send the same request again.
- `400` with `Unexpected error occurred`: retrying the same request rarely helps. Check the inputs first.
- `401`: sign in again, then retry with the new token.
- `403`, `404` and `422`: don't retry unchanged. The answer will be the same until the request changes.
- [Create a waybill](/reference/create-a-waybill) after a timeout: don't retry blindly. Read the order first, and call again only if it has no waybill.
