Receiving

Forward received emails

Forward an inbound email to another address — either with the built-in forward endpoint, or by downloading the raw message, parsing it, and re-sending via POST /emails.

Received emails can be forwarded on to another address. There are two approaches: the built-in forward endpoint, which re-sends the stored parsed message body with the original attachments (inline images preserved) in one call, or a manual re-send, where you download and parse the raw message yourself for full RFC 5322 fidelity.

Webhooks include metadata only — not the body, headers, or attachment content. Retrieve the message with the Receiving API (and the Attachments API for files) before forwarding.

Forward endpoint

The quickest way to forward is `POST /emails/receiving/:id/forward`. It re-sends the received email's stored parsed subject, html, and text — along with the original attachments — as a new outbound email. Pass from (required) and the recipient(s); the original subject, body, and files are reused.

Body
fromstringoptional

Required. The sender address for the forwarded message. Must be an address on a verified sending domain.

tostring | string[]optional

The recipient address(es) to forward to.

import { MailBlastr } from 'mailblastr';

const mb = new MailBlastr('mb_xxxxxxxxx');

const { data, error } = await mb.emails.receiving.forward('56761188-7520-42d8-8898-ff6fc54ce618', {
  "from": "Acme <hello@yourdomain.com>",
  "to": ["delivered@example.com"]
});
console.log({ data, error });
The forward endpoint re-sends the parsed subject and body and re-attaches the original attachments — inline images are preserved via their content_id, so embedded images still render. Attachments are best-effort: any whose stored bytes can't be loaded are skipped, and the same per-attachment / total size caps as a normal send apply. For full RFC 5322 fidelity (exact original MIME, custom headers), use the manual re-send below instead.

Forward by re-sending

The most faithful way to forward is to download the raw RFC 5322 message and parse it, so you correctly extract the HTML/text bodies and every attachment — especially inline images referenced by Content-ID. Then re-send the extracted content with POST /emails.

The retrieved received email exposes a raw.download_url you can fetch to get the original bytes. Strip the angle brackets from each inline part's content_id so the forwarded HTML still resolves its embedded images.

// app/api/events/route.ts
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { simpleParser } from 'mailparser';

const API_KEY = 'mb_xxxxxxxxx';

export const POST = async (request: NextRequest) => {
  const event = await request.json();

  if (event.type === 'email.received') {
    // 1. Get the received email (includes raw.download_url)
    const metaRes = await fetch(
      `https://api.mailblastr.com/emails/receiving/${event.data.email_id}`,
      { headers: { Authorization: `Bearer ${API_KEY}` } },
    );
    const email = await metaRes.json();

    if (!email?.raw?.download_url) {
      return new NextResponse('Raw email not available', { status: 500 });
    }

    // 2. Download and parse the raw RFC 5322 message
    const rawResponse = await fetch(email.raw.download_url);
    const rawEmailContent = await rawResponse.text();
    const parsed = await simpleParser(rawEmailContent, { skipImageLinks: true });

    // 3. Re-build attachments, keeping inline content_ids
    const attachments = parsed.attachments.map((attachment) => {
      const contentId = attachment.contentId
        ? attachment.contentId.replace(/^<|>$/g, '')
        : undefined;
      return {
        filename: attachment.filename,
        content: attachment.content.toString('base64'),
        content_type: attachment.contentType,
        content_id: contentId || undefined,
      };
    });

    // 4. Forward by sending a new email
    const sendRes = await fetch('https://api.mailblastr.com/emails', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        from: 'Acme <hello@yourdomain.com>',
        to: ['delivered@example.com'],
        subject: email.subject || '(no subject)',
        html: parsed.html || undefined,
        text: parsed.text || undefined,
        attachments: attachments.length > 0 ? attachments : undefined,
      }),
    });

    return NextResponse.json(await sendRes.json());
  }

  return NextResponse.json({});
};
The Node.js example uses `mailparser` (npm install mailparser). In any language, use an RFC 5322-capable parser — the example above uses Python's built-in email package.

Forward style: passthrough vs. wrapped

Re-sending the parsed html/text and attachments reproduces the original message as it arrived — a clean passthrough forward. If you instead want a "forwarded message" footer like an email client, send your own intro html/text and append the original content (and a quoted header block) beneath it:

const footer = `
  <p>See attached forwarded message.</p>
  <hr>
  <p>---------- Forwarded message ----------<br>
     From: ${email.from}<br>
     Subject: ${email.subject}</p>
`;

await fetch('https://api.mailblastr.com/emails', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    from: 'Acme <hello@yourdomain.com>',
    to: ['delivered@example.com'],
    subject: `Fwd: ${email.subject || '(no subject)'}`,
    html: footer + (parsed.html || ''),
    attachments: attachments.length > 0 ? attachments : undefined,
  }),
});
The forwarding from must be an address on a verified sending domain — it is a brand-new outbound send via POST /emails, not a relay of the original envelope.