Skip to content
OpenPulseDocs

Products

Mail

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#

TypeScript
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#

TypeScript
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#

TypeScript
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.

TypeScript
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#

CountingEach recipient of an email you send counts once; suppressed and cancelled ones do not.
DomainsAdd and verify sending domains in the Console (Domains); DNS records are checked for you.
BouncesHard bounces and complaints suppress the address for your organization automatically.
Messages between OpenPulse usersUse sealed messaging on the wire, not email; mail is for the rest of the internet.