The CommodityAI API implements rate limiting to ensure fair usage and maintain system stability for all users. Rate limits are applied per API key.
Current Rate Limits
All API keys are subject to the following limits:
Per Minute : 100 requests
Per Day : 10,000 requests
These limits apply to all API endpoints and are tracked separately for each API key.
Every API response includes headers showing your current rate limit status:
HTTP / 1.1 200 OK
X-RateLimit-Limit-Minute : 100
X-RateLimit-Remaining-Minute : 87
X-RateLimit-Reset-Minute : 1705939260
X-RateLimit-Limit-Day : 10000
X-RateLimit-Remaining-Day : 1234
X-RateLimit-Reset-Day : 1705968000
Maximum number of requests allowed per minute
X-RateLimit-Remaining-Minute
Number of requests remaining in the current minute
Unix timestamp (in seconds) when the per-minute limit resets
Maximum number of requests allowed per day
X-RateLimit-Remaining-Day
Number of requests remaining today
Unix timestamp (in seconds) when the daily limit resets
Rate Limit Exceeded Response
When you exceed your rate limit, the API returns a 429 Too Many Requests status:
Per-Minute Limit Exceeded:
{
"error" : {
"code" : "rate_limit_exceeded" ,
"message" : "Rate limit exceeded. Maximum 100 requests per minute. Retry after 42 seconds."
}
}
Daily Limit Exceeded:
{
"error" : {
"code" : "rate_limit_exceeded" ,
"message" : "Daily rate limit exceeded. Maximum 10000 requests per day. Retry after 6 hours."
}
}
The response includes rate limit headers and a Retry-After header indicating how long to wait (in seconds) before making another request:
HTTP / 1.1 429 Too Many Requests
X-RateLimit-Limit-Minute : 100
X-RateLimit-Remaining-Minute : 0
X-RateLimit-Reset-Minute : 1705939260
Retry-After : 42
Handling Rate Limits
Check the rate limit headers in every response to track your usage:
const response = await fetch ( 'https://app.commodityai.com/api/v1/sources/123e4567-e89b-12d3-a456-426614174000/records' , {
headers: {
'Authorization' : 'Bearer cai_live_your_api_key_here'
}
});
// Check rate limit status
const minuteRemaining = response . headers . get ( 'X-RateLimit-Remaining-Minute' );
const minuteReset = response . headers . get ( 'X-RateLimit-Reset-Minute' );
const dayRemaining = response . headers . get ( 'X-RateLimit-Remaining-Day' );
const dayReset = response . headers . get ( 'X-RateLimit-Reset-Day' );
console . log ( `Requests remaining: ${ minuteRemaining } /minute, ${ dayRemaining } /day` );
console . log ( `Resets: minute at ${ new Date ( minuteReset * 1000 ). toISOString () } , day at ${ new Date ( dayReset * 1000 ). toISOString () } ` );
Exponential Backoff
Implement exponential backoff when you receive rate limit errors. Use the Retry-After header to determine the wait time:
async function makeRequestWithRetry ( url , options , maxRetries = 3 ) {
for ( let attempt = 0 ; attempt <= maxRetries ; attempt ++ ) {
try {
const response = await fetch ( url , options );
if ( response . status === 429 ) {
if ( attempt === maxRetries ) {
throw new Error ( 'Rate limit exceeded after max retries' );
}
// Use Retry-After header if available, otherwise exponential backoff
const retryAfter = response . headers . get ( 'Retry-After' );
const waitTime = retryAfter
? parseInt ( retryAfter ) * 1000
: Math . pow ( 2 , attempt ) * 1000 ;
console . log ( `Rate limited. Waiting ${ waitTime } ms before retry...` );
await new Promise ( resolve => setTimeout ( resolve , waitTime ));
continue ;
}
return response ;
} catch ( error ) {
if ( attempt === maxRetries ) throw error ;
}
}
}
// Usage
const response = await makeRequestWithRetry (
'https://app.commodityai.com/api/v1/sources/123e4567-e89b-12d3-a456-426614174000/records' ,
{
headers: {
'Authorization' : 'Bearer cai_live_your_api_key_here'
}
}
);
Batch Requests
When fetching large datasets, use pagination to stay within rate limits:
async function fetchAllRecords ( definitionId ) {
let allRecords = [];
let cursor = null ;
do {
const params = new URLSearchParams ({
limit: '1000' // Max limit to minimize requests
});
if ( cursor ) {
params . append ( 'cursor' , cursor );
}
const response = await fetch (
`https://app.commodityai.com/api/v1/sources/ ${ definitionId } /records? ${ params } ` ,
{
headers: {
'Authorization' : 'Bearer cai_live_your_api_key_here'
}
}
);
// Check if we're approaching rate limit
const remainingMinute = parseInt (
response . headers . get ( 'X-RateLimit-Remaining-Minute' ) || '0'
);
if ( remainingMinute < 10 ) {
console . log ( 'Approaching rate limit, slowing down...' );
await new Promise ( resolve => setTimeout ( resolve , 2000 ));
}
const data = await response . json ();
allRecords . push ( ... data . data );
cursor = data . meta . has_more ? data . meta . next_cursor : null ;
} while ( cursor );
return allRecords ;
}
Best Practices
Use cursor-based pagination
Cache API responses when the data doesn’t change frequently. This reduces redundant API calls and helps you stay within rate limits.
Regularly check the rate limit headers to understand your usage patterns. Set up alerts before reaching limits.
Use webhooks for real-time updates
Instead of polling the API, use webhooks (coming soon) to receive real-time notifications when data changes.
Separate API keys for different services
Create separate API keys for different applications or services. This helps isolate rate limit usage and makes it easier to track which service is consuming your quota.
Need Higher Limits?
If your use case requires higher rate limits, please contact our sales team at [email protected] to discuss custom limits for your account.