Skip to content

Rate limits

Rate limits are applied per app, per environment. Your app’s exact limits are shown in the console under Apps → Usage → Rate limits; the defaults are generous enough that a well-behaved integration never sees a 429:

SurfaceDefault limit
API requests, per app300 requests / minute
Full menu push, per store12 / hour
Availability batch, per store60 / minute
OAuth token and refresh calls, per app60 / minute

Limits are enforced with a sliding window. Bursts within the window are fine; sustained traffic above it is not.

When a limit is exceeded, the request is rejected with the standard error envelope and a Retry-After header giving the number of seconds to wait:

HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/json
{ "error": { "code": "rate.limited", "message": "Rate limit exceeded. Retry after 23 seconds." } }

Honour Retry-After exactly — retrying earlier extends the window and delays your own recovery.

  • Retry with exponential backoff and jitter on 429 and 5xx. Start at the Retry-After value (or 1 second), double per attempt, add random jitter, cap around 60 seconds, and cap total attempts.
  • Cache tokens. One access token per merchant, reused for its full hour, refreshed 60 seconds early — see Authentication. Minting a token per request is the most common way integrations rate-limit themselves.
  • Push menus on change, not on a timer. A full menu push is the heaviest call on the platform. Push when the catalogue changes and when Quiqqy asks via action_required — not every few minutes. Use the batch and availability endpoints for small deltas.
  • Batch availability changes. One call with fifty items beats fifty calls with one item.
  • Never poll for orders. Orders arrive over webhooks; polling adds load and latency and gains nothing.