# Migrate from Plunk (/migrate/plunk)



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-two-variable-swap]

The request and response bodies are unchanged — only the URL and key move:

```js title="Before (Plunk)"
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>",
  }),
});
```

```js title="After (Sendly)"
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>",
  }),
});
```

## Supported fields [#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": ... }`.

<Callout type="info">
  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](/sdks) or the [API](/api-reference/overview).
</Callout>

## Errors [#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.
