Skip to content
Developers & API

Errors, rate limits and best practices

The error format, status and error codes, the rate guidance and a checklist for a safe integration.

3 min readUpdated Developers

On this page

Every error answers with the same JSON shape. Check success on every response and branch on error.code.

Error format#

JSON
{  "success": false,  "message": "Validation failed",  "error": {    "code": "VALIDATION_ERROR",    "message": "Latitude must be between -90 and 90"  }}

Some calls of the Trips API also return an optional error.details object, for example details.batch_id.

HTTP status codes#

Status

Meaning

200

Success

201

Created

400

Bad request: invalid input or validation error

401

Unauthorised: missing or invalid token

403

Forbidden: insufficient permissions

404

Not found

413

Payload too large

415

Unsupported media type: send Content-Type: application/json

422

Unprocessable entity: validation failed

500

Internal server error

502

Bad gateway: an external service failed

503

Service unavailable

Error codes#

Code

Meaning

VALIDATION_ERROR

Request validation failed

UNAUTHORIZED

Authentication required or token invalid

FORBIDDEN

Insufficient permissions

NOT_FOUND

Resource not found

DISPATCH_IN_PROGRESS, PENDING_BATCH_EXISTS, NO_RIDERS_ONLINE, RIDER_OFFLINE, NO_QUEUED_ORDERS

Trips API only. See Plan and approve trips for your own riders

EMAIL_ROLE_MISMATCH, ALREADY_MAPPED, RIDER_HAS_ACTIVE_TRIP

Riders API (409). See Add and manage your riders from your system

ROUTE_NOT_FOUND

POST /api/estimate and POST /api/orders (422): there is no road route to the drop point. Correct the coordinates; retrying will not help

EXTERNAL_API_ERROR

An external service (for example distance calculation) failed. Retrying later may help

BAD_REQUEST, UNSUPPORTED_MEDIA_TYPE, PAYLOAD_TOO_LARGE

The body could not be read: empty or broken JSON (400), not application/json (415), too large (413)

INTERNAL_ERROR

Server-side error

Rate limits#

There are no explicit rate limits at the moment. The recommendation is a maximum of 100 requests per minute per API user. Excessive requests may be throttled.

Best practices#

Tokens#

  • Store tokens in environment variables or secure storage.

  • Tokens expire after 90 days. Build refresh logic: on a 401, log in again.

  • Never expose tokens in client-side code or logs.

Errors and retries#

  • Always check the success field.

  • Retry 5xx responses. A 422 ROUTE_NOT_FOUND and an unreadable body (400 BAD_REQUEST, 415, 413) cannot succeed on retry, so fix the request instead.

  • Send an Idempotency-Key on POST /api/trips so a retry after a timeout is safe.

  • Treat webhook deliveries as idempotent: the same update can arrive more than once.

Requests#

  • Use the estimate call before creating orders if you show distance to customers.

  • Cache estimates when appropriate: coordinates do not change.

  • Batch operations when possible, for example one POST /api/trips for all queued orders.

  • Validate coordinates before sending: latitude -90 to 90, longitude -180 to 180.

Security#

  • Use HTTPS in production.

  • Never share API keys. Rotate them periodically (see Get your API credentials).

  • Monitor API usage for anything suspicious.

What should I do on a 401?

Log in again with POST /auth/api/login and repeat the call with the new token.

Which errors are worth retrying?

5xx responses and EXTERNAL_API_ERROR. Do not retry ROUTE_NOT_FOUND or validation errors.

Related guideQuickstart: your first delivery from code in 10 minutesLog in, create an order for your own riders, plan the trip and receive the order.updated webhook. One request and one response per step.

Was this page helpful?

Type to search all guides.