Errors & rate limits

Every error is JSON with a stable error shape and the right HTTP status. No surprises, no HTML error pages.

Error shape

401 · response
{
  "error": {
    "type": "unauthorized",
    "message": "Invalid or revoked API key."
  }
}

Status codes

200OK - request succeeded. "Nothing found" is still a 200 (e.g. an unknown tracking number returns an empty updates list).
400Bad request - a parameter is missing or malformed.
401Unauthorized - missing, malformed, invalid or revoked API key.
403Forbidden - this key may not call this endpoint, or the request IP is not on the project's whitelist.
413 / 415POST body too large / not application/json.
422Unsupported link - no platform and product id could be detected.
429Too many requests - the per-minute rate limit or a daily quota was hit.
5xxServer error - retry with backoff.

Quotas

Limits apply per workspace and are shared by all its projects: Free allows 2,000 requests a day and 30 a minute, Pro 50,000 a day and 240 a minute. A project can also have its own daily cap. Only successful calls count - errors and rate-limited responses don't. Daily quotas reset at midnight UTC. GET /v1/usage returns today's numbers at any time.

Rate-limit headers

Responses on plans with a per-minute limit include:

  • X-RateLimit-Limit - requests allowed per minute.
  • X-RateLimit-Remaining - requests left in the current minute.
  • X-RateLimit-Reset - unix time (seconds) when the minute window resets.

A 429 carries Retry-After (seconds) and an error object with scope, limit, used and reset_at. Wait that long before retrying.