Skip to content

Switch from Mailjet

Replace Mailjet's transactional send API with Tinbox while keeping node-mailjet for v3.1 Messages sends.

Tinbox can replace the API side of a Mailjet transactional integration when your app uses node-mailjet and the v3.1 send resource with Messages[].

The smallest migration is to keep node-mailjet, use the Tinbox key as the basic-auth secret, and change one config.host line. That lets you test-drive Tinbox without removing Mailjet dependencies or rewriting Messages[] payloads.

What changes

Mailjet project settingTinbox replacement
MJ_APIKEY_PUBLIC / MJ_APIKEY_PRIVATEAny username plus TINBOX_API_KEY=tbx_... as the secret
api.mailjet.com<your-tinbox-host>/api/send/compat/mailjet
Mailjet message dashboardTinbox send ledger and delivery events
Mailjet sender/domain verificationTinbox sending domain verification

One-line test drive

Keep your existing mailjet.post("send", { version: "v3.1" }).request(...) calls. Change the constructor host:

config: { host: "mail.yourdomain.com/api/send/compat/mailjet", version: "v3.1" }

Then use a Tinbox tbx_... key as the API secret. Tinbox receives the Mailjet-shaped Messages[] request.

Inventory your Mailjet usage

rg "from ['\"]node-mailjet['\"]|Mailjet\\(|\\.post\\(['\"]send['\"]|Messages:"
rg "TemplateID|Variables|InlinedAttachments|SandboxMode|EventPayload|CustomID"
UsageMigration path
post("send", { version: "v3.1" }).request({ Messages })Keep the Mailjet SDK
Multiple Messages[]Maps to Tinbox batch sends
From, To, Cc, Bcc, ReplyTo, Subject, HTMLPart, TextPartSupported
Attachments[] with Base64ContentSupported
TemplateID, Variables, TemplateLanguageRender before calling Tinbox
InlinedAttachments, EventPayload, sandbox modeNot drop-in; warn or migrate separately

Configure the SDK

TINBOX_HOST=mail.yourdomain.com
TINBOX_API_KEY=tbx_...
import Mailjet from "node-mailjet";

const mailjet = new Mailjet({
  apiKey: "tinbox",
  apiSecret: process.env.TINBOX_API_KEY!,
  config: {
    host: `${process.env.TINBOX_HOST}/api/send/compat/mailjet`,
    version: "v3.1",
  },
});

await mailjet.post("send", { version: "v3.1" }).request({
  Messages: [
    {
      From: { Email: "hello@yourdomain.com", Name: "Acme" },
      To: [{ Email: "ada@example.com", Name: "Ada" }],
      Cc: [{ Email: "billing@example.com" }],
      Bcc: [{ Email: "audit@example.com" }],
      ReplyTo: { Email: "support@yourdomain.com" },
      Subject: "Your receipt",
      HTMLPart: "&#x3C;p>Thanks.&#x3C;/p>",
      TextPart: "Thanks.",
      Headers: { "X-Receipt-ID": "receipt-4821" },
      CustomID: "receipt-4821",
      Attachments: [
        {
          Filename: "receipt.txt",
          ContentType: "text/plain",
          Base64Content: Buffer.from("receipt").toString("base64"),
        },
      ],
    },
  ],
});

The SDK posts to:

POST /api/send/compat/mailjet/v3.1/send

Tinbox also exposes the vendor-style alias POST /v3.1/send.

Field mapping

Mailjet fieldTinbox supportNotes
Messages[]YesEach message becomes a Tinbox send.
From, To, Cc, BccYesMailjet address objects are accepted.
ReplyToYesMaps to Tinbox reply-to.
SubjectYesPer message.
HTMLPart, TextPartYesAt least one body part is required.
HeadersPartialCustom X-* headers only.
AttachmentsYesBase64Content is required.
CustomIDPartialUseful as correlation/idempotency metadata.
TemplateID, Variables, TemplateLanguageNoRender templates before send.
InlinedAttachmentsNoInline CID attachments are not drop-in yet.
SandboxMode, EventPayload, MonitoringCategoryWarningAccepted only as compatibility metadata.

Warnings and failures

Template expectations fail with 422 when Tinbox cannot safely honor them. Lower-risk Mailjet-only analytics and sandbox fields return X-Tinbox-Compat-Warnings while keeping a Mailjet-shaped response.

Tinbox-native path

import { Tinbox } from "tinbox/sdk";

const tinbox = new Tinbox({
  host: `https://${process.env.TINBOX_HOST}`,
  apiKey: process.env.TINBOX_API_KEY!,
});

await tinbox.emails.batch([
  {
    from: "Acme &#x3C;hello@yourdomain.com>",
    to: "ada@example.com",
    subject: "Your receipt",
    html: "&#x3C;p>Thanks.&#x3C;/p>",
    idempotencyKey: "receipt-4821",
  },
]);

Cutover checklist

  1. Verify the Tinbox sending domain.
  2. Create a Tinbox sending key scoped to the Mailjet From address.
  3. Point node-mailjet config.host at /api/send/compat/mailjet.
  4. Send one single-message smoke test and one multi-message smoke test.
  5. Replace Mailjet templates and event payload assumptions with app-side rendering and Tinbox events.

Source note

This guide is validated against node-mailjet v6.0.11. The SDK mirror test records the exact method, path, basic-auth style, content type, and JSON body emitted by the official package.