Migrate from Plunk
Plunk is Sendly's ancestral API — a near drop-in for existing Plunk senders
Plunk's transactional send is Sendly's ancestral shape, so POST /v1/send is a
near passthrough. Change the base URL and the API key and your existing Plunk
send calls keep working.
- Endpoint:
https://api.sendly.now/api/compat/plunk/v1/send - Auth:
Authorization: Bearer <sk_...>
The two-variable swap
The request and response bodies are unchanged — only the URL and key move:
await fetch("https://api.useplunk.com/v1/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer your-plunk-secret-key",
},
body: JSON.stringify({
to: "customer@example.com",
subject: "Hello",
body: "<p>Welcome aboard.</p>",
}),
});await fetch("https://api.sendly.now/api/compat/plunk/v1/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer sk_your_sendly_key",
},
body: JSON.stringify({
to: "customer@example.com",
subject: "Hello",
body: "<p>Welcome aboard.</p>",
}),
});API reference
The one operation this dialect covers, with its full request and response schema:
Supported fields
| Field | Support | Notes |
|---|---|---|
to | Full | String or array. |
subject | Full | |
body | Full | HTML or plain text. |
Idempotency-Key header | Full | 1–255 characters; safely retries a send. |
The response mirrors Plunk's native shape:
{ "success": true, "emails": [...], "timestamp": ... }.
Because Plunk and Sendly share this send shape, most Plunk integrations migrate with only the URL and key change. For everything beyond transactional sending, use the official Sendly SDKs or the API.
Errors
Failures come back in Plunk's { code, error, message, time } shape with the matching
status, so a client reading body.message or body.error behaves unchanged.