Chat SDK
A pattern for building conversational, two-way email on MailBlastr — send with the SDK, receive via webhooks, thread with email headers.
You can turn email into a two-way communication channel for an agent or app: send with the official `mailblastr` SDK (or POST /emails), receive inbound mail through webhooks, and thread conversations using standard email headers. This page describes that pattern and shows how to package it as a Vercel Chat SDK adapter so reply chains map cleanly onto Chat SDK threads.
Prerequisites
- Create an API key.
- Verify your domain.
- Set up webhooks for
email.receivedevents. - Enable receiving on your domain.
1. Send with the SDK
Install the official Node SDK. Every reply you post is just an emails.send call from a verified address.
npm install mailblastrimport { MailBlastr } from 'mailblastr';
const mb = new MailBlastr(process.env.MAILBLASTR_API_KEY!);
async function reply(to: string, subject: string, text: string, headers?: Record<string, string>) {
const { data, error } = await mb.emails.send({
from: 'My Bot <bot@yourdomain.com>',
to: [to],
subject,
text,
headers, // set In-Reply-To / References here to keep the thread intact
});
if (error) throw new Error(`${error.name}: ${error.message}`);
return data;
}2. Receive via webhooks
Point a MailBlastr webhook at your server and subscribe to the email.received event. Verify the signature against your signing secret, then fetch the full message — including headers and body — from the Receiving API.
// POST /webhook
async function handler(req: Request) {
const payload = await req.text();
// Verify the signature against MAILBLASTR_WEBHOOK_SECRET before trusting input.
if (!verifyMailblastrSignature(payload, req.headers, process.env.MAILBLASTR_WEBHOOK_SECRET!)) {
return new Response('invalid signature', { status: 400 });
}
const event = JSON.parse(payload);
if (event.type === 'email.received') {
// Fetch the full inbound message (headers, text, html, attachments).
const { data: email } = await mb.emails.receiving.get(event.data.email_id);
await onInbound(email);
}
return new Response('ok', { status: 200 });
}See Webhook signatures for the verification details and Receiving for the inbound message shape.
3. Thread with email headers
Email threading is carried entirely by standard headers — there is no special API. When you reply, set In-Reply-To to the inbound message's Message-ID and append it to References. Group inbound messages into a conversation by following the same chain.
async function onInbound(email) {
const messageId = email.headers['message-id'];
const references = [email.headers['references'], messageId].filter(Boolean).join(' ');
await reply(email.from, `Re: ${email.subject}`, `Got your email: ${email.text}`, {
'In-Reply-To': messageId,
'References': references,
});
}In-Reply-To/References.Packaging it as a Chat SDK adapter
If you use the Vercel Chat SDK, you can wrap the three steps above in a custom adapter so reply chains surface as Chat SDK threads. The adapter's post maps to mb.emails.send, its webhook handler maps to step 2, and thread resolution uses the In-Reply-To/References headers from step 3. A minimal shape:
import { MailBlastr } from 'mailblastr';
// A custom adapter you author — not a published package.
function createMailblastrAdapter(opts: { fromAddress: string; fromName?: string }) {
const mb = new MailBlastr(process.env.MAILBLASTR_API_KEY!);
return {
name: 'mailblastr',
async post(thread, text) {
await mb.emails.send({
from: opts.fromName ? `${opts.fromName} <${opts.fromAddress}>` : opts.fromAddress,
to: [thread.recipient],
subject: thread.subject,
text,
headers: thread.threadHeaders, // In-Reply-To / References
});
},
// verify signature -> fetch via mb.emails.receiving.get -> resolve thread by headers
async handleWebhook(request) { /* step 2 + step 3 */ },
};
}"mailblastr" consistent across your Chat config and your thread routing so inbound emails resolve to the right thread.Going further
- Card emails — send rich HTML emails with structured card elements.
- Attachments — handle inbound email attachments.
- Proactive outreach — start new email threads without waiting for inbound.