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.