API & webhooks

API errors and rate limits

What each status code means, what the 402 payloads carry, and how the per-key rate limit works.

Every response from the public API is either your data or a status code that tells you what to do next. This is the whole set.

Status codes

CodeMeaningWhat to do
200Success.
400Malformed request body or an invalid reference.Fix the payload. Retrying unchanged will fail again.
401Missing or unrecognised API key.Check the Authorization header. Keys can be revoked.
403Key is valid but not permitted for this call.Check the key is active and the account is enabled.
402Payment required — two distinct causes, see below.Branch on data.error, never on the message text.
429Rate limit exceeded for this key.Wait Retry-After seconds, then retry.
5xxOur side, or the carrier upstream.Retry with backoff. If it persists, send us the reference.

The two 402s

They mean different things and need different handling, so data.error distinguishes them rather than making you scrape a string.

data.errorCausePayload carries
shipment_limit_reachedAll shipment slots for the billing period are used.limit, used, plan, maxedOut, manageUrl, usageUrl, and contactUrl when you are already on the largest standard plan.
payment_overdueA payment failed and the grace period has ended.overdueDays, graceDays, plan, manageUrl, usageUrl.

maxedOut is the field worth branching on: it is the difference between "upgrade" and "you have already upgraded as far as self-serve goes, talk to us". Telling a customer on the top plan to upgrade is how an integration gets abandoned.

A 402 for a slot limit does not affect references you already track — those keep updating. It blocks adding new ones. See how shipment slots are counted.

Rate limits

PropertyValue
ScopePer API key, not per account or per IP.
Default120 requests per minute.
WindowFixed, 60 seconds.
HeadersX-RateLimit-* on every response, not only on a 429.
Over limit429 with Retry-After in seconds.

Because the headers are on every response, you can pace yourself without ever tripping the limit — read the remaining count rather than waiting to be refused. Higher limits can be set per plan; ask if 120/min is genuinely not enough for your integration.

Authentication

Send your key as a bearer token:

Authorization: Bearer <your-api-key>

Keys are stored hashed, so we cannot show you an existing key again — if you lose it, issue a new one and revoke the old. See getting an API key.

Checking usage without tripping a limit

The Developer page shows live usage — used, limit, remaining — for the account, and the same figures are available to your integration. Poll that rather than discovering your position from a 402.

Was this helpful?