Contents

Rate limits

How many requests each API accepts, how limits are counted and how to back off.

How limits work

Limits protect every store on the platform from a single runaway client. They are counted in fixed one-minute windows and, depending on the endpoint, per client IP, per key or per person. Some endpoints have two limits at once — for example per IP and per publishable key — and a request must stay within both.

Public endpoints that shoppers' browsers call count per shopper IP, so a busy storefront does not run out: each visitor has their own allowance.

Limits by endpoint

This table is built from the API specifications. The endpoint's reference page explains any extra rule (for example the returns lookup locks an order number after 5 failed attempts in 15 minutes).

APIEndpointLimitCounted
OAuth & OpenID Connectpost/oauth/register10 / minuteper IP
OAuth & OpenID Connectpost/oauth/token60 / minuteper IP
OAuth & OpenID Connectget/api/public/organizations/{slug}/branding120 / minuteper IP
AI Toolsget/api/v1/ai-tools120 / minuteper user
AI Toolspost/api/v1/ai-tools/{name}120 / minuteper user
Collectorpost/events120 / minuteper IP
Collectorpost/consent120 / minuteper IP
Collectorget/config120 / minuteper IP
Collectorget/size/{product}120 / minuteper IP
Delivery Promiseget/public/promise120 / minuteper IP
Returns Portalget/60 / minuteper IP
Returns Portalpost/lookup10 / minuteper IP
Returns Portalget/order60 / minuteper IP
Returns Portalpost/returns10 / minuteper IP
Returns Portalget/r/{token}60 / minuteper IP
Returns Portalget/r/{token}/label60 / minuteper IP
Shipment Trackingget/public/tracking/{token}60 / minuteper IP
Shipment Trackingpost/webhooks/tracking/{connection}600 / minuteper IP
WMS T-Dataget/V1/Orders/New600 / minuteper key
WMS T-Datapost/V1/Orders/Acknowledge600 / minuteper key
WMS T-Datapost/V1/Orders/Processed600 / minuteper key
WMS T-Datapost/V1/Orders/Shipped600 / minuteper key
WMS T-Datapost/V1/Orders/Canceled600 / minuteper key
WMS T-Datapost/V1/Orders/Cancel600 / minuteper key
WMS T-Datapost/V1/Stock/Update600 / minuteper key
WMS T-Dataput/V1/Stock/Update600 / minuteper key
WMS T-Dataget/V1/Returns/New600 / minuteper key
WMS T-Datapost/V1/Returns/Acknowledge600 / minuteper key
WMS T-Datapost/V1/Return/Update600 / minuteper key
WMS T-Datapost/V1/Returns/Update600 / minuteper key
WMS T-Datapost/V1/Returns/Canceled600 / minuteper key
WMS T-Dataget/V1/Labels/Get600 / minuteper key
WMS T-Datapost/V1/Labels/Add600 / minuteper key
WMS T-Dataget/V1/Documents/Get600 / minuteper key
WMS T-Datapost/V1/Catalogue600 / minuteper key
WMS FFWget/api/admin/ws/ws_orders600 / minuteper key
WMS FFWpost/api/aggiorna-giacenze-impegni600 / minuteper key
WMS FFWget/api/admin/resi/list600 / minuteper key
WMS FFWpost/api/admin/resi/notify-reso600 / minuteper key
WMS FFWpost/api/admin/spedizioni/notify-spedizione600 / minuteper key
WMS FFWget/api/admin/documenti/get-order-docs600 / minuteper key
WMS FFWget/api/documenti/admin/get-order-docs600 / minuteper key
WMS FFWpost/api/admin/spedizioni/get-etichette-corriere600 / minuteper key
WMS FFWpost/api/admin/spedizioni/del-etichette-corriere600 / minuteper key
WMS FFWpost/api/admin/spedizioni/ws-close-bordero600 / minuteper key
Content Deliveryget/120 / minuteper IP
Content Deliveryget/page120 / minuteper IP
Content Deliveryget/collections/{collection}/entries120 / minuteper IP
Content Deliveryget/collections/{collection}/entries/{entry}120 / minuteper IP
Content Deliveryget/menus120 / minuteper IP
Content Deliveryget/redirects120 / minuteper IP
Content Deliveryget/sitemap120 / minuteper IP
Content Deliveryget/media/{mediaId}120 / minuteper IP

When you hit a limit

Over the limit, Nucleo answers 429 Too Many Requests. Most endpoints add:

HeaderMeaning
Retry-AfterSeconds to wait before trying again
X-RateLimit-LimitRequests allowed in the window
X-RateLimit-RemainingRequests left in the current window

Where the header is missing, the body carries the wait in retry_after. Wait at least that long, then retry with exponential backoff and a little jitter:

async function withRetry(doRequest, attempts = 5) {
  for (let i = 0; i < attempts; i++) {
    const res = await doRequest();
    if (res.status !== 429 && res.status < 500) return res;
    const header = Number(res.headers.get("Retry-After"));
    const body = res.status === 429 ? await res.clone().json().catch(() => ({})) : {};
    const wait = (header || body.retry_after || 2 ** i) * 1000 + Math.random() * 250;
    await new Promise((r) => setTimeout(r, wait));
  }
  throw new Error("Nucleo API: too many retries");
}

Stay well below the limits

  • Batch. The Collector accepts up to 50 events per request; send them together.
  • Cache. The delivery promise is already cached by Nucleo for the time the merchant chose; cache CMS content on your side and refresh it on the revalidate webhook.
  • Poll calmly. Warehouse interfaces are designed for polling every few minutes, not every second.
  • Do not retry 4xx errors other than 429: the same request will fail the same way.