Skip to main content

Error envelope

Every error response uses the same JSON shape:
code is a stable machine-readable identifier; message is human-readable and may change. Always switch on code, not message.

Status codes

On the IP endpoints, a 400 bad_request carries a more specific code in the envelope — one of invalid_ip_reserved (RFC-reserved / non-global address), invalid_ip_integer_form (bare integer not accepted), or invalid_ip_format (unparseable). Switch on these subcodes when you need to distinguish why an IP was rejected.

Rate-limit headers

Every response carries the current rate-limit state:
A 429 response adds two headers telling you when to retry:
X-RateLimit-Limit is your request ceiling, expressed as requests per 60-second window (not per second). X-RateLimit-Remaining is how many requests remain in the current window. X-RateLimit-Window is the window length in seconds. On a 429, Retry-After is the recommended wait in seconds and X-RateLimit-Reset is the Unix timestamp when the next slot frees (≈ now + Retry-After). Because this is a sliding-window limiter, the exact reset instant is only defined at denial time, so X-RateLimit-Reset appears on 429 responses only — prefer Retry-After for backoff.

Retry strategy

For transient errors (429, 500, 503):
Don’t retry 4xx errors other than 429. They indicate a problem with your request, and retrying just wastes quota.

Circuit breaking

For high-volume integrations, wrap calls in a circuit breaker so a brief outage doesn’t cascade into your application:
We aim for 99.5 % (Pro) / 99.9 % (Business) / 99.95 % (Enterprise) availability, but caller-side circuit breakers are still recommended.