Skip to main content
A cutover, not a sync. Profiles, consent, templates, segments, and flows move once, then nothing stays connected to Klaviyo. The rule behind every step below: only one platform sends live email to a given contact at a time. This guide assumes your Brew brand and sending domain are already set up. If not, verify your domain first. DNS can take up to 72 hours.
Looking to go the other way, designing in Brew and sending from Klaviyo? See the Klaviyo integration instead.
Not ready to commit? Leave your Klaviyo flows running and route one new one-off email through Brew instead. Steps 1 to 5 cover contacts and a template, which is all you need for a single test send.

Concepts

Every marketing recipient must have opted in to hear from you. Importing or syncing contact data into Brew is not permission to email it. See What You Can Send.
Audience → Lists & segments → open the list or segment → Manage list → Export list to CSV. For a segment, the menu says Manage segment → Export segment to CSV. Only Owner, Admin, and Analyst users see the option. To export every profile at once, build a segment that holds all of them, then export it. Large exports take a few minutes. Files from the last 30 days wait under Settings → Other → Downloads. Pick the properties to include. Keep these:
  • Email, first name, last name, and any custom properties you use
  • Email marketing consent, with its consent timestamp
  • Email suppressions
Consent and suppression are separate in Klaviyo. A profile can show Subscribed and still be suppressed, for example after a hard bounce. Export both columns so you can tell. Never subscribed is the one people miss. Klaviyo can still send these profiles some flow emails, such as abandoned cart. But they never agreed to marketing email. Importing them as subscribed means sending marketing to people who never opted in. Leave them out of your marketing audience. Then export the suppression list on its own. Go to Audience → Profiles, click Suppressed Profiles in the upper right, then click Export CSV. It holds hard bounces, repeated soft bounces, and manual suppressions. Import every address on it as Subscribed: false. A contact you leave out can come back later through a form or an integration as a new, subscribed contact. The export doesn’t include list membership or event data. Export each list you still need as its own file, which Step 4 uses. Brew’s engagement-based audiences start counting from your import date. Bring Your Consent Records covers carrying the consent timestamp over.

2. Map Your CSV

Notes:
  • Don’t import the consent column as it is. Brew reads opt-outs only from a Subscribed column, so any other column becomes a plain custom property and those people import as subscribed
  • Klaviyo marks its own properties with a $ prefix on export, such as $consent_method. Rename the ones you keep to plain names, such as consentMethod, and drop the rest
  • New columns become camelCase properties. A Plan Type column becomes planType. Use that name in merge tags and filters
  • Empty cells don’t overwrite existing data on update imports
  • Duplicate rows: the last one wins, so dedupe first
  • These names belong to built-in contact fields and can’t be used for custom properties: email, firstName, lastName, subscribed, createdAt, updatedAt, validationStatus, lastValidatedAt, importId, csvFileName
  • Save as UTF-8. Garbled characters at the mapping step usually mean it wasn’t
  • Dates: day-first dates such as 03/04/2026 (3 April) import correctly when you pick day first at the mapping step, and YYYY-MM-DD needs no choice. See date formats
Full import behavior lives in Add Contacts.

3. Import into Brew

Audience → Add contacts → CSV Upload. Map columns, review, then import. Tick the validation checkbox first if the list hasn’t been checked recently. It costs 2 credits per address, which is worth it before warming up a new domain. Upload the subscribed contacts, the opt-outs, and the suppression list as separate files. That keeps Subscribed set correctly per batch. A contact’s Subscribed status says Brew may email them. A consent record says how and when they agreed. Carry both over.
  • Export the evidence. Klaviyo’s export includes the consent timestamp and $consent_method, which says how the person opted in. Keep those columns as custom properties.
  • In the app, tick the consent checkbox at the review step. Brew records consent once for the whole file, dated the day you import.
  • To keep each person’s original opt-in, import over the API instead. POST /v1/contacts takes a consent record per contact, with the original date as capturedAt. It never changes Subscribed.

4. Rebuild Segmentation

Audiences are dynamic filters over contact properties, email engagement, and subscription status. Describe one in plain English or build the filters by hand. Segments built on what someone has done need a derived property. Klaviyo segments can filter on any tracked metric, such as “Placed Order at least once”. Brew Audiences can’t filter on event history other than email engagement. To rebuild one:
  1. Write the signal onto the contact as a custom property with the API (POST /v1/contacts), such as orderCount.
  2. Build your Brew Audience on that property, not on the raw event.
Klaviyo’s predictive analytics fields export as columns too. They import as plain properties and stop updating on the day you export. Lists don’t have a direct equivalent. Brew has no opt-in categories and no subscriber-facing preference center. Opt-outs work at two levels. Each marketing domain keeps its own unsubscribe list, and Unsubscribe from all covers every marketing domain. See Unsubscribes. Rebuild each list as a custom property plus an Audience filtered on it. Add a column to that list’s export, such as vipList set to true, and import it. Some people chose a list themselves. Decide how to honor that choice before your first send. Before cutover, spot-check that a recreated Audience’s membership count is in the right ballpark against the original segment. A wrong translation can undercount or overcount who gets an email, and that isn’t always visible in the UI.

5. Rebuild Templates and Merge Tags

To get the HTML, go to Content → Templates in Klaviyo. Open the options menu on the right of a template and click Export. In Brew, open Emails in the sidebar, then use the import tools in the toolbar on the right side of the canvas. See Importing existing designs. For most templates, use the HTML or screenshot as reference. Prompt Brew to rebuild it against your brand rather than treating the import as finished. It’s faster, and the result inherits your brand identity automatically. Running a long parallel test instead of a fast cutover? You can design in Brew and still send from Klaviyo. Click Send in the top right, choose Export template, and pick Klaviyo. That pushes the finished email to Klaviyo as a CODE template through the Klaviyo integration. Keep each GIF under 2 MB so it loads fast on a phone.

Translate Merge Tags

Klaviyo uses Django-style tags. Brew runs Liquid, which looks close, so most tags only need new names. Brew property names are camelCase and case-sensitive, and a snake_case name renders empty. If you keep an imported template’s HTML as it is, replace Klaviyo’s tags before you send:
  • {{ first_name|default:'there' }} becomes {{ firstName | there }}. The fallback after the pipe shows for contacts with nothing on file.
  • {{ person.plan }} becomes {{ customer.plan }}, or just {{ plan }}.
  • {{ person|lookup:'Plan Type' }} becomes the camelCase name from your import, {{ planType }}. Liquid has no lookup filter.
  • {{ event.ProductName }} becomes {{ trigger.productName }}, named after the key you send in the fire’s payload. See Step 7.
  • {% if %} and {% for %} blocks keep their shape, but rename the variables inside them. Django’s {% elif %} is {% elsif %} in Liquid.
  • Django filters don’t all exist in Liquid. Check each filter you use against the Liquid templating reference.
  • Delete {% unsubscribe %}, {% manage_preferences %}, and {{ organization.full_address }}. Brew adds the unsubscribe link and your mailing address to every marketing email.

6. Rebuild Automations

Transactional flow emails. Klaviyo marks single emails in metric-triggered flows as transactional after a review. In Brew, the sending domain decides instead. Rebuild each one as a trigger plus a one-step automation on a transactional-purpose domain. See Transactional Email. Test-fire before publishing. Leave every rebuilt automation unpublished until cutover day, which is what prevents a double-send. Build an Automation covers the trigger setup and the test step.

7. Swap the API Calls in Your Code

Klaviyo’s API lives at https://a.klaviyo.com/api. It takes a private key in a Klaviyo-API-Key header, a dated revision header, and JSON:API bodies. Brew uses one host, a bearer key, and plain JSON. Contact upsert. Before, with Klaviyo:
After, with Brew:
Klaviyo’s profile import never changes consent. Subscribing is a second call, POST /api/profile-subscription-bulk-create-jobs. In Brew, one call does both: subscribed: true opts the person in, and the consent record says how. The consent record never changes subscribed. subscribed: true applies only to a new contact. A single upsert that asks for it on an opted-out contact gets 422 RESUBSCRIBE_NOT_ALLOWED, and nothing is written. Handle that 422 by sending the same call without subscribed. Events. A Klaviyo event can start a metric-triggered flow. In Brew that becomes a fire call: fire a trigger event, and every published automation listening for it starts. Before, with Klaviyo:
After, with Brew:
The metric name becomes the trigger you fire. Event properties become the fire’s payload, read in the email as {{ trigger.plan }}. Use plain keys without spaces, so no lookup is needed. Klaviyo’s unique_id becomes the Idempotency-Key header. Keep the same stable value, like the subscription id above, so a repeat fire starts nothing new. See Idempotency. Full request shapes are in the API reference. This section shows the shape of the migration, not a copy-paste replacement for your code.

8. Cut Over

Move in this order:
  1. Rebuild while Klaviyo keeps sending. Import contacts and rebuild segments, templates, and automations. None of it touches live sending. Keep every Brew automation unpublished.
  2. Check your segments. Confirm each recreated Audience’s membership count against the original. See Step 4.
  3. Refresh opt-outs. Right before your first Brew send, export Klaviyo’s new unsubscribes and suppressions and import them into Brew as Subscribed: false. Repeat before each type you move, until Klaviyo stops sending. Anyone who opted out during the rebuild stays opted out.
  4. Warm up with the first type you move. Pause that type on Klaviyo first, so nobody gets it from both. Send to your most engaged contacts first and ramp over several days. Gradual send does the ramping for you. No history means no reputation, even on a verified domain.
  5. Move one type at a time. Campaigns first, then flows. For each flow, in order: set it to Draft on Klaviyo, publish the Brew automation, then point its signup forms, integrations, or tracked events at Brew. Watch each in analytics before you move the next.
  6. Move transactional email last. Before you move any, add a separate transactional-purpose subdomain (see Transactional Email). A fire for a new address creates a subscribed contact, so only send marketing to people who opted in. Order confirmations and resets are the highest-stakes sends. Cut them over one at a time, and test-run each automation with a real payload before you point production code at its trigger.
  7. Keep Klaviyo as a fallback. Leave it active but silent for a couple of weeks, then downgrade or cancel. Keep SMS on Klaviyo, or move it to a dedicated provider.
Never leave the same email type live in both places at once. That’s how a contact gets the same campaign twice.

Quick Reference

Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

Search Documentation

Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.

ChatGPT/Claude Integration

Click “Open in ChatGPT” at the top right of any page to explore it further with ChatGPT or Claude.