Skip to main content
Brevo is a multichannel platform. It sends email, SMS, and WhatsApp, and it includes a CRM and a sales pipeline. Brew is email only. If you send SMS or WhatsApp through Brevo, keep Brevo for those channels. If you run deals through Brevo’s CRM, keep that too or move it to a dedicated tool. Email moves in full: campaigns, automations, and transactional. In Brew, a transactional email is a trigger plus a one-step automation sending from a transactional-purpose domain. Step 7 covers it. This guide assumes your Brew brand and sending domain are set up. If not, verify your domain first. DNS changes can take up to 72 hours. Brevo’s own domain authentication needs fewer records than most platforms. It uses a Brevo code record, one or two DKIM records depending on your account, and DMARC. Expect Brew’s setup to look different rather than wrong. Rule for the whole migration: only one platform sends live email to a given contact at a time.
Looking to go the other way, designing in Brew and sending from Brevo? See the Brevo integration instead.
Not ready to commit? Leave your Brevo automations 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.
Go to CRM → Contacts. Load a list or segment first if you only want a subset, or leave it blank to export everyone. Select all contacts, click More actions, then Export. Choose the attributes you want, List ID under System data, and subscription status under Subscriptions. Pick a CSV separator, then click Start export. Download the file from your Notifications bell once it finishes. Large databases can take a few minutes. To carry your suppression list over, filter to blocklisted or unsubscribed contacts first. Go to CRM → Contacts → Add filter → Email → Email campaigns subscriptions → Blocklisted. Export that view on its own. Brevo’s transactional unsubscribes are sender-specific by default. A contact who unsubscribed from one transactional sender may still be eligible for transactional email from another. Check this before assuming a contact is fully suppressed. Brevo lists transactional blocks separately, under Settings → Transactional emails → Blocked or Unsubscribed contacts. Keep any opt-in date and source columns in the export. Bring Your Consent Records covers carrying them over.

2. Map Your CSV

Notes:
  • Don’t import a status 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.
  • Brevo attributes are UPPERCASE by convention, such as FIRSTNAME and LASTNAME. Brew properties use camelCase, such as firstName. Rename columns to match during mapping.
  • 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.
For how an import handles empty cells, duplicate rows, and columns Brew manages such as Created At, see Add Contacts. Custom properties can’t use the names of Brew’s built-in contact fields, listed in Custom Properties.

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 credits, which is worth it before warming up a new domain. See Validate Contacts for the cost. Mark blocklisted or unsubscribed contacts as unsubscribed on import so they aren’t re-subscribed by mistake. Brew’s importer never re-subscribes a contact who previously unsubscribed. See Add Contacts. 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. Include any opt-in date, double opt-in confirmation, or signup source your Brevo export carries. 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 date, import over the API instead, with a consent record per contact. See Add Contacts for the consent fields.

4. Rebuild Segmentation

Brevo lists are static. Contacts stay until you remove them by hand or through automation. Static lists don’t have a direct equivalent. Rebuild each one as a custom property plus an Audience filtered on it. To carry over opt-outs from a specific sender, import them into that domain’s list. Brevo segments are dynamic, filtering on conditions like “opened a campaign”, “purchased within 30 days”, or “abandoned a cart”. Email engagement carries over as an Audience filter. A purchase or cart signal needs a custom property first. Lists and Event-Based Segments covers both changes. 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

Open Emails in the sidebar, then use the Import tools on the right side of the canvas. See Importing existing designs. Set your brand identity once: logo, colors, fonts, and voice pulled from your site. Every rebuilt template inherits it automatically.

Translate Merge Tags

Brevo writes templates in Brevo Template Language, which looks like Django templates. Brew renders Liquid. The two look alike, so most templates need a translation pass, not a rebuild. Simple tags are a rename. Contact attributes drop the contact. prefix and use the Brew property name. Values Brevo passed as params come from the trigger payload in Brew:
Conditions, loops, and filters run in Brew too, but some keywords and filter names differ: Loops keep their shape: {% for item in params.items %} becomes {% for item in trigger.items %}. Brevo’s title filter, its time_* filters, and its encryption filters have no direct Liquid match. Rewrite or drop those lines. Declare every payload field the template reads in the trigger’s schema. That includes fields used only inside a condition or a loop. Then test each branch with a test email before you switch sending over. Object variables, used only in Brevo automations triggered by a custom object, have no Brew equivalent.

6. Rebuild Automations

Brevo automations run on triggers, conditions, and actions. A trigger starts the automation, a condition filters who continues, and an action sends a message or updates data. Test-fire before publishing, and leave every rebuilt automation unpublished until cutover day. Build an Automation covers the trigger setup and the test step.

7. Swap the API Calls in Your Code

Brevo uses one API for contacts and transactional sends, authenticated with an api-key header at https://api.brevo.com/v3. Brew also uses one API, authenticated with a bearer key. Contact upsert. Before, with the Brevo SDK:
After, with Brew:
Brevo’s UPPERCASE attributes and numeric list IDs become camelCase properties, and a saved Audience filters on them (Step 4). Brew’s contact endpoint upserts by email, so there’s no separate update flag. A new contact is subscribed by default. Send subscribed: false for anyone who hasn’t opted in, and a consent record for those who have. subscribed: true applies only to a new contact. Brew refuses it for anyone who opted out, and Unsubscribes says how to retry. Events. Brevo has a dedicated Events API for tracking contact interactions, which is what feeds automation triggers. In Brew that becomes a fire call: fire a trigger event and let the automation decide what to send. A cart-abandonment or re-engagement email is a marketing send fired per recipient by a custom event. It uses this exact mechanism. Start its automation with a Filter on your opt-in property, such as contact.marketingOptIn. Send Marketing Only to Contacts Who Opted In shows how to get it onto the contact. Transactional sends become trigger fires too. A smtp/email call for a reset or receipt maps to a trigger plus a one-step automation. Its Send Email node uses a transactional-purpose sending domain, which skips the unsubscribe footer and delivers to unsubscribed contacts. The template data you passed as params becomes the fire’s payload, referenced in the email as {{ trigger.* }}. The fire call is identical to the events example below; only the domain on the automation’s send node differs. Before, with Brevo’s Events API:
After, with Brew:
Derive the Idempotency-Key from something stable about the action, like the subscription id above. A key built from a timestamp changes on every retry, which defeats the point and lets a retry send twice. See Idempotency. Brevo also has an older trackEvent endpoint on a separate domain, in-automate.brevo.com, with its own ma-key header. Older integrations, especially e-commerce ones, may use that instead. The Brew side of the mapping is the same either way. 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 Brevo 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 Brevo’s new unsubscribes and bounces and import them into Brew as Subscribed: false. That stops marketing only. Transactional sends still reach these contacts, so don’t fire transactional triggers for addresses that hard-bounced or complained. Repeat before each type you move, until Brevo 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 Brevo 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. One-off emails first, then automations. For each automation, in order: pause it on Brevo, publish the Brew version, then point its signup forms 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. Resets and receipts 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 Brevo as a fallback. Keep its marketing side active but unused for a couple of weeks, then downgrade to whatever still covers the channels that stay. Keep SMS, WhatsApp, and CRM on Brevo, or move them to a dedicated provider.
Never leave the same message type live in both places at once.

From an Agent or Code

Steps 3 to 5 also run from an AI assistant connected over MCP. Ask in plain English, one step at a time:
“Import subscribed.csv, then unsubscribed.csv, as separate batches, and record the consent source as import.”
“Create an audience of subscribed contacts whose plan is pro, and tell me how many it holds.”
“Import this HTML as an editable email called Newsletter.”
Check each count against the old platform before you move on. From code:
  • Contacts. POST /v1/contacts/import-csv, or brew-cli contacts import-csv --file contacts.csv, once per file. Add Contacts covers limits and the consent record.
  • Segments. POST /v1/audiences with a name and filters, or brew-cli audiences create.
  • Templates. POST /v1/emails/import with the format and content. Import is free and uses no AI.
Step 6’s flows follow Build an Automation.

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.

Ask ChatGPT or Claude

Click here to open the Copy page menu at the top of this page, then send the page to ChatGPT, Claude, or your editor.