send0

Rate Limits

Understand API rate limits and how to handle them.

Rate Limits

send0 enforces rate limits to ensure fair usage and platform stability. Limits apply per API key and vary by plan tier.

Rate limit headers

Every API response includes rate limit headers so you can track your usage in real time.

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 94
X-RateLimit-Reset: 1712922000

When you hit the limit, the response also includes a Retry-After header:

Retry-After: 47
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Limits by tier

TierRequests/minEmails/month
Free1003,000
Growth50050,000
Scale2,000Unlimited

Send operations and read operations have separate rate limits. Sending an email and listing emails count against different buckets, so high read volume won't block your sends.

SDK behavior

The SDK handles 429 responses automatically with exponential backoff. If a request is rate limited, the SDK waits for the duration specified in the Retry-After header and retries the request. No additional code is needed.

import { Send0 } from 'send0';

// Automatic retry on 429 — no extra configuration required
const send0 = new Send0('sk_live_...');

await send0.emails.send({
  from: 'hello@yourdomain.com',
  to: 'user@example.com',
  subject: 'Hello',
  html: '<p>Hello</p>',
});

Manual handling

If you need to handle rate limits manually — for example, to log them or implement custom retry logic — catch the Send0RateLimitError.

import { Send0RateLimitError } from 'send0';

try {
  await send0.emails.send({
    from: 'hello@yourdomain.com',
    to: 'user@example.com',
    subject: 'Hello',
    html: '<p>Hello</p>',
  });
} catch (err) {
  if (err instanceof Send0RateLimitError) {
    const waitMs = (err.retryAfter ?? 60) * 1000;
    console.log(`Rate limited. Retrying in ${waitMs / 1000}s...`);
    await new Promise(r => setTimeout(r, waitMs));
    // retry the request
  }
}

Best practices

  • Check headers proactively. Monitor X-RateLimit-Remaining and slow down before hitting the limit rather than reacting to 429 errors.
  • Use exponential backoff. If you implement custom retry logic, use exponential backoff with jitter to avoid thundering herd problems.
  • Batch where possible. Instead of sending 100 individual requests, check if the API supports batch operations to reduce request count.
  • Separate send and read traffic. Since sends and reads have independent limits, separate your send and read logic to maximise throughput.
  • Upgrade your plan if you consistently hit limits. Growth and Scale tiers offer significantly higher throughput.