Rate Limits
GoTab enforces rate limits separately on the REST and GraphQL APIs because they have different cost profiles: one GraphQL request can replace dozens of REST calls.
Limits
Section titled “Limits”| API | Limit |
|---|---|
| REST | 100 requests per minute per credential |
| GraphQL | 4 requests per second (240/min) per credential |
Limits are applied per api_access_id. Multiple server instances sharing the same credential share the same limit bucket.
429 response
Section titled “429 response”When you exceed the limit, you receive:
HTTP/1.1 429 Too Many RequestsRetry-After: 15Content-Type: application/json
{ "error": "rate_limit_exceeded", "message": "Too many requests.", "statusCode": 429}The Retry-After header tells you the minimum number of seconds to wait before retrying. Always respect it.
Response headers
Section titled “Response headers”GoTab includes rate limit metadata in every response so you can track consumption proactively:
| Header | Description |
|---|---|
X-RateLimit-Limit | Your total request allowance for the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Check X-RateLimit-Remaining before making high-volume calls — if it’s near zero, pause briefly rather than waiting for a 429.
Staying under the limit
Section titled “Staying under the limit”Batch with GraphQL — If you’re making multiple REST calls to assemble a response (e.g. locations + menus + pricing), consolidate them into one GraphQL query. This is the primary purpose of the GraphQL API.
Cache aggressively — Catalog data (menus, products, categories) doesn’t change frequently. Cache responses and invalidate via webhooks (MENU_UPDATED, PRODUCT_UPDATED) rather than polling.
Use webhooks instead of polling — Subscribe to relevant events instead of querying for changes on a timer. A ORDER_PLACED webhook is instant; polling /orders every 10 seconds burns rate limit.
Paginate with larger page sizes — Fewer requests to fetch the same data. Use first: 100 rather than first: 10 for bulk exports.
See also
Section titled “See also”- Error Handling — Retry strategies and exponential backoff
- Webhooks — Event-driven alternative to polling
- Pagination — Fetching large result sets efficiently