Rate limits and feature gates
jtWMS limits how many requests each tenant can make, in two ways: a short-term burst limit and a daily quota. Both count every authenticated request made as your tenant, whether it uses a user token or an API key, and all your users and keys share them.
Burst limit
Section titled “Burst limit”Each tenant can make up to 100 requests in a burst, refilling at 20 requests per second. A client that sends steadily at 20 requests per second or less never reaches the limit; a client that is idle for 5 seconds can then send 100 requests at once. The burst limit is the same on every plan.
A request over the burst limit gets 429 Too Many Requests:
HTTP/1.1 429 Too Many RequestsContent-Type: application/problem+jsonRetry-After: 1
{ "title": "Too Many Requests", "status": 429, "detail": "Too many requests in a short period. Slow down and retry after the number of seconds in the Retry-After header.", "errorCode": "burst_limit_exceeded", "traceId": "00-6f1c0a9d2b6e4c1f8a3b5d7e9f0a1b2c-4d5e6f7a8b9c0d1e-00", "correlationId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301"}Retry-After is the whole number of seconds until a request will be accepted again, at least 1.
Daily quota
Section titled “Daily quota”Each tenant has a daily request quota set by its plan:
| Plan | Requests per day |
|---|---|
| Free | 100 |
| Starter | 1,000 |
| Pro | 10,000 |
| Enterprise | Unlimited |
Each API Credit Pack add-on adds 5,000 requests per day. The quota resets at midnight UTC.
While a quota applies, every counted response carries two headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
The tenant’s daily quota. |
X-RateLimit-Remaining |
The requests left today. |
Tenants with an unlimited quota get neither header.
A request over the quota gets 429 Too Many Requests with errorCode rate_limit_exceeded:
HTTP/1.1 429 Too Many RequestsContent-Type: application/problem+jsonX-RateLimit-Limit: 1000X-RateLimit-Remaining: 0X-RateLimit-Reset: 1792454400Retry-After: 30512
{ "title": "Too Many Requests", "status": 429, "detail": "You have exceeded your daily API request limit. Upgrade your plan or purchase additional API credits.", "errorCode": "rate_limit_exceeded", "traceId": "00-6f1c0a9d2b6e4c1f8a3b5d7e9f0a1b2c-4d5e6f7a8b9c0d1e-00", "correlationId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301"}X-RateLimit-Reset is the next midnight UTC, in Unix seconds, and Retry-After is the seconds until
then.
A plan change reaches an API key within about a minute. A user’s access token keeps the quota it was issued with until it is refreshed, at most 15 minutes later.
Handling 429
Section titled “Handling 429”- Branch on
errorCode:burst_limit_exceededclears within seconds, whilerate_limit_exceededlasts until midnight UTC. - Wait at least the
Retry-Afterseconds before retrying. Don’t retry in a tight loop. - Spread bulk work out, and prefer bulk and snapshot endpoints, such as
POST /api/v1/products/bulk(up to 500 products per request) andGET /api/v1/products/snapshot, over many single requests. - Watch
X-RateLimit-Remainingto slow down before the quota runs out.
Feature gates
Section titled “Feature gates”Some routes belong to a feature module that the tenant’s plan must include. A request to such a
route from a tenant whose plan lacks the module gets 403 Forbidden, and isn’t processed:
{ "title": "Forbidden", "status": 403, "detail": "Your current plan does not include the 'catalog' module.", "errorCode": "feature_not_entitled", "traceId": "00-6f1c0a9d2b6e4c1f8a3b5d7e9f0a1b2c-4d5e6f7a8b9c0d1e-00", "correlationId": "3f2504e0-4f89-11d3-9a0c-0305e82c3301"}These routes are gated today:
| Routes | Feature |
|---|---|
/api/v1/products/..., /api/v1/product-categories/... |
catalog |
/api/v1/facilities/{facilityId}/inventory/... |
inventory |
Warehouse configuration, webhooks, team and account routes are available on every plan.
A feature gate is different from a missing permission. feature_not_entitled means your plan needs
upgrading; a 403 without that code means the user or key lacks a permission (see
Permissions and scopes). After an upgrade, an API key gains the
feature within about a minute, and a user gains it when their token is next refreshed.