Rate Limits
Understanding and working with API rate limits to ensure reliable service.
Overview
The MsGine API uses rate limiting to protect infrastructure and ensure fair usage. Rate limits are applied per API key.
Default Limits
| Tier | Requests/Minute | Requests/Second (Burst) |
|---|---|---|
| Free | 60 | 10 |
| Starter | 100 | 20 |
| Professional | 500 | 50 |
| Enterprise | Custom | Custom |
Rate Limit Headers
Every API response includes rate limit information in headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000| Header | Description |
|---|---|
X-RateLimit-Limit | Total requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Rate Limit Exceeded
When you exceed the rate limit, you'll receive a 429 Too Many Requests response:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Please try again later.",
"retryAfter": 60
}
}The Retry-After header indicates when you can retry (in seconds):
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000060Handling Rate Limits
Manual Retry Logic
If using the REST API directly, implement retry logic:
async function sendWithRetry(url: string, data: any, retries = 3) {
for (let i = 0; i < retries; i++) {
const response = await fetch(url, {
method: 'POST',
headers: {
'X-Api-Key': process.env.MSGINE_API_KEY!,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
if (response.status !== 429) {
return response.json()
}
const retryAfter = parseInt(response.headers.get('Retry-After') || '60')
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000))
}
throw new Error('Max retries exceeded')
}Check Rate Limit Status
Monitor your rate limit status:
async function checkRateLimit() {
const response = await fetch('https://api.msgine.net/api/v1/account', {
headers: {
'X-Api-Key': process.env.MSGINE_API_KEY!,
}
})
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(`Rate Limit: ${remaining}/${limit}`)
console.log(`Resets at: ${new Date(parseInt(reset!) * 1000)}`)
}Best Practices
1. Implement Exponential Backoff
async function exponentialBackoff(attempt: number) {
const delay = Math.min(1000 * Math.pow(2, attempt), 10000)
await new Promise(resolve => setTimeout(resolve, delay))
}2. Use Request Queuing
For high-volume applications, implement a request queue:
class RequestQueue {
private queue: Array<() => Promise<any>> = []
private processing = false
private readonly requestsPerMinute = 100
async enqueue<T>(request: () => Promise<T>): Promise<T> {
return new Promise((resolve, reject) => {
this.queue.push(async () => {
try {
const result = await request()
resolve(result)
} catch (error) {
reject(error)
}
})
if (!this.processing) {
this.process()
}
})
}
private async process() {
this.processing = true
const interval = 60000 / this.requestsPerMinute
while (this.queue.length > 0) {
const request = this.queue.shift()!
await request()
await new Promise(resolve => setTimeout(resolve, interval))
}
this.processing = false
}
}3. Batch Recipients
Send to multiple recipients in a single request instead of multiple requests:
// ✅ Better - Single request for multiple recipients
await client.sms.send({
to: phones,
message: 'Hello!'
})
// ❌ Not optimal - Multiple requests
for (const phone of phones) {
await client.sms.send({ to: phone, message: 'Hello!' })
}4. Cache Responses
Cache responses when appropriate:
const cache = new Map()
async function getAccountInfo() {
const cached = cache.get('account')
if (cached && Date.now() - cached.timestamp < 60000) {
return cached.data
}
const data = await client.getAccount()
cache.set('account', {
data,
timestamp: Date.now()
})
return data
}5. Monitor Usage
Track your rate limit usage:
function checkRateLimitHealth(remaining: number, limit: number) {
const percentage = (remaining / limit) * 100
if (percentage < 10) {
console.error('Critical: Less than 10% rate limit remaining')
} else if (percentage < 25) {
console.warn('Warning: Less than 25% rate limit remaining')
}
}Increasing Rate Limits
To increase your rate limits:
- Upgrade your plan: Higher tiers have higher limits
- Contact sales: Enterprise customers can request custom limits
- Optimize usage: Implement batching and caching
Rate Limit by Endpoint
Different endpoints may have different rate limits:
| Endpoint | Limit (req/min) |
|---|---|
POST /developers/sms | Plan-dependent |
GET /developers/sms/history | Plan-dependent |
GET /account | Plan-dependent |
POST /webhooks | 20 |
Burst Limits
Burst limits allow short spikes in traffic:
- Burst window: 1 second
- Burst limit: Varies by plan (10-50 requests/second)
Next Steps
- REST API - API reference and examples
- Authentication - Managing API keys
- Best Practices - Optimization strategies