Looking to go the other way, designing in Brew and sending from Klaviyo? See the Klaviyo integration instead.
Concepts
1. Export Contacts, Consent, and Suppression
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
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
Subscribedcolumn, 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 asconsentMethod, and drop the rest - New columns become camelCase properties. A
Plan Typecolumn becomesplanType. 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, andYYYY-MM-DDneeds no choice. See date formats
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 keepsSubscribed set correctly per batch.
Bring Your Consent Records
A contact’sSubscribed 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/contactstakes aconsentrecord per contact, with the original date ascapturedAt. It never changesSubscribed.
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:- Write the signal onto the contact as a custom property with the API (
POST /v1/contacts), such asorderCount. - Build your Brew Audience on that property, not on the raw event.
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 nolookupfilter.{{ event.ProductName }}becomes{{ trigger.productName }}, named after the key you send in the fire’spayload. 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 athttps://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:
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:
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:- Rebuild while Klaviyo keeps sending. Import contacts and rebuild segments, templates, and automations. None of it touches live sending. Keep every Brew automation unpublished.
- Check your segments. Confirm each recreated Audience’s membership count against the original. See Step 4.
- 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. - 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.
- 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.
- 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.
- 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.
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:- Self-Service Tools
- Talk to Our Team
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.