Getting started

Idempotency

Use the Idempotency-Key header to retry send and batch requests safely without delivering duplicate emails.

A network timeout leaves you unsure whether a send request succeeded. If you retry blindly, the recipient may get the email twice. An idempotency key makes the retry safe: Sooner recognizes the repeated request and returns the original result instead of sending again.

How it works

Add an Idempotency-Key header to POST /emails or POST /emails/batch.

Shell
curl -X POST https://api.sooner.dev/emails \
  -H "Authorization: Bearer $SOONER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: welcome-user-123" \
  -d '{
    "from": "Acme <hello@mail.yourcompany.com>",
    "to": ["user@example.com"],
    "subject": "Welcome",
    "html": "<p>Thanks for signing up</p>"
  }'
JSON
{ "id": "01jcz8w3f2x9k4m7n6p5q2r1s0" }

Send the same request again with the same key and you get the same id back, and no second email is sent. For a batch, you get the same list of IDs.

Rules

RuleDetail
Where it appliesPOST /emails and POST /emails/batch. Other endpoints ignore the header.
Key format1 to 256 characters. Anything else returns 400 invalid_idempotency_key.
Lifetime24 hours. After that the key is forgotten and can be reused.
ScopePer team. Two teams can use the same key string without interfering.
Same key, same bodyReturns the original IDs. The retry does not use any quota.
Same key, different bodyReturns 409 invalid_idempotent_request.

Sooner compares the exact request body text, so a change in whitespace or in the order of fields counts as a different body. Build the body once and reuse the same string when you retry.

What is recorded

A key is only recorded once the request has passed validation and the quota check. If a request is rejected with a 422, a 429 or an error on our side, the key is released, and you can retry with the same key after you fix the problem.

If two identical requests with the same key arrive at the same time, both receive the same IDs and the email is sent once.

Choosing a key

Use a value that identifies the business event, so that the same event always produces the same key and different events never share one:

  • welcome-user-123
  • invoice-8841-receipt
  • password-reset- followed by the reset token ID

Avoid random values generated inside the retry loop, because each retry would get a new key and defeat the protection. Generate the key once, before the first attempt.

With the Node SDK

TypeScript
import { Resend } from "resend";

const resend = new Resend(process.env.SOONER_API_KEY, { baseUrl: "https://api.sooner.dev" });

const { data, error } = await resend.emails.send(
  {
    from: "Acme <hello@mail.yourcompany.com>",
    to: ["user@example.com"],
    subject: "Welcome",
    html: "<p>Thanks for signing up</p>",
  },
  { idempotencyKey: "welcome-user-123" },
);

With Python

Python
import os
import requests

res = requests.post(
    "https://api.sooner.dev/emails",
    headers={
        "Authorization": f"Bearer {os.environ['SOONER_API_KEY']}",
        "Idempotency-Key": "welcome-user-123",
    },
    json={
        "from": "Acme <hello@mail.yourcompany.com>",
        "to": ["user@example.com"],
        "subject": "Welcome",
        "html": "<p>Thanks for signing up</p>",
    },
    timeout=15,
)
print(res.status_code, res.json())