Skip to content
emailkit
Esc
navigateopen⌘Jpreview
On this page

Send email

One message format for every provider — attachments, replies, scheduling included.

The same message object sends through Resend, Mailgun, Gmail, Outlook, or AIInbx. emailkit builds the provider-specific request behind the scenes.

Send a message

const result = await emailkit.sendEmail({
  from: { email: "hello@example.com", name: "Acme" },
  to: [
    { email: "ada@example.com", name: "Ada" },
    { email: "grace@example.com", name: "Grace" },
  ],
  subject: "Quarterly update",
  text: "The report is attached.",
  html: "<p>The report is <strong>attached</strong>.</p>",
});

console.log(result.messageId, result.provider);

Include a text body, an HTML body, or both. The result always tells you which provider sent it and the message ID to save.

Attach files

await emailkit.sendEmail({
  from: { email: "reports@example.com" },
  to: { email: "ada@example.com" },
  subject: "Your report",
  text: "Attached.",
  attachments: [
    {
      filename: "report.pdf",
      content: reportBytes,
      contentType: "application/pdf",
    },
  ],
});

Pass content directly, or a URL when your provider supports it.

Reply in the same thread

Take the reply details from a received email and send. emailkit produces the right threading for each provider — including Outlook’s native reply flow, which it runs for you behind the same sendEmail() call.

onInbound: async (inbound) => {
  await emailkit.sendEmail({
    from: { email: "support@example.com" },
    to: inbound.from,
    subject: `Re: ${inbound.subject}`,
    text: "Thanks — we received your message.",
    reply: {
      messageId: inbound.messageId,
      references: inbound.reply.references,
      threadId: inbound.reply.threadId,
    },
  });
},

Use provider extras

Scheduling, templates, tracking, tags, duplicate-send protection — they appear in TypeScript when your provider supports them:

await emailkit.sendEmail({
  from: { email: "hello@example.com" },
  to: { email: "ada@example.com" },
  subject: "Tomorrow's reminder",
  text: "Your meeting starts at 10:00.",
  sendAt: new Date("2026-07-16T08:00:00Z"),
  idempotencyKey: "meeting-reminder-42",
  sender: { emailDriver: "resend" },
});

With several providers configured, add sender.emailDriver when a message needs a feature only one of them has.

Send from a connected mailbox

Set up the mailbox lookup once in resolveEmailDriver (see Connect mailboxes), and every send call stays this simple:

await emailkit.sendEmail({
  from: { email: "acme.support@gmail.com" },
  to: { email: "customer@example.com" },
  subject: "From the support inbox",
  text: "This message appears in the connected mailbox.",
});

emailkit finds the inbox from the from address and sends through it.

Abort a send

await emailkit.sendEmail(message, { signal: request.signal });

Last updated on July 24, 2026

Was this page helpful?