Skip to main content

Rate Limits

Information about API rate limits and how to handle them.

Overview​

The Courimax API implements rate limiting to ensure fair usage and system stability. Rate limits are applied per API key.

Rate Limit Headers​

All API responses include rate limit information in the headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1629388800
HeaderTypeDescription
X-RateLimit-LimitnumberMaximum requests allowed in the time window
X-RateLimit-RemainingnumberRemaining requests in current window
X-RateLimit-ResetnumberUnix timestamp when the window resets

Rate Limit Tiers​

Integration Endpoints​

EndpointLimitWindowDescription
Order creation1001 minutePOST /integrations/*/orders
Order queries5001 minuteGET /integrations//orders/
Delivery windows2001 minuteGET /integrations/yango/delivery-windows
Bulk availability501 minuteGET /integrations/yango/availability-bulk
Zone export1001 minuteGET /integrations/yango/zones/export
Order release1001 minutePOST /integrations/yango/orders/*/release

Provisioning Endpoints​

EndpointLimitWindowDescription
List organizations1201 hourGET /provisioning/organizations
Create organization301 hourPOST /provisioning/organizations
Add admin601 hourPOST /provisioning/organizations/*/admins
Resend invite301 hourPOST /provisioning/admins/*/resend-invite
Reset password301 hourPOST /provisioning/admins/*/reset-password
List API keys1201 hourGET /provisioning/organizations/*/api-keys
Create API key601 hourPOST /provisioning/organizations/*/api-keys
Rotate API key601 hourPOST /provisioning/organizations//api-keys//rotate
Revoke API key601 hourDELETE /provisioning/organizations//api-keys/

Handling Rate Limits​

Check Headers​

Monitor rate limit headers to avoid hitting limits:

async function makeRequest(url, options) {
const response = await fetch(url, options);

const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const reset = parseInt(response.headers.get('X-RateLimit-Reset'));

if (remaining < 10) {
const waitTime = (reset - Date.now() / 1000) * 1000;
console.log(`Rate limit low. Waiting ${waitTime}ms`);
await sleep(waitTime);
}

return response;
}

Exponential Backoff​

When you receive a 429 response, implement exponential backoff:

async function requestWithBackoff(url, options, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter) * 1000
: Math.pow(2, i) * 1000;

console.log(`Rate limited. Waiting ${waitTime}ms`);
await sleep(waitTime);
continue;
}

return response;
}

throw new Error('Max retries exceeded');
}

Request Queuing​

Queue requests to stay within limits:

class RateLimitedQueue {
constructor(limit, windowMs) {
this.limit = limit;
this.windowMs = windowMs;
this.queue = [];
this.running = 0;
this.lastReset = Date.now();
}

async add(request) {
return new Promise((resolve, reject) => {
this.queue.push({ request, resolve, reject });
this.process();
});
}

async process() {
if (this.running >= this.limit) return;
if (this.queue.length === 0) return;

// Reset counter if window has passed
if (Date.now() - this.lastReset > this.windowMs) {
this.running = 0;
this.lastReset = Date.now();
}

const { request, resolve, reject } = this.queue.shift();
this.running++;

try {
const result = await request();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.process();
}
}
}

// Usage
const queue = new RateLimitedQueue(100, 60000); // 100 requests per minute

const result = await queue.add(() =>
fetch('https://api.courimax.com/api/integrations/yango/orders', {
method: 'POST',
headers: { 'X-API-Key': API_KEY },
body: JSON.stringify(orderData)
})
);

Best Practices​

Batch Operations​

Use bulk endpoints when possible:

// Instead of multiple individual requests
for (const date of dates) {
await fetch(`/delivery-windows?zone=${zone}&date=${date}`);
}

// Use bulk endpoint
await fetch(`/availability-bulk?fromDate=${startDate}&toDate=${endDate}`);

Caching​

Cache responses when appropriate:

const cache = new Map();

async function getDeliveryWindows(zone, date) {
const cacheKey = `${zone}-${date}`;

if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}

const response = await fetch(
`/delivery-windows?zone=${zone}&date=${date}`
);
const data = await response.json();

// Cache for 5 minutes
cache.set(cacheKey, data);
setTimeout(() => cache.delete(cacheKey), 5 * 60 * 1000);

return data;
}

Request Prioritization​

Prioritize critical requests:

const criticalQueue = new RateLimitedQueue(50, 60000);
const normalQueue = new RateLimitedQueue(50, 60000);

// Critical: Order creation
await criticalQueue.add(() => createOrder(orderData));

// Normal: Order queries
await normalQueue.add(() => getOrderStatus(orderId));

Monitoring​

Monitor your rate limit usage:

class RateLimitMonitor {
constructor() {
this.usage = [];
}

track(response) {
const limit = parseInt(response.headers.get('X-RateLimit-Limit'));
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const used = limit - remaining;
const percentUsed = (used / limit) * 100;

this.usage.push({
timestamp: Date.now(),
limit,
remaining,
percentUsed
});

if (percentUsed > 80) {
console.warn(`Rate limit usage at ${percentUsed}%`);
}
}
}

Increasing Limits​

If you need higher rate limits:

  1. Optimize your integration - Use bulk endpoints, caching, and batching
  2. Contact support - Email support@courimax.com with:
    • Your organization ID
    • Current usage patterns
    • Required limits
    • Business justification

Rate Limit Errors​

When you exceed the rate limit, you'll receive:

{
"statusCode": 429,
"message": "Too many requests, please try again later",
"error": "Too Many Requests"
}

Response headers include:

Retry-After: 60

Wait for the specified number of seconds before retrying.

Monitoring Tools​

Dashboard​

Monitor your API usage in the admin dashboard:

  1. Navigate to Settings → API Usage
  2. View real-time rate limit usage
  3. Analyze historical usage patterns
  4. Set up alerts for high usage

Alerts​

Set up alerts for rate limit warnings:

// In your webhook handler
if (remaining < 20) {
sendAlert({
type: 'rate_limit_warning',
remaining,
limit,
endpoint: url
});
}

Next Steps​