- New conversation — pass
to,subject, and a body. We pick a mailbox from the pool, register the conversation, fireemail.sent. - Reply to existing — pass
convIdand a body. We resolve recipient, subject, threading headers, and the bound mailbox from the conv.
New conversation
text and html can both be set; recipients see the multipart message
their client prefers. Most production senders set both.
If you’re stitching to a thread that started outside 12m (e.g. you
imported a CRM history), pass inReplyTo and references:
Reply to a thread
When you have theconvId from a prior send (or from a webhook),
replying is one field:
Re: prefix), threading headers,
and — critically — the same backing mailbox from the conversation
state. Recipients see a coherent thread from one consistent sender.
convId is mutually exclusive with to / subject. Cross-identity
replies (a convId that lives on a different identity) return 404.
Idempotency
Every send accepts an optionalIdempotency-Key header. Same key with
the same body returns the original response (with
Idempotent-Replayed: true); same key with a different body returns
409. Keys live for 24 hours.
<leadId>:<step> — if the worker
crashes after we accepted the send but before your DB recorded it, the
retry returns the same response and you don’t double-send.
Response
convId— store this against your lead/contact record. Every follow-up uses it.affinity—new(we created an affinity row),existing(we reused the recipient’s pinned mailbox), orreassigned(the pinned mailbox was unhealthy or capped, we picked another).account.email— the rotated mailbox we used. Surfaced for transparency and deliverability dashboards. You don’t need to act on it.remaining— daily-cap budget left on this identity today.
202 if anything was accepted, 429 if every recipient
was rejected (typically cap_exceeded).
What we don’t support yet
In the interest of not lying to you:- Scheduled sends. No
sendAt. Every send dispatches immediately. If you need “fire at 9am Tuesday in the prospect’s timezone,” run a scheduler in your own infra and call us at fire time. TheIdempotency-Keymakes the retry semantics safe. - Attachments. Not supported. If your use case needs them, tell us.
- Custom headers. No way to set
List-Unsubscribe/List-Unsubscribe-Posttoday. This is high-priority because Gmail/Yahoo bulk-sender requirements increasingly need it; we’ll ship it. - Multi-recipient sends.
toaccepts an array, but we send to each recipient separately so each gets its own conversation. Bulk broadcasts tocclists aren’t a 12m use case — that’s transactional email territory.