Migrate from Mailgun
Point the Mailgun SDK (mailgun.js) at Sendly with a URL override and a Sendly key
Sendly implements Mailgun's POST /v3/<domain>/messages. Keep the official
mailgun.js SDK — change the URL and the API key.
- Base URL:
https://api.sendly.now/api/compat/mailgun(the SDK appends/v3/<domain>/messages) - Auth: HTTP Basic
api:<sk_...>— Mailgun's basic-auth style, where the username is the literalapiand the password is your key. Use a Sendly secret key as the key.
Mailgun does not publish an official Python SDK. Python senders can call the compat
endpoint over plain HTTP (multipart/form-data) or use the Sendly Python SDK.
The two-variable swap
import formData from "form-data";
import Mailgun from "mailgun.js";
const mailgun = new Mailgun(formData);
const mg = mailgun.client({ username: "api", key: "your-mailgun-key" });
await mg.messages.create("yourdomain.com", {
from: "you@yourdomain.com",
to: "customer@example.com",
subject: "Hello",
html: "<p>Welcome aboard.</p>",
});import formData from "form-data";
import Mailgun from "mailgun.js";
const mailgun = new Mailgun(formData);
const mg = mailgun.client({
username: "api",
key: "sk_your_sendly_key",
url: "https://api.sendly.now/api/compat/mailgun",
});
await mg.messages.create("yourdomain.com", {
from: "you@yourdomain.com",
to: "customer@example.com",
subject: "Hello",
html: "<p>Welcome aboard.</p>",
});The domain in the URL path (yourdomain.com above) must match the domain of your
from address. A mismatch returns a 400 in Mailgun's error shape.
API reference
The one operation this dialect covers, with its full request and response schema:
Supported fields
| Field | Support | Notes |
|---|---|---|
from | Full | Must be on a verified domain that matches the URL path. |
to | Full | Repeatable, as Mailgun sends it. |
cc / bcc | Full | |
subject | Full | |
html / text | Full | html is preferred when both are present. At least one is required. |
h:X-* headers | Full | The h: prefix is stripped. |
o:tag | Partial | Repeatable; mapped to Sendly tags (sanitized). |
attachment | Full | File parts are read and attached. |
Success comes back in Mailgun's shape:
{ "id": "<id@domain>", "message": "Queued. Thank you." }.
Not supported
Mailgun options beyond o:tag — scheduled delivery (o:deliverytime), tracking toggles,
and stored templates — are not applied; only the fields in the table above are
honored. Auth, validation, and domain-match failures return Mailgun's bare
{ "message": ... } error body with the matching status (a bad key is 401), so
mailgun.js's own error handling (error.status / error.details) fires as it does
today.