Rate Limits
API requests are rate limited to ensure fair usage and system stability.
Rate Limits by Plan
| Plan | Requests/min | Emails/day | Storage |
|---|---|---|---|
| Free | 60 | 100 | 1 GB |
| Hobby | 300 | Unlimited* | 10 GB |
| Pro | 1,000 | Unlimited* | 100 GB |
| Enterprise | Custom | Unlimited* | Custom |
* Usage-based pricing applies. See pricing for details.
Email-Specific Limits
| Limit Type | Value | Description |
|---|---|---|
| Batch size | 100 | Max emails per batch request |
| Broadcast recipients | 1,000 | Max recipients per broadcast |
| Email size | 25 MB | Max total email size with attachments |
| Attachments | 10 | Max attachments per email |
CDN-Specific Limits
| Limit Type | Value | Description |
|---|---|---|
| Max file size | 100 MB | Maximum upload file size |
| Bulk delete | 100 | Max assets per delete request |
| Bulk move | 100 | Max assets per move request |
| Image dimension | 4096px | Max transform output dimension |
Rate Limit Headers
All API responses include headers to help you track your rate limit status:
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests allowed per minute |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when window resets |
| Retry-After | Seconds to wait (only on 429 responses) |
Handling Rate Limits
When you exceed the rate limit, you'll receive a 429 response:
429 Response
HTTP/1.1 429 Too Many RequestsContent-Type: application/jsonX-RateLimit-Limit: 60X-RateLimit-Remaining: 0X-RateLimit-Reset: 1699999999Retry-After: 45{"error": {"code": "RATE_LIMITED","message": "Too many requests. Please wait 45 seconds before retrying."}}
Best Practices
- 1.Check headers — Monitor X-RateLimit-Remaining to avoid hitting limits
- 2.Use batch endpoints — Send multiple emails in one request instead of many single requests
- 3.Implement backoff — Use exponential backoff when retrying after rate limit errors
- 4.Queue requests — For high-volume operations, implement a queue to spread requests over time
- 5.Cache responses — Cache read operations where possible to reduce API calls
Example: Rate Limit Aware Client
rate-limit-client.ts
class RateLimitedClient {private remaining = Infinityprivate resetAt = 0async request(fn: () => Promise<Response>) {// Wait if we know we're rate limitedif (this.remaining === 0 && Date.now() < this.resetAt) {const waitTime = this.resetAt - Date.now()await new Promise(r => setTimeout(r, waitTime))}const response = await fn()// Update rate limit state from headersthis.remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || 'Infinity')this.resetAt = parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000if (response.status === 429) {const retryAfter = parseInt(response.headers.get('Retry-After') || '60')await new Promise(r => setTimeout(r, retryAfter * 1000))return this.request(fn) // Retry}return response}}
Need Higher Limits?
If you need higher rate limits or custom quotas, contact us about our Enterprise plan. We can accommodate high-volume use cases with dedicated infrastructure.