> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brew.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate From Brevo to Brew

> Move email contacts, templates, segments, and automations from Brevo into Brew, including the API swap and what to do with SMS, WhatsApp, and CRM.

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. This guide covers email.

It assumes your Brew brand and sending domain are set up. If not, [verify your domain](/get-started/verify-your-sending-domain) first. DNS changes can take up to 72 hours.

Brevo's own domain authentication needs fewer records than most platforms: 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.**

<Note>
  Looking to go the other way, designing in Brew and sending from Brevo? See the [Brevo integration](/integrations/export/brevo) instead.
</Note>

## Concepts

| Brevo                                      | Brew                                                             |
| ------------------------------------------ | ---------------------------------------------------------------- |
| Contact                                    | Contact                                                          |
| Attribute (UPPERCASE, such as `FIRSTNAME`) | Custom property (camelCase, such as `firstName`)                 |
| List (static)                              | Custom property plus an Audience filter, see Step 4              |
| Segment (dynamic)                          | [Audience](/audience/create-audiences), with a limit, see Step 4 |
| Campaign (one-time)                        | [Email](/create-emails/emails)                                   |
| Automation / Workflow                      | [Automation](/create-emails/automations)                         |
| Transactional email                        | An automation fired by a trigger event                           |
| Brevo Template Language tag                | Brew merge tag with a fallback, simple cases only                |
| Brevo code, DKIM, DMARC records            | Brew DNS records                                                 |
| Custom Object record                       | No equivalent, flag for manual handling                          |

## 1. Export Contacts From Brevo

<Warning>
  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](/get-started/what-you-can-send).
</Warning>

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.

## 2. Map Your CSV

| Column        | Required                                |
| ------------- | --------------------------------------- |
| `EMAIL`       | Yes, Brevo's primary identifier         |
| Anything else | Becomes a custom property automatically |

Notes:

* Brevo attributes are UPPERCASE by convention, such as `FIRSTNAME` and `LASTNAME`. Brew properties use camelCase, such as `firstName`. Rename columns to match during mapping
* These names are reserved and can't be used for custom properties: `email`, `first_name`, `last_name`, `subscribed`, `created_at`, `updated_at`, `validation_status`, `last_validated_at`, `import_id`

**Personalization.** Brevo has its own templating language, Brevo Template Language. This step needs real judgment, not just a syntax swap.

Simple attribute substitution translates cleanly, into a Brew merge tag with a built-in fallback:

```
{{ contact.FIRSTNAME }}   →   {{ firstName | there }}
```

Everything past that needs a manual rebuild rather than a renamed tag:

* If/else conditional blocks
* For loops that repeat a section of content
* Filters written with a pipe, such as `{{ contact.ATTRIBUTE|filter }}`
* Object variables, used only in automations triggered by a custom object, which has no Brew equivalent

If a template used only the first case, migration is mechanical. If it used any of the rest, budget real time to rebuild the logic.

Values from a trigger payload use the same form, as `{{ orderId }}`. See [merge tags](/create-emails/automations#personalization).

## 3. Import Into Brew

Audience → Add contacts → CSV Upload. Map columns, tick [validation](/audience/validate-contacts) if the list hasn't been checked recently, review, then import.

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](/audience/add-contacts).

## 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.** Brew has one subscription state per contact, subscribed or unsubscribed. There are no opt-in categories and no subscriber-facing preference center. Marketing emails and automations respect that flag, and transactional sends bypass it.

Rebuild each static list as a custom property plus an Audience filtered on it. You keep the targeting, but membership is yours to manage.

Contacts can't pick lists for themselves, and unsubscribing opts them out of all marketing email rather than one list. If a Brevo list carried a real consent distinction, decide how to honor it before your first send.

Brevo segments are dynamic. They filter on conditions like "opened a campaign", "purchased within 30 days", or "abandoned a cart". Contacts enter and exit automatically as they match or stop matching.

Brew Audiences filter on three things: contact properties, subscription status, and email engagement (opens, clicks, and sends). They can't filter on other event data directly. To rebuild a segment based on event or behavior data:

1. Write the derived signal onto the contact as a custom property, using an automation or the API on whatever cadence fits.
2. Build your Brew Audience on that property, not on the raw event.

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

| You have                                           | Use in Brew                                                             |
| -------------------------------------------------- | ----------------------------------------------------------------------- |
| A Brevo email with simple attribute tags           | Screenshot or export, then prompt Brew to rebuild it against your brand |
| A Brevo email with conditionals, loops, or filters | Rebuild by hand. The logic has no direct import path                    |
| A Figma source                                     | Connect with Figma                                                      |

Open **Emails** in the sidebar, then use the **Import** tools on the right side of the canvas. See [Importing existing designs](/create-emails/emails#importing-existing-designs).

Set your [brand identity](/brand/brand-identity) once: logo, colors, fonts, and voice pulled from your site. Every rebuilt template inherits it automatically.

## 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.

| Brevo                                                                       | Brew node                                                                               |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| Trigger (form submitted, email opened, link clicked, list joined, and more) | Integration event, or custom HTTP trigger if the source isn't a native Brew integration |
| Condition / filter                                                          | Filter or Split                                                                         |
| Wait step                                                                   | Wait                                                                                    |
| Campaign (one-time send)                                                    | Email, sent to a Brew Audience                                                          |
| Transactional email                                                         | An automation fired by a trigger event, see Step 7                                      |

Test-fire before publishing, and leave every rebuilt automation unpublished until cutover day. [Build an Automation](/create-emails/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:

```js theme={null}
import { ContactsApi, CreateContact } from "@getbrevo/brevo";

const contactsApi = new ContactsApi();
contactsApi.authentications.apiKey.apiKey = process.env.BREVO_API_KEY;

const contact = new CreateContact();
contact.email = "user@example.com";
contact.attributes = { FIRSTNAME: "Ada", LASTNAME: "Lovelace" };
contact.listIds = [Number(process.env.BREVO_LIST_ID)];
contact.updateEnabled = true;

await contactsApi.createContact(contact);
```

After, with Brew:

```js theme={null}
await fetch('https://brew.new/api/v1/contacts', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.BREW_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: "user@example.com",
    firstName: "Ada",
    lastName: "Lovelace",
  }),
});
```

Brevo's UPPERCASE attributes and numeric list IDs become camelCase properties and Audience membership. Brew's contact endpoint upserts by email, so there's no separate update flag.

**Events and transactional sends.** Brevo has a dedicated Events API for tracking contact interactions, which is what feeds automation triggers. It also has a separate transactional send call. In Brew both become the same thing: fire a trigger event and let the automation decide what to send.

That's worth understanding even if you never sent transactional email through Brevo. A cart-abandonment or trial-ending email is a marketing send fired per recipient by a custom event. It uses this exact mechanism.

Before, with Brevo's Events API:

```js theme={null}
await fetch('https://api.brevo.com/v3/events', {
  method: 'POST',
  headers: {
    'api-key': process.env.BREVO_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    event_name: "trial_started",
    identifiers: { email_id: "user@example.com" },
    event_properties: { plan: "pro" },
  }),
});
```

After, with Brew:

```js theme={null}
await fetch(
  `https://brew.new/api/v1/automations/triggers/${process.env.BREW_TRIAL_STARTED_TRIGGER_ID}/fire`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.BREW_API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': `trial-started-${subscription.id}`,
    },
    body: JSON.stringify({
      payload: { email: "user@example.com", plan: "pro" },
    }),
  },
);
```

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](/api-reference/api/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](/api-reference/api/api-introduction). This section shows the shape of the migration, not a copy-paste replacement for your code.

## 8. Cut Over

1. Warm up your Brew sending domain before any real volume. Send to your most engaged contacts first and ramp over several days. [Gradual send](/create-emails/send-options#gradual-send) does the ramping for you.
2. Rebuild contacts, segments, templates, and automations while Brevo keeps sending normally.
3. Move one message type at a time. A reasonable order is one-off emails first, then automations, then transactional.
4. Give single-recipient, account-critical messages extra care, whichever category they're in. A password reset or a receipt qualifies.
5. Watch each moved type in [analytics](/analytics/reading-analytics) before you move the next.
6. Confirm recreated segments' membership counts before their automations go live. See Step 4.
7. Point signup forms and any tracked events at Brew once everything upstream is verified.
8. Keep SMS, WhatsApp, and CRM on Brevo, or move them to a dedicated provider. Brew doesn't cover these channels.
9. Keep Brevo active but unused for a couple of weeks as a fallback, then downgrade or cancel.

Never leave the same message type live in both places at once.

## Quick Reference

| Task                   | Where in Brew                                      |
| ---------------------- | -------------------------------------------------- |
| Import contacts        | Audience → Add contacts → CSV Upload               |
| Build a segment        | Audience → Create Audience                         |
| Import a template      | Emails → canvas → Import                           |
| Build a flow           | Emails → Automations tab                           |
| Create a trigger event | Trigger events, or `POST /v1/automations/triggers` |
| API keys               | Settings → API                                     |

## 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:

<Tabs>
  <Tab title="Self-Service Tools">
    <CardGroup cols="2">
      <Card title="Search Documentation" icon="magnifying-glass" color="#c44925">
        Type in the "Ask any question" search bar at the top left to instantly find relevant documentation pages.
      </Card>

      <Card title="ChatGPT/Claude Integration" icon="robot" color="#c44925">
        Click "Open in ChatGPT" at the top right of any page to explore it further with ChatGPT or Claude.
      </Card>
    </CardGroup>
  </Tab>

  <Tab title="Talk to Our Team">
    <CardGroup cols="2">
      <Card title="Schedule a Call" icon="calendar" color="#c44925" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ1iYoRUG1J792XQpbuQLjSRRDupr7MwraFK-HQRCtTYdBmrQi8nZu2qXfzKQigb8gbKJK3KN3-R">
        Book time with our founders for personalized guidance on strategy, best practices, or complex implementation questions.
      </Card>

      <Card title="Call Us Directly" icon="phone" color="#c44925">
        Need immediate assistance? Reach us at **+1-(332)-203-2145** for urgent issues or time-sensitive questions.
      </Card>

      <Card title="Slack Channel" icon="slack" color="#c44925">
        Our preferred support channel. You'll receive an invite after signup for direct founder support and fast responses.
      </Card>

      <Card title="Email Support" icon="envelope" color="#c44925" href="mailto:support@brew.new">
        Contact us at **[support@brew.new](mailto:support@brew.new)** for detailed inquiries or if you prefer not to use Slack.
      </Card>
    </CardGroup>
  </Tab>
</Tabs>
