429 response immediately — no request is partially processed. Every answer tells you how much of the current minute’s budget is left, so your client can slow down before it reaches a limit. If a 429 still arrives, read the Retry-After header and pause before retrying, rather than hammering the endpoint in a tight loop.
Limits by endpoint
Calls made with an API key are counted per key in fixed one-minute windows: the counter starts again at the beginning of every minute. The key’s own limits below are the only ones such a call meets — there is no per-IP limit on top of them. The keyless endpoints,GET /v1/health and GET /v1/public/prices, have no key to count against, so they are limited per IP address.
GET /v1/key returns every limit of your key in one call, under rate_limits.
Sending 30 requests with invalid or missing API keys from the same IP address within one minute triggers an automatic 5-minute IP-level ban. During the ban every request from that IP returns
429 too_many_failed_auth, whichever key it carries. Fix the key and wait out the ban before retrying.Rate limit headers
Once your key is accepted, every answer carries four headers for the bucket the call spent:X-RateLimit-Remaining reaches 0, hold further calls on that bucket for X-RateLimit-Reset seconds.
429 response format
When you exceed a per-key limit the API returns:bucket names the spent bucket (read, trading or buy_orders) and limit_per_min its ceiling. The Retry-After header value is an integer number of seconds: the time left until the minute’s window restarts, from 1 to 60. retry_after_sec carries the same number. Waiting that long is always enough, because the counter starts again with the window.
The bulk price snapshot uses a distinct error code when rate-limited:
Retry-After is the exact time left in the minute as well, and so is the one from the P2P write limit (rate_limit_exceeded) and the Instant Sell quote limit (rate_limited). Those bodies carry only code and detail.
A fourth concurrent listing stream on one key answers 429 too_many_streams with Retry-After: 90. A connection that dropped without closing keeps its slot for up to 90 seconds, so a reconnect right after a network blip may have to wait that long:
GET /v1/public/prices is limited by IP address rather than by key, and its 429 body has no code field — branch on the status and Retry-After:
Handling 429s in your client
ReadRetry-After and sleep for at least that many seconds before retrying. Better still, read X-RateLimit-Remaining on every answer and slow down before it runs out. The example below shows a simple loop in bash that does both:
Polling versus the stream
The listing stream publishes anew event about 0.3 seconds after a listing enters the catalogue. Measured on October 26, 2026: median 0.34 s, maximum under 0.5 s. Polling GET /v1/listings faster cannot show you a listing sooner than the stream delivers it. Every key receives the same stream at the same moment — there is no priority tier.
- For new listings and
goneevents, keep one stream open. Reconnect withLast-Event-ID, or start from theX-Stream-Positionof a listings snapshot, and you miss nothing. - For filtered reads — one item, a float range, a price band — use
GET /v1/listings.