Rate limits
Every response — success or error — includes rate-limit headers so you always know where you stand:
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 47
X-RateLimit-Limit-Day: 10000
X-RateLimit-Remaining-Day: 8241
X-RateLimit-Reset: 1730000000
X-RateLimit-Reset is a Unix epoch second — when the tightest bucket refills.
Default tiers
| Tier | Requests/minute | Requests/day | Notes |
|---|---|---|---|
| Free | 30 | 500 | Evaluation. Watermarked images. No SLA. |
| Standard | 60 | 10,000 | Default for paying customers. |
| Enterprise | Custom | Custom | Contact us — we set limits based on expected volume. |
Limits are per client (per client_id), not per user or per IP. If you run a POS network
with 500 store terminals hitting from the same client, budget accordingly — a single client
credential shares one bucket across every consumer of that credential.
Recommended pattern for multi-tenant POS: issue one API client per store, so each store has its own bucket. See Guides → POS integration.
What counts
Every HTTP request against /api/v1/** counts against your minute + day buckets, including:
- Successful requests
4xxerrors (yes, even a401— spamming with a bad token still counts)HEADrequests- Free endpoints (
/health,/pricing,/productscatalog listing)
5xx errors on our side do not count against your budget.
When you hit the limit
Response is HTTP 429 Too Many Requests:
{
"error": "rate_limited",
"message": "Exceeded 60 requests/minute. Retry after 43s.",
"request_id": "req_01H8Y3G7Z8mnpqrsw"
}
Response headers include Retry-After: 43 — wait that many seconds before your next request.
Best practices
1. Watch the Remaining headers. If Remaining-Minute drops below 5, throttle yourself
proactively — don't wait for the 429.
2. Batch when you can. POST /products/bulk-check with 500 barcodes costs one request and
5 credits; 500 individual HEAD /products/{barcode} calls costs 500 requests and 25 credits.
Same information, 100× less rate-limit pressure.
3. Cache freely at the metadata layer. Product metadata changes rarely — days between edits is typical. Caching a product's metadata for hours or even days is fine and dramatically reduces load. Do not cache signed image URLs (they expire in 15 min and are single-use).
4. Respect Retry-After. Aggressive retry loops that ignore Retry-After get flagged as
abuse and can result in your client being disabled without notice.
Auth endpoint sub-limits
POST /auth/token and POST /auth/refresh have their own tighter limits, independent of your
tier:
| Endpoint | Limit |
|---|---|
/auth/token | 10 requests / minute / IP |
/auth/refresh | 30 requests / minute / IP |
If you find yourself refreshing more than 30 times a minute, you're leaking tokens — check that your client wrapper is reusing tokens across requests instead of exchanging on every call. See the Authentication guide.
Enterprise: dedicated buckets
Enterprise customers can request:
- Higher static limits
- Burst allowance (e.g. 200 rpm for the first 30s of each minute)
- Dedicated rate-limit bucket unaffected by other clients
- Per-endpoint limits (e.g. unlimited
/productscatalog, standard limits on/products/{barcode})
Contact api@retaildigitals.com.