Two of the most-requested additions to JetEmail's outbound stack are live today: idempotency keys, which guarantee the same email is never delivered twice, and scheduled send, which lets you queue a message for any moment in the future. Both features are available on the JetEmail HTTP API and over SMTP, so you can use them however you already send mail with JetEmail.
Idempotency Keys
An idempotency key is a unique label you attach to a send request. JetEmail records the key the first time it sees it and links it to the resulting message. If we receive another request with the same key, instead of sending a second email, we return the original result. The recipient sees one email, no matter how many times your code retried the request behind the scenes.
This matters more than it looks. A retried background job, a connection reset between your server and ours, a customer double-clicking a checkout button: any of those can turn one order confirmation into three. That's not just embarrassing, it actively damages your domain reputation, because inbox providers treat repeated near-identical sends as a spam signal. With idempotency keys, retries become safe by default and you can stop writing fragile dedupe logic in your application.
How to use idempotency keys
Set the Idempotency-Key header on your send. The value is any opaque string from 1 to 256 characters. A UUID v4 is a safe default, but tying the key to the business event you're emailing about (an order ID, invoice number, or webhook delivery ID) means a retry of the same event naturally reuses the same key.
- API: add the header
Idempotency-Key: 7c3a9e2a-1f3b-4d6e-9c2a-9e2a1f3b4d6eto your POST request tohttps://api.jetemail.com/email. - SMTP: add the header
X-Idempotency-Key: 7c3a9e2a-1f3b-4d6e-9c2a-9e2a1f3b4d6eto the message before you DATA it across. The header is stripped before delivery so it never reaches recipients.
A retry with the same key and the same body replays the original response: the API returns the original 201 (or 202 for a scheduled send), and SMTP replays the original 250 OK with the same queue ID. Reusing a key with a different body is rejected: 409 IDEMPOTENCY_BODY_MISMATCH on the API, or 554 5.5.0 over SMTP. A concurrent retry that arrives while the first request is still in flight gets a 451 over SMTP (or IDEMPOTENCY_IN_FLIGHT on the API), which is your signal to back off briefly and try again.
One caveat worth knowing: idempotency keys are currently scoped per region. A retry that lands in a different region than the original request will not see the prior key and may produce a duplicate. We're working on a global key store that will close that gap; until then, retry on the same transport you originally submitted on. (For background on why we run regional infrastructure in the first place, see our global infrastructure expansion post.)
Scheduled Send
Scheduled send lets you submit a message now and have JetEmail deliver it at a future time you specify. We accept the message into our queue, hold it on our infrastructure, and release it for delivery at the moment you asked for. Your application doesn't need to stay running, doesn't need a cron, and doesn't need to track pending messages in its own database.
This is the kind of feature most teams end up building themselves. You hold the message in your own database, run a scheduler, and dispatch when the time arrives. It works, but it's a small piece of infrastructure that has to keep running, has to be monitored, and has to be reasoned about every time you deploy. Pushing it down to your email provider gets it out of your stack entirely.
How to use scheduled send
Specify when you want the message delivered, as either a Unix timestamp in seconds (UTC) or an ISO 8601 / RFC 3339 string with offset. The time has to be in the future and no more than 30 days out; anything outside that window is rejected at submit time.
- API: add a
scheduledAtfield to your JSON body, for example"scheduledAt": "2026-05-15T10:00:00Z".scheduled_atis also accepted as a snake_case alias. - SMTP: add the header
X-Scheduled-At: 2026-05-15T10:00:00Zto the message.
A scheduled API send returns 202 Accepted with the queued message ID (immediate sends still return 201). SMTP submissions get a normal 250 reply. Validation actually runs twice: once at submit time, so failures like a missing domain verification or a suppressed recipient surface synchronously instead of 30 days later, and again right before delivery to catch state that has changed in the meantime. If the sending domain is no longer verified, the recipient was suppressed, or the account was downgraded below what the payload requires, the scheduled message is recorded as a failure rather than delivered.
Pair scheduled sends with an idempotency key on the scheduling call itself. A network blip while you're queueing a reminder shouldn't end up scheduling two of them.
Frequently Asked Questions
What is an idempotency key in email sending?
An idempotency key is a unique string you attach to a send request so the email provider can recognise duplicates. If your code retries the same request, the provider replays the original response instead of sending a second email. JetEmail accepts an Idempotency-Key HTTP header on the API and an X-Idempotency-Key MIME header over SMTP.
How do I schedule an email with the JetEmail API?
Add a scheduledAt field to your POST /email JSON body, using either Unix seconds (UTC) or an ISO 8601 / RFC 3339 string with offset. The time has to be in the future and no more than 30 days out. A scheduled send returns 202 Accepted with the queued message ID.
How do I schedule an email over SMTP?
Add an X-Scheduled-At MIME header to the message inside the DATA payload. The value can be Unix seconds or an ISO 8601 timestamp. JetEmail accepts the message with a normal 250 reply, holds it in the queue, and dispatches it at the requested time.
What happens if I retry with the same key but a different body?
JetEmail rejects the request rather than sending a second email. The API returns 409 Conflict with code IDEMPOTENCY_BODY_MISMATCH. Over SMTP the submission is rejected with 554 5.5.0. Generate a new key for a different message.
How long are idempotency keys remembered?
JetEmail caches submissions for 24 hours. Keys are scoped per region today, so a retry that lands in a different region will not see the prior key. Always retry on the same transport you originally submitted on.
How far ahead can I schedule a JetEmail send?
Up to 30 days in the future. The scheduled time has to be in the future and within the 30-day window; anything outside that window is rejected at submit time.
Available Today
Both features are live now for every JetEmail customer, including the free tier. There's no upgrade required, no flag to enable, and no extra charge. Add the header (or field) to your existing send and it just works. If you're new to our outbound stack, see the email API overview for a higher-level walkthrough.
Ready to start using them? The full reference is in the API docs, or jump straight into the dashboard to send a test message.