Put the code in the subject
Users can read it from the notification preview without opening the message.
Confirm new accounts and send one-time codes from your backend with one authenticated request. Sendix handles domain signing, queueing, retries to the receiving server and the delivery trail.
await fetch("https://sendix.dev/api/v1/emails", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.SENDIX_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": "login-code-" + challenge.id,
},
body: JSON.stringify({
from: "Acme <[email protected]>",
to: [user.email],
subject: code + " is your Acme login code",
template_id: LOGIN_CODE_TEMPLATE_ID,
template_data: { code, expires_in: "10 minutes" },
priority: "critical",
}),
});Generate the code or signed link in your app and store only its hash, then POST it to https://sendix.dev/api/v1/emails with template_data such as {"code": "742913"}, priority "critical" and an Idempotency-Key per challenge. Keep codes short-lived and single-use, and use email.bounced and email.suppressed events to tell users when they should try a different address.
What your code does, what Sendix does, and where to look when something goes wrong.
Create a 6-digit code or a signed link, store its hash with an expiry, and tie it to the user or sign-up session.
POST /v1/emails with the template, the code in template_data and priority "critical".
Compare the submitted code with the stored hash, accept it once, and limit the number of attempts.
On email.bounced or email.suppressed, prompt the user to correct the address instead of resending.
Habits that protect deliverability and your users, whichever provider you use.
Users can read it from the notification preview without opening the message.
Short validity windows (minutes, not hours) limit the value of an intercepted or forwarded message.
Cap guesses per code and resends per address in your app; each resend should invalidate the previous code.
A dedicated address such as login@ keeps security mail recognisable and separate from product or marketing mail.
Include the code in plain text as well, so it survives clients that block html.
Account verification is not newsletter consent. Use Sendix audience confirmation emails for double opt-in.
Sendix signs each webhook with X-Sendix-Signature and keeps the same events on the message at GET /v1/emails/{id}/events.
| Event | What to do with it |
|---|---|
| email.delivered | What to do with itThe receiving server accepted the code. |
| email.delivery_delayed | What to do with itTemporary failure; show a “still sending” hint. |
| email.bounced | What to do with itAddress does not exist — ask the user to fix it. |
| email.suppressed | What to do with itAddress previously bounced or complained. |
Short answers to the questions teams ask while wiring this up.
Email verification proves that a user controls the address on their account. Double opt-in records consent to receive marketing or newsletter mail. Sendix supports double opt-in through audience confirmation emails (POST /v1/audience/contacts/{id}/send-confirmation), which store the consent proof.
Yes. Put the signed URL in template_data and render it in the template. Treat the link like a code: single use, short-lived, and invalidated when a new one is issued.
Production sending should use a domain verified in Sendix. The dashboard lists the SPF, DKIM, DMARC and bounce records to publish and can apply them automatically for Cloudflare-hosted zones.
The API accepts scheduled_for (an ISO 8601 timestamp), but verification and login mail should normally be sent immediately with priority "critical".
The free plan includes 1,000 emails per month. Paid plans change volume and limits, not your API calls or SMTP settings.
1,000 emails free every month. No credit card required. Upgrade only when you outgrow the free tier — and we will let you know when that time comes.
Managed SaaS platform · Native SMTP engine · SOC 2 in progress