Skip to content

Rate limits

The API limits requests per second per team (not per key):

Plan Requests per second
Free 10
Pro 10
Scale 25
Enterprise Custom

Resend’s limit is 2 requests per second. A batch of up to 100 emails is one request, so you can send thousands of emails per second within the limit.

Limits are applied in one-second windows. Dashboard sessions are not rate limited. Sending quotas (Plans and quotas) are separate from request limits.

Every response includes:

Header Meaning
ratelimit-limit Requests allowed per window (for example 10).
ratelimit-remaining Requests left in the current window.
ratelimit-reset Seconds until the window resets (1).
retry-after Only on 429: seconds to wait before retrying (1).
HTTP/1.1 429 Too Many Requests
ratelimit-limit: 10
ratelimit-remaining: 0
ratelimit-reset: 1
retry-after: 1
{ "statusCode": 429, "name": "rate_limit_exceeded", "message": "Too many requests. You can only make 10 requests per second." }
import { SpacePost, type SendEmailOptions } from "@spacepost/node";
const spacepost = new SpacePost();
async function sendWithRetry(email: SendEmailOptions, key: string, attempts = 5) {
for (let i = 0; i < attempts; i++) {
const { data, error } = await spacepost.emails.send(email, { idempotencyKey: key });
if (!error) return data;
if (error.name !== "rate_limit_exceeded") throw new Error(`${error.name}: ${error.message}`);
await new Promise((r) => setTimeout(r, 1000 * (i + 1)));
}
throw new Error("rate limited");
}

Always reuse the same Idempotency-Key on retries so a request that actually succeeded is not repeated.

  • Prefer batches over many single sends.
  • Queue sends in a background worker and cap its concurrency to your limit.
  • Spread import jobs (for example creating contacts) at a steady pace.