Errors
Every error the API answers has the same shape:
{
"success": false,
"error": "Purpose of shipment can't be blank",
"errors": ["Purpose of shipment can't be blank"]
}
erroris one sentence, ready to show a person.errorslists 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. | 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:
{
"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.400withUnexpected error occurred: retrying the same request rarely helps. Check the inputs first.401: sign in again, then retry with the new token.403,404and422: don't retry unchanged. The answer will be the same until the request changes.- Create a waybill after a timeout: don't retry blindly. Read the order first, and call again only if it has no waybill.