Products
Send and receive email from your domains and give agents their own mailboxes.
Built Send email from your own domains, receive it, and give agents mailboxes of their own. The API will feel familiar if you have used Resend: emails, templates, audiences, broadcasts, API keys and webhooks.
Send#
import { OpenPulseMail, MailError } from '@openpulse/sdk/mail'const mail = OpenPulseMail.fromEnv() // MAIL_API_KEY + MAIL_API_URLawait mail.send({ from: 'Acme <hello@acme.example>', to: 'ana@example.com', subject: 'Welcome', html: '<p>Hi Ana</p>' })Templates#
await mail.templates.create({ name: 'Welcome', alias: 'welcome', from: 'Acme <hello@acme.example>', subject: 'Welcome, {{first_name|friend}}', html: '<p>Hi {{first_name}}</p>', // {{x}} escaped, {{{x}}} raw})await mail.send({ to: 'ana@example.com', template: { id: 'welcome', variables: { first_name: 'Ana' } } })A missing variable is a 422 that names it (TEMPLATE_VARIABLES_MISSING).
Broadcasts#
const readers = await mail.audiences.create({ name: 'Newsletter' })await mail.contacts.import(readers.id, [{ email: 'ana@example.com', first_name: 'Ana' }])const issue = await mail.broadcasts.create({ audience_id: readers.id, from: 'News <news@acme.example>', subject: 'September', html: '<p>…</p><a href="{{{unsubscribe_url}}}">Unsubscribe</a>',})await mail.broadcasts.send(issue.id, { scheduled_at: 'in 1 hour' })Webhooks#
Delivery and broadcast events are retried for about a day with a stable id; verify them like Svix webhooks.
const hook = await mail.webhooks.create({ endpoint: 'https://acme.example/hooks/mail', events: ['email.bounced'] })const event = await mail.webhooks.verify({ payload: rawBody, headers: req.headers, secret: hook.secret })Good to know#
| Counting | Each recipient of an email you send counts once; suppressed and cancelled ones do not. |
| Domains | Add and verify sending domains in the Console (Domains); DNS records are checked for you. |
| Bounces | Hard bounces and complaints suppress the address for your organization automatically. |
| Messages between OpenPulse users | Use sealed messaging on the wire, not email; mail is for the rest of the internet. |