Skip to main content
Every API key is rate-limited using a sliding window. Limits are flat: the same for every organization and every key. There are no API plan tiers. A separate, lower layer also throttles by IP address, before any API key is checked at all - see Pre-authentication IP throttle below. That layer, not this one, is what catches unauthenticated and credential-guessing traffic.

Response headers

Every response that reaches the rate limiter includes rate-limit headers, success or error. A request reaches it only after the key, the plan and account state, and the scope have passed. The headers are therefore absent on 401 and 403 responses and on pre-authentication 429s (see Pre-authentication IP throttle). Pre-authentication 429s carry only Retry-After. POST /v1/notifications also advertises its daily budget with X-RateLimit-Daily-Limit, X-RateLimit-Daily-Remaining and X-RateLimit-Daily-Reset.

How the sliding window works

Each bucket above tracks requests in a rolling window, not a fixed per-minute clock that resets on the dot. Every request you send is timestamped; a request counts against your limit until it “ages out” of the trailing window, and X-RateLimit-Remaining reflects exactly how much budget is left in that window at the moment you asked. When you run out, the API returns 429 with a Retry-After telling you precisely how long until enough old requests age out to free up capacity - that’s the number to sleep for, not a guess. Retry-After gets your next request through, not your next burst. It counts down to the moment the oldest request in your window ages out, which is when a single retry will be accepted. It is not the moment your whole budget returns. The rest comes back gradually, one slot at a time, as each earlier request ages out in turn. So after a 429, size your next burst from X-RateLimit-Remaining on the response you just received, rather than assuming a fresh window. A client that sleeps Retry-After and then fires the full limit will be throttled again immediately. Measured on the default bucket, after a burst that exhausted it: How much budget is back at Retry-After depends on how your earlier requests were spaced, so treat the middle row as an illustration, not a number to hard-code. The header is the only reliable answer.

Default limits

Limits are flat: the same fixed budget applies to every organization. Every bucket below is keyed per API key except the customer lookup row, which is keyed per organization instead: A customer lookup counts against two buckets: the default bucket (60 requests per minute per key) and the stricter lookup bucket (5 requests per second per organization). Whichever runs out first returns the 429. On a lookup that succeeds, the X-RateLimit-* headers describe the lookup bucket. Because the lookup bucket is org-scoped rather than key-scoped, every API key belonging to the same organization shares this one budget; minting a second key does not multiply it (unlike every other row above, where a second key gets its own independent budget).
Contact support@vexioncards.one if you need higher limits.

Pre-authentication IP throttle

Everything above is keyed on api_key_id and only runs once a request has been authenticated. A separate, independent layer runs on every /v1 request before the API key is even looked up, keyed on the caller’s IP address instead. It exists to protect the authentication check itself, since an unauthenticated or key-guessing request is cheap to send but not cheap to reject. Only responses that come back 401 (missing, invalid, or revoked key) count toward the failed-authentication ceiling. A 403 from a valid key that simply lacks a required scope does not count - that is a configuration problem, not a guessing attempt. Both ceilings send Retry-After (seconds), same as every other 429 on this page. A caller can be rejected here without an API key ever having been evaluated, so a 429 with code: too_many_failed_attempts or rate_limited at unusually high volume does not necessarily mean any of your keys are over budget - check which ceiling the error names.
These ceilings are enforced across all servers, not per server. The counters are shared, so a restart or redeploy does not reset them.

What triggers 429

You get a 429 Too Many Requests response in one of two cases:
  • The number of requests we have seen from your key (or, for the customer lookup filter, your organization) in the trailing window exceeds the relevant X-RateLimit-Limit above.
  • Your IP address has exceeded one of the two pre-authentication ceilings described in Pre-authentication IP throttle - this can happen even before your API key is checked.
Both paths return the same 429 status and a Retry-After header, so the response body’s code is what tells you which ceiling you hit - see the table in Pre-authentication IP throttle and the Errors reference for the full code list.

Handling 429 correctly

1

Read the response headers

Check Retry-After and X-RateLimit-Remaining on the 429 - they tell you exactly how long to wait and confirm which budget you ran out of.
2

Wait the exact Retry-After duration, then re-read your budget

Sleep for that many seconds before your next attempt. Don’t apply your own exponential backoff on top of it - Retry-After is when your next single request will be accepted. It is not when your full budget returns, so read X-RateLimit-Remaining on that retry before sending anything more.
3

Retry the same request

Resend with the same idempotency key if the endpoint supports one, so a delayed retry can’t create a duplicate.
4

Escalate if it keeps happening

Repeated 429s at low volume usually mean too many parallel workers sharing one key. If you’ve ruled that out and still need more headroom, contact support@vexioncards.one.
The snippets below implement steps 1-3:
Do not implement your own exponential backoff. Respect the Retry-After header: it reflects the exact time our system needs before it will accept another request.

MCP server

The MCP server follows the same plan and limits as the REST API. When you send too much, the assistant receives “Too many requests. Slow down.” with a wait time, and should pause. The MCP server adds its own limits on top:

Bulk operations

For large data imports or one-time syncs, prefer:
  • Idempotency keys, which make retries free
  • Off-peak hours (early morning UTC)
  • Contact us for a temporary rate-limit increase

Best practices

  • Cache GET responses on your side. Most resources change less than once a day.
  • Poll intelligently. For “has anything changed?” checks, use webhooks. See Webhooks.