Skip to main content

Migration from Klaviyo to Orbit

Klaviyo ships an email/SMS marketing product with a customer-profile store: profiles with custom properties, static lists, rule-based segments, an event stream (Placed Order, Viewed Product), flow automations, campaigns, and metric-driven attribution. Orbit ships the same building blocks natively — a CDP contact and event layer, segments, blast/drip/journey campaigns, and conversion-goal attribution — next to the messaging channels themselves. This guide maps every Klaviyo concept onto its Orbit equivalent and walks the manual, code-level migration. The migration proceeds incrementally — Klaviyo keeps running until you redirect your own integration, and Orbit never sends messages through Klaviyo.

Concept mapping


Prefer the wizard?

The Settings → Import → Klaviyo wizard ports your account’s configuration — lists, segments, templates, flows, and profiles — with a read-only private API key (pk_…). It dry-runs counts and known conflicts before anything is written, runs server-side, and wipes the key when the job finishes. The full walkthrough is the assisted import wizard guide. The rest of this page covers the manual, code-level migration for teams who want control over each step.

Step 1: Create your Orbit account

  1. Sign up at orbit.devotel.io/signup
  2. Generate an API key at Settings → API Keys
  3. Note your key prefix: dv_live_sk_xxxx
Authenticate every request with the X-API-Key header. Keep both the Klaviyo pk_… key and the Orbit key server-side — browser code must never carry either.

Step 2: Export profiles and events from Klaviyo

Read profiles with GET /api/profiles and events with GET /api/events against Klaviyo’s REST API, authenticated with your pk_… key. Paginate with the page[cursor] links Klaviyo returns, and collect email, phone_number, and every custom property you rely on per profile. For events, filter by metric name (Placed Order, Viewed Product, custom metrics) and capture the event timestamp plus the profile it belongs to — you need both to rebuild attribution on Orbit.

Step 3: Ingest profiles and events into the CDP

Create the contact first, then post its events against the contact id. Batch this loop: create-or-update contacts, then walk the exported events and post each one. Worked curl — profile ingest (contact upsert):
Worked curl — event ingest (CDP event stream):
Name events in snake_case and keep the name byte-for-byte stable — a conversion goal later matches the exact string, so placed_order and Placed Order are different events. Verify ingest on the CDP event debugger live tail before you run the full backfill.

Step 4: Rebuild segments as CDP segments

Static lists become static lists directly. Rule-based segments are re-built as CDP segments with the definition preserved — membership re-evaluates from your ingested CDP data rather than a frozen export. Walk each Klaviyo segment’s filter (metric counts, property predicates, list membership) and re-express it against the CDP contact and event fields you ingested in Step 3. The workspace for this is CDP segments. If you want a preview of how much of the export maps cleanly, run it through the CDP segment migration calculator first.

Step 5: Convert flows into campaign journeys

Klaviyo flows (welcome series, abandoned cart, win-back) map onto campaign journeys: a trigger enrolls contacts one at a time, and a graph of messages, waits, and branches walks them through. Create the campaign as type: "journey" and author the graph on the journey canvas — the builder and the API write the same variables.journeyDefinition. Worked curl — journey campaign creation:
Then draw the graph on the canvas (or PATCH the campaign’s variables.journeyDefinition) with a trigger whose event name matches the one you ingested in Step 3 — e.g. enrollment on placed_order for a post-purchase flow, or on your signup event for the welcome series. Inbound conversational automations (chat-style flows over your inbound messages) are Flows, not journeys — the build your first flow guide covers that canvas. For full journey mechanics (validation gates, simulator, per-node analytics) see build, simulate, and launch a campaign journey.

Step 6: Re-create suppression and opt-out handling

Do not carry suppression as a segment filter — rebuild it as a real suppression surface so every channel honors it:
  • Import Klaviyo’s suppressed/unsubscribed profiles into opt-out lists, and route your sending through message suppression so blast, drip, and journey sends all refuse suppressed contacts.
  • Map Klaviyo’s per-channel unsubscribe flags to the matching Orbit opt-out list per channel instead of one global flag.
Suppressions on Klaviyo stop applying the day you switch sends to Orbit, so treat this as a launch gate, not a cleanup task.

Step 7: Re-map attribution from Klaviyo metrics to conversion goals

Klaviyo attributes revenue to the metric a campaign drove (Placed Order within X days). On Orbit you create a Custom event conversion goal named for the event you ingested (e.g. placed_order), set the lookback window, and pick the model — first-touch, last-touch, or linear. The goal then joins conversions back to the campaign each contact most recently touched. The full walk is conversion goals and attribution; the derived revenue view per campaign is ROAS and revenue attribution. Re-build every metric you report on before cut-over so the numbers you compare against Klaviyo exist on Orbit day one.

Step 8: Dual-send cut-over and rollback

Run Klaviyo and Orbit in parallel and shift traffic by cohort:
  1. Phase 1 — dry run. Orbit campaigns send to an internal test segment only; Klaviyo serves all production traffic.
  2. Phase 2 — split. Route a small production cohort (10%) through Orbit, the rest through Klaviyo; compare delivery, engagement, and attributed conversions against the same metrics on both sides.
  3. Phase 3 — full send. Move all production traffic to Orbit once the numbers hold.
Rollback. If phase 2 or 3 regresses, revert your integration layer back to Klaviyo — the import wizard’s dry-run never touched your Klaviyo data, and a wizard-run import can be rolled back from the import history surface. Keep the Klaviyo pk_… key alive until parity is confirmed; release it from your secret store after decommission.

Migration checklist

  • Create Orbit account and generate an API key
  • Run the Import → Klaviyo wizard, or export profiles/events manually
  • Ingest profiles, then backfill events into the CDP event stream
  • Rebuild segments as CDP segments
  • Convert flows into journey campaigns (or Flows for inbound)
  • Re-create suppression via opt-out lists + message suppression
  • Re-map metrics to conversion goals
  • Port sending numbers (SMS) or register senders — see port numbers
  • Dual-send 10%, compare, cut over 100%
  • Decommission Klaviyo and release the pk_… key
Need help? Our solutions team offers free migration support for customers moving from Klaviyo. Contact migrate@devotel.io.