Rate Limits
API requests are rate-limited per store based on the subscription plan.
Limits by Plan
| Plan | Limit | Burst |
|---|---|---|
| Trial | 10 req/min | 20 |
| Basic | 60 req/min | 120 |
| Pro | 300 req/min | 600 |
| Enterprise | 600 req/min | 1200 |
Limits apply per store, not per user. All API keys for the same store share the same quota.
Response Headers
Every API response includes rate limit headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Reset: 1712678460
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
429 Response
When the limit is exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 8
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712678460
{
"statusCode": 429,
"message": "Rate limit exceeded. Retry after 8 seconds.",
"error": "Too Many Requests",
"code": "RATE_LIMIT_EXCEEDED"
}
SDK Auto-Retry
The SDK automatically retries on 429 with exponential backoff:
const tanqory = createClient({
apiKey: 'pk_live_...',
maxRetries: 3, // Default: 3
})
// SDK waits for Retry-After, then retries automatically
const products = await tanqory.products.list(storeId)
To handle rate limits manually:
import { TanqoryRateLimitError } from '@tanqory/sdk'
try {
await tanqory.products.list(storeId)
} catch (error) {
if (error instanceof TanqoryRateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`)
console.log(`Limit: ${error.limit}, Reset: ${error.resetAt}`)
}
}
Best Practices
- Use pagination with reasonable
limitvalues instead of fetching all records. - Cache responses when possible (products, collections, settings).
- Use webhooks instead of polling for real-time updates.
- Batch operations with bulk endpoints (
/products/bulk,/orders/bulk). - Monitor
X-RateLimit-Remainingand throttle proactively.