Mailjet Bridge
Drop-in replacement for the Mailjet Send API (v3.1 and legacy v3) — keep Basic auth and your existing request structure, swap in your wemail API key.
The Mailjet bridge lets you migrate from Mailjet to wemail without changing your integration code. Point your base URL to https://api.wemail.io/bridge/mailjet, keep HTTP Basic auth with your wemail API key in the password slot, and keep the same request bodies and response shapes — both the modern v3.1 Messages array and the legacy v3 send format are supported.
Authentication
Mailjet uses HTTP Basic auth with an API key and secret pair. The bridge accepts any username and reads your wemail API key (afn_live_… or afn_test_…) from the password slot — so api:afn_live_YOUR_KEY works with every Mailjet SDK. Test-environment keys route through the sandbox: messages are accepted, simulated, and never delivered.
Authorization: Basic base64("api:afn_live_YOUR_WEMAIL_KEY")Supported Endpoints
POST /bridge/mailjet/v3.1/send
Send messages (modern batched format) — mirrors Mailjet Send API v3.1.
POST /bridge/mailjet/v3/send
Send a message (legacy format) — mirrors Mailjet Send API v3.
GET /bridge/mailjet/v3/REST/message
List messages — mirrors Mailjet's message resource.
Field-Level Compatibility
POST /v3.1/send — Request Fields
| Parameter | Type | Required | Description |
|---|---|---|---|
From | object | Required | { Email, Name? } — must use a domain verified in your wemail workspace. |
To / Cc / Bcc | array | Required | Recipient lists [{ Email, Name? }] (To required). |
Subject | string | Optional | Required unless TemplateID is provided. |
HTMLPart / TextPart | string | Optional | Body parts. At least one of HTMLPart, TextPart, TemplateID is required. |
TemplateID | string | Optional | A wemail template id (tpl_…). Numeric Mailjet template ids are not resolvable — re-point to the migrated template's wemail id. |
Variables | object | Optional | Template variables, substituted like Mailjet Variables. |
Headers | object | Optional | Custom SMTP headers. |
CustomID / EventPayload | string | Optional | Echoed back on webhook events as CustomID / Payload, exactly like Mailjet. |
Response
Returns 200 with { Messages: [{ Status, CustomID, To: [{ Email, MessageUUID, MessageID, MessageHref }] }] }. Per-message validation failures appear as Status: "error" entries with Errors[], matching Mailjet's partial-failure semantics. The legacy v3 endpoint returns { Sent: [{ Email, MessageID }] }.
GET /v3/REST/message
| Parameter | Type | Required | Description |
|---|---|---|---|
Limit | integer | Optional | Page size, default 10, max 1000. |
Offset | integer | Optional | Pagination offset, default 0. |
Returns { Count, Data: [{ ID, UUID, Status, Subject, From, To, ArrivedAt, CreatedAt, … }], Total } with wemail statuses mapped to Mailjet vocabulary (queued, sent, bounced, spam, blocked).
Webhooks
When the Mailjet bridge is active, webhook deliveries are formatted exactly like Mailjet event callbacks: a JSON ARRAY of flat event objects with event, time, MessageID, Message_GUID, email, CustomID, Payload, plus event-specific fields (url/ip/agent on clicks, hard_bounce/error on bounces). Event names use Mailjet's vocabulary (sent, open, click, bounce, spam, blocked, unsub) — note that like Mailjet, sent means DELIVERED. Payloads are not signed.
Known Deviations from Mailjet API
| Parameter | Type | Required | Description |
|---|---|---|---|
TemplateID | behavior | Optional | Numeric Mailjet template ids are not resolvable; use the wemail tpl_… id of the migrated template. TemplateLanguage interpolation runs through wemail variables. |
MessageID | behavior | Optional | Numeric ids are deterministic hashes of the wemail message id; MessageUUID/Message_GUID carry the real wemail id. |
Attachments | unsupported | Optional | Not yet supported through the bridge; use the native wemail /v3/send for attachments. |
SandboxMode | behavior | Optional | Use a wemail test key (afn_test_…) instead of Mailjet's SandboxMode flag. |
Migrating for good? Follow the Mailjet migration guide — templates and suppressions auto-import, and Mailjet stays warm for 30 days.
Code examples
curl -X POST https://api.wemail.io/bridge/mailjet/v3.1/send \
-u "api:afn_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"Messages": [{
"From": { "Email": "sender@yourdomain.com", "Name": "Your App" },
"To": [{ "Email": "user@example.com" }],
"Subject": "Hello from the Mailjet bridge",
"HTMLPart": "<p>It works — zero code changes.</p>"
}]
}'// Mailjet SDK — point the client at the wemail bridge
const Mailjet = require('node-mailjet');
const mailjet = Mailjet.apiConnect('api', 'afn_live_YOUR_KEY', {
config: { host: 'bridge.wemail.io/mailjet', version: 'v3.1' },
});
await mailjet.post('send', { version: 'v3.1' }).request({
Messages: [{
From: { Email: 'sender@yourdomain.com', Name: 'Your App' },
To: [{ Email: 'user@example.com' }],
Subject: 'Hello from the Mailjet bridge',
HTMLPart: '<p>It works — zero code changes.</p>',
}],
});import requests
resp = requests.post(
"https://api.wemail.io/bridge/mailjet/v3.1/send",
auth=("api", "afn_live_YOUR_KEY"),
json={
"Messages": [{
"From": {"Email": "sender@yourdomain.com", "Name": "Your App"},
"To": [{"Email": "user@example.com"}],
"Subject": "Hello from the Mailjet bridge",
"HTMLPart": "<p>It works — zero code changes.</p>",
}]
},
)
print(resp.status_code, resp.json()) # 200 {'Messages': [{'Status': 'success', ...}]}