Migrating from Klaviyo
A practical, consent-safe path from Klaviyo to Hober: export, transform, import, run both in parallel, then cut over. Written for a marketer with a spreadsheet, not a data engineer.
The one rule that governs everything below: consent state must survive the move exactly. A suppressed profile that arrives as an active subscriber is how migrations destroy sender reputations. Hober's import is built to make the safe path the easy one — opted-out state stored in Hober always survives re-imports.
1. Export from Klaviyo
- Profiles: Lists & Segments → select a list → Manage list → Export list to CSV. Export each list you intend to keep, plus your master list.
- Suppressed profiles: Profiles → Suppressed → export separately. You will not import these as subscribers — see step 3.
- Templates: open each email template → export/copy the HTML. There is no bulk template export on most plans; budget manual time per template.
2. Transform the profile CSV
Hober's importer maps columns by header name. Build this header set:
| Hober column | From Klaviyo | Notes |
|---|---|---|
email | Required — rows without it fail, the rest continue. | |
external_id | your CRM/user ID property | Optional but strongly recommended: it's what unifies imported profiles with SDK and server events later. |
attributes | any properties you keep | A JSON object per row, e.g. {"first_name":"Ana","plan":"pro"}. Invalid JSON is ignored field-by-field, the row still imports. |
consent_type | consent status | express for profiles with explicit opt-in (Klaviyo "subscribed"), implied otherwise. See the semantics below — they are not interchangeable. |
consent_source | e.g. klaviyo_migration | Free-text provenance; name the migration so the ledger reads honestly later. |
consent_timestamp | consent date if exported | RFC 3339 or YYYY-MM-DD. |
Consent semantics that protect you:
expressoverwrites prior consent state — assert it only for profiles with a real, attributable opt-in.impliedonly seeds consent where none exists — a stored opt-out in Hober always survives animpliedre-import. When in doubt, useimplied.- Rows with consent metadata but no
consent_type(or an unknown type) fail validation individually; the import continues.
3. Suppressed profiles: do not import them
Leave Klaviyo's suppressed export out of the subscriber import entirely. Keep the file: it is your audit record. If a suppressed person genuinely re-subscribes later, they come back through a real opt-in path (signup form, preference center) — never through a CSV.
Hober enforces consent and suppression at send time on every channel, so the guardrail catches mistakes — but the clean migration is to never create the subscriber row at all.
4. Import
Dashboard → Subscribers → Lists → Import from CSV (max 50 MB per file; split larger exports). The import runs asynchronously with per-row error reporting: failed rows are named with reasons, successful rows proceed. Import list-by-list to preserve your list structure.
5. Templates
Klaviyo templates are HTML with Django-style variables; Hober email content
uses Liquid merge tags. The HTML body ports
directly; variables need translation (e.g. {{ first_name|default:"there" }}
→ Liquid's {{ first_name | default: "there" }} — similar, not identical).
Paste the ported content into a Hober template, then use preview and a test
send to yourself before anything ships. Validation catches undefined merge
tags before send, not after.
6. Parallel run
Do not flip traffic on day one:
- Week 1–2 — Hober sends to a slice. Route one campaign type (or one engaged segment) through Hober while Klaviyo carries the rest. Follow the domain warm-up guidance if Hober sends from a new subdomain.
- Suppression sync, both directions, manually. Until cutover, export Klaviyo's new unsubscribes weekly and remove them from the affected Hober lists; check Hober's suppression ledger (Deliverability page) before any Klaviyo send to the same audience. This is the tedious part — keep the window short.
- Compare deliverability. Hober's per-channel deliverability dashboard shows delivery/bounce/complaint rates; hold the ramp if bounces exceed 2% or complaints 0.1%.
7. Cutover checklist
- All lists imported; spot-check counts against Klaviyo per list.
- Suppressed export retained (not imported); archived with the migration date.
- Templates ported, previewed, test-sent.
- Journeys/flows rebuilt in Hober and activated with entry conditions verified.
- Domain authentication (SPF/DKIM) green in the channel's deliverability panel.
- Final Klaviyo unsubscribe export applied.
- Klaviyo flows paused before Hober journeys activate on the same triggers (double-send window: zero).
- Klaviyo account left read-only for one billing cycle as the rollback path.
Prefer the built-in preset
The manual transform in step 2 now has a shortcut: in the import dialog,
choose File format → Klaviyo export and upload Klaviyo's CSV as-is. The
importer applies this guide's mapping automatically — Email becomes the
subscriber email, the consent status column translates consent-safely
(subscribed → express with klaviyo_import provenance; unsubscribed and
suppressed rows are skipped, never imported; everything else → implied),
and the remaining columns become snake_cased attributes. Skipped rows appear
in the failed count with their reason, so the numbers stay honest.
Steps 2–3 remain the reference for what the preset does — and the manual path still works when you need custom control.
Migrating from Braze instead?
That path has its own guide and import preset — and Braze templates are already Liquid, so the template step is renames, not syntax translation.