⏱️Rate Limits
Our API employs rate limiting to ensure fair usage and to prevent abuse. Gangmates employs layered rate limiting to protect tenants and the platform. There are two buckets evaluated per request:
Endpoint Bucket (per token + IP + route)
Default: 100 requests/min
Sensitive endpoints: 10 requests/min (listed below)
Global Bucket (per company + IP)
Standard: 50 requests/min
Premium: 1,000 requests/min
Enterprise: 5,000 requests/min
The effective limit is the stricter of the two. For example, a Standard plan calling a non‑sensitive endpoint is limited to 50/min globally, even though the endpoint bucket allows 100/min.
Response headers
Every response includes rate‑limit headers so you can programmatically back off:
X-RateLimit-Limit-Endpoint: <int>
X-RateLimit-Remaining-Endpoint: <int>
X-RateLimit-Limit-Global: <int>
X-RateLimit-Remaining-Global: <int>
On 429 Too Many Requests
, you’ll also receive:
Retry-After: <seconds>
429 handling (pseudo‑code)
if response.status == 429:wait(response.headers['Retry-After'] seconds)retry
Add jitter/exponential backoff in production clients.
Errors
Standard HTTP status codes are used.
200 OK
– Success201 Created
– Resource created400 Bad Request
– Invalid request401 Unauthorized
– Missing/invalid/expired token403 Forbidden
– Token scopes do not allow this route404 Not Found
– Resource not found429 Too Many Requests
– Rate limit exceeded (seeRetry-After
)
Error bodies are JSON. Examples:
{ "error": "Unauthorized" }
Examples
Here are examples of how you can implement this retry logic in different programming languages:
const axios = require('axios');
async function makeApiRequest(url, options) {
try {
const response = await axios(url, options);
return response.data;
} catch (error) {
if (error.response && error.response.status === 429) {
// Extract the Retry-After header value
const retryAfter = parseInt(error.response.headers['retry-after'], 10);
if (!isNaN(retryAfter)) {
console.log(`Rate limit exceeded. Retrying after ${retryAfter} seconds...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return makeApiRequest(url, options); // Retry the request
} else {
console.error('Rate limit exceeded but no Retry-After header found.');
}
} else {
console.error('Request failed:', error.message);
}
}
}
// Example usage
const url = 'https://api.example.com/your-endpoint';
const options = {
method: 'GET',
headers: {
'Authorization': 'Bearer your_token_here'
}
};
makeApiRequest(url, options)
.then(data => {
console.log('API Response:', data);
})
.catch(error => {
console.error('Request failed:', error.message);
});
By implementing the above retry mechanism, your application can handle rate limiting gracefully, ensuring that your requests are processed once the rate limit resets. If you have any questions or need further assistance, please contact our support team at [email protected].
Last updated