> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryoto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API errors and rate limits

> How OTO API failures arrive, how to retry safely, how to handle token expiry, what the rate limits are, and what every status and error code means.

Integrations are not judged on the happy path. They are judged on what they do when a carrier is down, a token has expired, or an address will not geocode.

## How failures arrive

There are three different shapes of failure, and they need three different responses.

| Shape | Looks like | What to do |
| - | - | - |
| **Your request was wrong** | A 4xx with a message naming the field. | Fix and resend. Retrying unchanged will fail identically. |
| **Your token expired** | A 401. | Get a new access token and retry once. Build this in from the start — it will happen every hour. |
| **Something downstream failed** | A 5xx, a timeout, or a success response carrying a carrier error. | Retry with backoff. The request may have partly succeeded, so make it safe to repeat. |

> [!WARNING]
>
> **The third shape is the one that bites**
>
> A carrier rejecting a booking is not an OTO error, so it does not always arrive as an HTTP failure. The shipment simply does not exist, and the order sits still.
>
> This is exactly what the `shipmentError` [webhook](https://docs.tryoto.com/developers/webhook-events.md) is for: it carries an `errorCode`, OTO’s own `errorMessage`, and the carrier’s raw words in `deliveryCompanyResponse` — usually something small and fixable, like a missing city or postcode. Without it, nobody learns until a customer asks.

## Retrying safely

* **Never retry a create blindly.** `createOrder` and `createShipment` change state. If a call times out, check whether the object exists before sending it again — `orderDetails` is cheaper than a duplicate shipment.
* **Back off exponentially.** A tight retry loop against a struggling service makes it worse and gets you nothing faster.
* **Cap the attempts and then escalate.** An order that has failed five times needs a person, not a sixth attempt.
* **Keep the failures.** A dead-letter table of requests that never succeeded is how you find the pattern — one carrier, one city, one product without a weight.

## Token expiry is not an error condition

Access tokens last an hour, so a long-running integration will meet a 401 as a matter of routine. Treat it as a signal, not a fault: refresh the token and replay the request once. Alert only if the refresh itself fails, because that means the credential is wrong rather than old.

## Rate limits

Polling is what pushes an integration into trouble — usually a loop asking for order statuses that have not changed. A [webhook](https://docs.tryoto.com/developers/webhook-events.md) removes the loop entirely, which is the real fix. Where you must poll, poll narrowly: filter by date and status rather than fetching everything and comparing.

## Status and error-code reference

The full list of order statuses and of platform error codes is maintained on [apis.tryoto.com](https://apis.tryoto.com), under **List Of Statuses** and **Error Codes**. Both are generated alongside the endpoints, so they stay in step with what the API actually returns.

> [!TIP]
>
> **Map statuses once, in one place**
>
> Your system and OTO will not use the same words, and the translation belongs in a single mapping rather than scattered through the code as string comparisons.
>
> When a new status appears, one table changes. The alternative is finding the seven places that check for `delivered`.

## Related

* [Webhook events](https://docs.tryoto.com/developers/webhook-events.md) — where shipment errors surface.
* [Authentication](https://docs.tryoto.com/developers/authentication.md) — token lifetime and refresh.
* [Carrier integration](https://docs.tryoto.com/modules/shipping-management/carrier-integration.md) — why a carrier refuses a booking.


## Related topics

- [OTO API overview](https://docs.tryoto.com/developers/overview.md)
- [Checkout API for live shipping rates](https://docs.tryoto.com/modules/sales-channels/checkout-api.md)
- [Platform architecture](https://docs.tryoto.com/get-started/architecture.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.