Rate Limits
Understand API rate limits and how to handle them.
Overview
Rate limits protect the API from abuse and ensure fair usage. Limits are enforced per API key.
Current Limits
REST API
| Environment | Limit | Window |
|---|---|---|
Live keys (wk_live_) | 1,000 requests | Per minute |
Test keys (wk_test_) | 100 requests | Per minute |
OAuth Endpoints
| Endpoint | Limit | Window |
|---|---|---|
POST /oauth/token | 60 requests per IP | Per minute |
POST /oauth/token | 30 requests per client_id | Per minute |
POST /oauth/register | 10 requests per IP | Per hour |
OAuth rate limit responses include a Retry-After header (seconds to wait). Implement exponential backoff — see OAuth errors for a code example.
Response Headers
Every API response includes rate limit information:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Handling Rate Limits
When you exceed the limit, the API returns 429 Too Many Requests:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 45 seconds."
}
}Exponential Backoff
Implement automatic retries with increasing delays:
async function apiRequest(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
const resetAt = response.headers.get('X-RateLimit-Reset');
const waitMs = resetAt
? (Number(resetAt) * 1000) - Date.now()
: Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, waitMs));
}
throw new Error('Rate limit exceeded after max retries');
}Best Practices
- Cache responses when possible to reduce API calls
- Use webhooks instead of polling for real-time data
- Batch operations where the API supports it
- Monitor your usage via the
X-RateLimit-Remainingheader - Spread requests over time instead of bursting