Email your users actually receive.
Receipts, resets, alerts. REST or SMTP. Idempotent, signed, delivered.
Developer-first
Send with your favorite stack.
One API call, or SMTP. Same pipeline.
One call
REST or SMTP. Same guarantees.
Idempotent
Retries never double-send.
Scoped keys
A service can send — and nothing more.
import { Unitpost } from "unitpost";
const unitpost = new Unitpost(process.env.UNITPOST_API_KEY);
await unitpost.email.send({
from: "you@acme.com",
to: "user@example.com",
subject: "Your receipt from Acme",
html: "<p>Thanks for your order!</p>",
});Observability
Complete visibility of every message.
Delivered, opened, clicked, bounced, complained. Per email, or in aggregate.
- Clicked “RSVP now” in Monthly Newsletteremail.clicked2m
- Opened Password resetemail.opened4m
- Order receipt delivered to ada@example.comemail.delivered9m
- Reply received at support@acme.comemail.received26m
Drop-in SMTP
Already have an SMTP setup?
Swap host, username, password. Keep your mail code.
TLS
Ports 587 and 465.
API key as password
Rotate or revoke anytime.
Built for reliability
Everything a transactional stream needs.
Speed, idempotency, inbox.
Deliverability
DKIM, SPF, DMARC. Kept in the inbox.
Templates by id
Build once. Send with variables.
Batch & scheduled
Up to 100 per call. Cancel before send.
Per-message tracking
Dashboard and API. What happened to that reset.
Suppression
Bounces and complaints. Automatic.
Rate-limited
Per-workspace limits. Scoped keys.
Extendable
Do more than sending.
One SDK. Send, retrieve, cancel — plus campaigns, webhooks, and domains.
import { Unitpost } from "unitpost";
const unitpost = new Unitpost(process.env.UNITPOST_API_KEY);
await unitpost.email.send({
from: "you@acme.com",
to: "user@example.com",
subject: "Your receipt from Acme",
html: "<p>Thanks for your order!</p>",
});Quick integration
Connect easily with any service
Add Unitpost to tools you already use, or point SMTP at the relay.
Flexible
Ready for every use case
Welcome mail or a critical alert. Same pipeline.
Password resets
Time-sensitive. Idempotent. One link, not two.
Receipts & invoices
From a template. Tracked per message.
OTP & verification
Built to hit the inbox, not spam.
Welcome
Fired the moment they sign up.
Alerts
From your backend or SMTP.
Trial & renewal
On a schedule. Before it lapses.
Invitations
Tracked links. Reliably delivered.
Policy updates
To everyone, with proof of delivery.
Start free
Send your first email in minutes
$0/ mo
- 5,000 emails / mo — no credit card
- Your domain with DKIM, SPF & DMARC
- REST API, SMTP & official SDKs
- Visual editor + code templates
- Open & click tracking + signed webhooks
- 10,000 contacts · automatic suppression
Questions
Common questions
What is transactional email?
Transactional email is mail sent to one person in response to something they did — a password reset, a receipt, an OTP code, a shipping notification. It is distinct from marketing email, which goes to many recipients at once and legally requires an unsubscribe link. Transactional mail is expected by the recipient, so it should never carry a marketing footer.
How do I stop duplicate emails when my code retries?
Send an Idempotency-Key header with the request. Unitpost dedupes on that key for 24 hours, so a retried POST returns the original result instead of sending a second email. Reusing a key with a different body returns 409 rather than silently sending the wrong message. This matters most in webhook handlers and job queues, where at-least-once delivery makes retries normal.
Can I schedule or cancel a transactional email?
Yes. Pass scheduled_at when you send, then PATCH the email to reschedule or cancel it before it goes out. Free plans can schedule up to 7 days ahead; paid plans up to 90. Batch sends can be cancelled as a whole batch.
How do I know whether an email was delivered?
Every message emits events you can read via the API or receive as signed webhooks: sent, delivered, delivery_delayed, bounced, complained, opened, clicked, and failed. Webhook deliveries are svix-compatible, signed with HMAC-SHA256, so you can verify them with any Svix-compatible library.
Do bounces and complaints suppress future sends automatically?
Yes, and you cannot accidentally turn it off. A hard bounce or spam complaint writes a suppression that blocks future sends to that address, and five consecutive soft bounces within 30 days escalate to a suppression too. Complaint suppressions cannot be self-serve deleted — the API returns 409 — because removing one is how senders destroy their own reputation.
Can I send transactional email over SMTP instead of the API?
Yes. Point any SMTP client at smtp.unitpost.com with the username unitpost and an API key as the password. It runs through the same pipeline as the REST API, so tracking, webhooks, suppression, and the dashboard behave identically. STARTTLS on 587 or 2587, implicit TLS on 465 or 2465; TLS is mandatory.