FlaresendDocs

Idempotency

Retry a send as often as you like without the email going out twice.

Networks fail. A request can time out after Flaresend has already accepted the email, and if you simply retry, the recipient gets it twice. An idempotency key prevents that: Flaresend remembers the key, and a repeat request with the same key returns the first email instead of creating a new one.

Send a key

Use the Idempotency-Key header, or the idempotencyKey body field if you can't set headers. When both are sent, the header wins.

await flaresend.emails.send(
  {
    from: 'Acme <hello@acme.com>',
    to: user.email,
    subject: 'Welcome to Acme',
    template: 'welcome',
    data: { name: user.name, appName: 'Acme', loginUrl },
  },
  { idempotencyKey: `welcome-${user.id}` },
);

Keys are 1 to 256 characters.

What happens on a repeat

RequestResult
New keyThe email is created as normal. 202.
Same key, same bodyNothing new is created. 200 with the first email's ID, its status (queued, scheduled or test) and idempotent: true.
Same key, different body409 idempotency_payload_mismatch. Nothing is sent.
{ "id": "email_01K6B2Y4ZP9R3M7T8V5N2QXW4C", "status": "queued", "idempotent": true }

"Same body" is decided by a SHA-256 hash of the parsed request, with object keys sorted and the key itself left out. So the order of fields in your JSON doesn't matter, but any change to a value does. A repeat returns status: "queued" even if the first email has since been sent or delivered; call Retrieve an email for its current status.

Two requests with the same key that arrive at the same moment are also safe: one creates the email, and the other gets the replay.

Scope and lifetime

  • Keys belong to a project. The same key in two projects creates two emails.
  • Keys never expire. welcome-42 can only ever send one welcome email in that project.
  • Keys are checked before the rate limit and daily limit, so a replay doesn't use up either.

Automatic keys in the Node.js client

flaresend.emails.send and flaresend.emails.sendBatch always send a key. If you don't pass one, the client makes a random one for that call (auto_<uuid>) and reuses it on its own retries. That makes the client's retries after a timeout or 5xx safe with no work from you.

An automatic key only covers one call. To stop duplicates across separate calls (a double click, a job that runs twice, a queue that redelivers), pass your own key made from something stable:

SituationGood key
Welcome emailwelcome-${user.id}
Receiptreceipt-${order.id}
Password resetreset-${resetToken.id}
Daily digestdigest-${user.id}-${date}

The RPC client does not retry and does not add keys. Pass one yourself if the calling code can run twice.

Batches

A batch Idempotency-Key is stored per item as <key>:<index>. See Batch sending.

On this page