Migration guide

Migrate from Plunk to Volanea.

Plunk and Volanea share a philosophy — one contact graph, per-email pricing, no contact limits — so this is the shortest guide on the site. What you gain: A/B experiments, template versioning, dynamic segments with live preview, and spending caps.

Undecided? Read the honest Volanea vs Plunk comparison first.

01

Create the project and verify your domain

Sign up (free, no card), add your sending domain, and install the DKIM/SPF records Volanea shows you — fresh records, separate from Plunk's. Keep Plunk live for now: nothing gaps while DNS propagates, and verification is one click once it does.

02

Swap the send call

This is the heart of it — one call replaced by one call. Grab your secret key from project settings first.

before — @plunk/node

import Plunk from "@plunk/node";

const plunk = new Plunk(process.env.PLUNK_API_KEY!);

await plunk.emails.send({
  to: "ada@example.com",
  subject: "Your order shipped",
  body: "<p>On its way, Ada.</p>",
});

after — volanea

// npm i @volanea/sdk   (or plain fetch — it's one POST)
import { Volanea } from "@volanea/sdk";

const volanea = new Volanea({ apiKey: process.env.VOLANEA_SECRET_KEY! });

await volanea.send(
  {
    to: "ada@example.com",
    subject: "Your order shipped",
    html: "<p>On its way, {{firstName}}.</p>",
    variables: { firstName: "Ada" },
  },
  { idempotencyKey: "order-4921" }, // retries become safe replays
);
  • body becomes html; everything else you already know.
  • Plunk's track() events map to POST /v1/events — same concept, and Volanea's public key makes it safe to call from client code.
  • Action-based automations rebuild as workflows: event trigger → delay/branch → send.
03

Bring your contacts

Export your list from Plunk as CSV and import it in the Volanea dashboard (or POST /v1/contacts/import). Columns map by header, imports run as a background job with live progress, and re-runs dedupe by email — a partial import is never a disaster. Unsubscribed contacts keep their status, so nobody who opted out gets mailed by mistake.

04

Re-point your webhooks

Register your endpoint in Volanea (the response includes the whsec_… signing secret), then translate the event names your handler listens for:

PlunkVolanea
deliveredemail.delivered
openedemail.opened
clickedemail.clicked
bouncedemail.bounced
complainedemail.complained

Every delivery is HMAC-signed in the X-Volanea-Signature header and retried with backoff for ~24 hours — the docs include a drop-in verifier.

05

Test, then flip

Send through your test key (sk_test_…) first — messages render and log fully but deliver nothing, so you can assert on the whole pipeline in CI. When the domain is verified and the test sends look right, swap in the live key, watch the first real sends land in the dashboard, and retire the Plunk credentials.

06

Watch for the gotchas

  • Export contacts from Plunk as CSV and import — the importer dedupes by email, so a partial re-run is harmless.
  • Re-verify your domain with fresh DKIM/SPF records; keep Plunk live until Volanea's verification is green so sending never gaps.
  • If you self-hosted Plunk, remember Volanea is hosted-only — your data moves to our infrastructure (see the privacy policy for exactly where).

An afternoon, start to finish.