Send your first transactional email
From a sender domain to your first transactional email: add and verify the domain, create an API key, send with curl, Node or SMTP.
postfly is invite-only, so you need an account first. Everything below can be done in the dashboard; the API calls are shown for when you want to automate it.
1 · Add a sender domain
Mail goes out from your own domain, so start by adding it: Domains → Add domain in the dashboard, or POST /v1/domains with a key that has domains:write. The domain starts as pending. A key reaches up to 50 sender domains, and a domain belongs to one group only.
2 · Publish the DNS records
The domain page lists the records to publish at your DNS provider, with the exact values for your domain (the DKIM key is generated for it). They look like this:
| Type | Name | Value | Purpose |
|---|---|---|---|
| TXT | yourdomain.com | v=spf1 include:_spf.postfly.app ~all | SPF |
| TXT | postfly._domainkey.yourdomain.com | v=DKIM1;h=sha256;k=rsa;p=MIIBIjANBg… | DKIM |
| TXT | _dmarc.yourdomain.com | v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; … | DMARC |
| MX | yourdomain.com | 10 mail.postfly.app | Optional |
If the domain already has an SPF record, don't add a second one: postfly shows your current record with its include: merged in, to publish in place of the old one. The MX record is optional and not checked; leave it out on a domain whose mail you receive elsewhere. Sender domains & DNS explains each record.
3 · Verify
Click Re-check now on the domain page, or call POST /v1/domains/{domain}/verify. When SPF, DKIM and DMARC all pass, the domain becomes verified and can send. DNS changes can take a while to show up; for its first 30 days postfly also re-checks a pending domain itself — every 10 minutes on the day you add it or once any of its records has passed, otherwise once a day — and emails you when it passes. To look yourself:
dig +short TXT postfly._domainkey.yourdomain.com
dig +short TXT _dmarc.yourdomain.com4 · Create an API key
On a domain's Keys & SMTP → Create key, pick Sending only (the emails:send scope) for an app that only sends, and optionally restrict the key to the domain you just verified. The key (pf_live_… or pf_test_…) is shown once; keep it in your secret store and pass it as POSTFLY_API_KEY.
5 · Send an email
One request per recipient. from must be an address on a verified domain of the key may send from; html, text or both make the body.
curl -X POST https://api.postfly.app/v1/emails \
-H "Authorization: Bearer $POSTFLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": "Welcome aboard",
"html": "<p>Thanks for signing up.</p>",
"tag": "welcome"
}'The API answers right away; delivery happens in the background:
{
"id": "m_3kTq9ZbW2xYv",
"status": "queued",
"createdAt": "2026-09-11T10:00:00.000Z"
}SMTP takes the same key as the password, with the key's username for the domain (smtp-…@yourdomain.com, beside the key on the Keys & SMTP tab; apikey is still accepted), on smtp.postfly.app:587 with STARTTLS — see SMTP.
6 · Track delivery
GET /v1/emails/{id} returns the message and its status: queued → sending → sent (accepted by our mail server) → delivered (accepted by the recipient's server), or bounced, complained, failed. The dashboard's Activity shows the same timeline, and a webhook pushes each change to your endpoint.