Documentation Index
Fetch the complete documentation index at: https://docs.buildwithchirp.com/llms.txt
Use this file to discover all available pages before exploring further.
The Chirp API enforces rate limits to ensure fair usage and maintain service quality for all users.
Rate Limit Tiers
Rate limits vary by endpoint and API key type:
App Keys
- SMS Sending: 100 requests per minute
- Webhook Management: 60 requests per minute
- General API: 120 requests per minute
Admin Keys
- Application Management: 60 requests per minute
- Organization Settings: 60 requests per minute
- General API: 120 requests per minute
Each API response includes headers indicating your current rate limit status:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
X-RateLimit-Limit
The maximum number of requests allowed in the current window.
X-RateLimit-Remaining
The number of requests remaining in the current window.
X-RateLimit-Reset
Unix timestamp when the rate limit window resets.
Rate Limit Exceeded
When you exceed the rate limit, the API returns:
HTTP Status: 429 Too Many Requests
Response:
{
"error": "Rate limit exceeded. Try again in 30 seconds."
}
Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Retry-After: 30
Best Practices
1. Implement Exponential Backoff
When you receive a 429 response, wait before retrying:
async function sendWithRetry(payload, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(`$https://api.buildwithchirp.com/v1/sms`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After");
await new Promise((r) => setTimeout(r, retryAfter * 1000));
continue;
}
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise((r) => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}
2. Monitor Rate Limit Headers
Track your usage by checking rate limit headers:
const response = await fetch(`$https://api.buildwithchirp.com/v1/sms`, options);
const limit = response.headers.get("X-RateLimit-Limit");
const remaining = response.headers.get("X-RateLimit-Remaining");
const reset = response.headers.get("X-RateLimit-Reset");
console.log(`${remaining}/${limit} requests remaining`);
console.log(`Resets at ${new Date(reset * 1000)}`);
3. Batch Requests When Possible
Send messages to multiple recipients in a single request:
{
"from": "+15551234567",
"to": ["+15559876543", "+15551112222", "+15553334444"],
"text": "Bulk message"
}
4. Implement Request Queuing
Use a queue to manage high-volume sending:
class RateLimitedQueue {
constructor(requestsPerMinute) {
this.queue = [];
this.interval = 60000 / requestsPerMinute;
}
async add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
if (this.queue.length === 1) {
this.process();
}
});
}
async process() {
while (this.queue.length > 0) {
const { fn, resolve, reject } = this.queue[0];
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
}
this.queue.shift();
if (this.queue.length > 0) {
await new Promise((r) => setTimeout(r, this.interval));
}
}
}
}
5. Cache When Appropriate
Cache responses that don’t change frequently:
- Webhook configurations
- Application settings
- Phone number assignments
Higher Rate Limits
If you need higher rate limits for your use case, contact our sales team to discuss custom limits for your account.
Test Mode
Rate limits also apply to test API keys, but test mode has more generous limits to facilitate development and testing.