Brevo Data Export and Migration: How to Move Your Data In or Out

Export contacts, statistics and logs from Brevo, learn exactly what does not transfer, and follow a step by step checklist for migrating in either direction.

Brevo data export
Brevo Data Export and Migration?

Search volume for phrases like “brevo data export migration to another platform” is driven by one worry: that the data you have accumulated is easier to put in than to take out. The honest answer for Brevo is that most of it comes out cleanly, some of it comes out in a shape you have to rebuild, and a small but important part of it cannot move at all.

This guide covers both directions. It lists exactly what exports, what does not, the API calls for accounts too large for the interface, and a migration checklist that treats suppression lists and sending reputation as first class concerns rather than afterthoughts.

What you can actually export from Brevo

DataHow it comes outFormat
Contacts and attributesContacts page export, or POST /v3/contacts/exportCSV
List membershipExport per list, or the _listIds metadata fieldCSV
Subscription statusexportSubscriptionStatus on the export jobCSV
Campaign statisticsCampaign report export, or GET /v3/emailCampaignsCSV, PDF, JSON
Transactional event logsGET /v3/smtp/statistics/events or a bulk export jobJSON, CSV
TemplatesGET /v3/smtp/templates returns htmlContentJSON
Companies and dealsExport from the relevant CRM pageCSV

Contacts and attributes

The interface path is CRM, then Contacts. To export the whole database, make sure no list or segment is loaded and no filters are applied. To export one list or segment, click “Load a list or segment” and pick it first.

You then select which standard and custom attributes to include. EMAIL, the last changed date and the creation date are selected by default, and you add the rest yourself, which is the step people most often get wrong. Choose your CSV field separator, semicolon or comma, and optionally turn on “Send export by email” so a download link goes to the account owner’s address. Click “Start export”, then download the file from the notifications bell next to your account name.

Lists and segments

Lists export as membership: run one export per list, or include the _listIds metadata in a single full export and split the file afterwards. GET /v3/contacts/lists gives you the list names, ids and folder ids so you can recreate the structure on the other side.

Segments are different, and this is the first real gap. GET /v3/contacts/segments returns only id, segmentName, categoryName and updatedAt. The filter conditions that define a segment are not exposed. You can export the members of a segment at a point in time, but the rule that produced them has to be read off the screen and rebuilt by hand in the new tool. Screenshot every segment before you cancel the account.

Campaign statistics

From a campaign report you can export the data as CSV, and email and SMS reports also offer a PDF version for sharing or printing. For a full historical pull, GET /v3/emailCampaigns accepts a statistics parameter with values globalStats, linksStats or statsByDomain, and a startDate and endDate pair covering a range of up to two years.

Transactional logs

Two paths, with different windows.

GET /v3/smtp/statistics/events returns individual events filtered by type (delivered, opened, clicks, hardBounces, spam, unsubscribed and others). The date range cannot exceed 90 days, and it defaults to the past 30 days if you pass neither a range nor the days parameter.

For bulk, POST /v3/webhooks/export creates an export job over the past 7 days of raw events, capped at 20 export jobs per 7 day period. It returns a processId, calls your notify URL when finished, and delivers CSV with columns including date, email, event, message-id, reason, sending_ip, subject, tag and template_id. Large volumes arrive as a compressed archive of several CSV files.

The practical consequence: if you want more than 90 days of transactional history, you needed to be exporting it on a schedule all along. Set that job up now, not on the week you decide to leave.

What does not come with you

This is the part most migration guides skip.

  • Automation workflow structures. The API can trigger automations through events, but there is no documented endpoint that reads back a workflow’s branches, delays and conditions. Every workflow is rebuilt manually in the new platform.
  • Segment filter definitions. As above, only the names and the current members are retrievable.
  • Full per contact engagement history. You can export the openers, clickers, non openers, unsubscribers, hard bounces or soft bounces of a specific campaign using the customContactFilter on the export endpoint. What you cannot pull is a single tidy file of “every open and click this contact ever made”, because the raw event endpoints are bounded to 90 days.
  • Template rendering fidelity. htmlContent exports cleanly, but drag and drop blocks, merge tag syntax and unsubscribe link placeholders are platform specific. The HTML you export is a starting point, not a finished template. Budget time to re-test every template in the new editor.
  • Deliverability reputation. Sender reputation lives on the sending IPs and the authenticated domain. New platform, new IP pool, new warm up. Keeping the same domain and DKIM configuration preserves the domain side of reputation, which genuinely helps, but it does not carry the IP side.
  • Form, landing page and tracking identifiers. Signup forms, landing pages and the tracking script all have platform specific ids. Anything embedded on your site has to be swapped, and any analytics tied to those ids breaks at cutover.

Scripted export for large accounts

Above roughly 100,000 contacts the interface export gets slow and awkward, and you want a repeatable job anyway. The contact export endpoint is asynchronous: it accepts a filter, returns a process id, and hands you a CSV when it finishes.

Terminal window
curl --request POST \
--url https://api.brevo.com/v3/contacts/export \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'api-key: YOUR_API_KEY' \
--data '{
"customContactFilter": { "actionForContacts": "allContacts" },
"exportMandatoryAttributes": true,
"exportAttributes": ["FIRSTNAME", "LASTNAME", "SMS", "COUNTRY"],
"exportMetadata": ["_listIds", "ADDED_TIME", "MODIFIED_TIME"],
"exportSubscriptionStatus": ["email_marketing", "sms_marketing"],
"exportDateInUTC": true,
"notifyUrl": "https://example.com/hooks/brevo-export"
}'

A successful call returns HTTP 202 and a body containing a processId. exportMandatoryAttributes defaults to true and covers EMAIL, ADDED_TIME and MODIFIED_TIME, so exportAttributes is where you name your custom fields. Setting exportSubscriptionStatus is what puts the marketing opt in state for email and SMS into the file, and omitting it is the single most common way people produce an export that is useless for a compliant migration.

If you would rather page through records than wait on a job, GET /v3/contacts accepts limit up to 1000 with an offset, plus modifiedSince and createdSince for incremental pulls. Each contact comes back with emailBlacklisted, smsBlacklisted, listIds, listUnsubscribed and consentGroups, which is everything you need to reconstruct consent state.

Watch the rate limits while you script this. Contact endpoints allow 36,000 requests per hour and 10 per second on standard plans, doubled on Professional and Enterprise tiers, while most other endpoints sit at 100 requests per hour. Paging a million contacts at 1000 per page is 1000 requests, comfortably inside the contacts budget, but hammering campaign or template endpoints in a loop is not.

Why your suppression list must migrate first

Move the opt outs before you move anything else.

The legal argument is simple. A contact who unsubscribed withdrew consent from your brand. That withdrawal does not reset because you changed vendors. Under GDPR the record of consent and its withdrawal is your obligation as controller, and under CAN-SPAM an opt out must be honoured within ten business days and stays honoured indefinitely. Losing the list in a migration is not a technical accident, it is a compliance failure with a paper trail pointing at you.

The deliverability argument is worse in practice. Suppressed addresses are disproportionately people who complained, hard bounced, or actively wanted out. Mailing them from a brand new IP with no reputation is the fastest known way to get a fresh sending setup throttled or blocked in its first week. A few thousand recycled spam traps and complainers can undo a month of careful warm up.

So export the suppressed cohorts explicitly rather than hoping they are implied. On the export endpoint, actionForContacts accepts unsubscribed for contacts blocklisted by any means and unsubscribedPerList for contacts opted out of one specific list. Do a separate pass for hardBounces per campaign. On the way in to a new platform, import that file into its suppression list, not into a mailable list.

Brevo handles the reverse case too: it supports importing a list of blocklisted contacts, and the import API takes emailBlacklist and smsBlacklist booleans so an imported file lands as suppressed. Note the asymmetry that Brevo is right to enforce: contacts cannot be un-blocklisted in bulk, because bulk resubscribing someone who asked to be left alone would be illegal. Suppression is easy to add and deliberately hard to remove. Treat that as the correct behaviour, not an obstacle.

Migration checklist, out of Brevo

  1. Audit. Count contacts, lists, segments, active automations, templates and integrations. Write down which integrations write into Brevo, because those are the pipes you will have to re-point.
  2. Export. Contacts with all attributes plus subscription status, one file per list or a single file carrying _listIds, suppression cohorts as separate files, campaign statistics, transactional events for as far back as the 90 day window allows, and template HTML.
  3. Archive what expires. Anything time bounded (raw events, logs) is gone once the window rolls. Store it in your own warehouse or object storage now.
  4. Clean and map. Deduplicate, normalise date and phone formats, and write an explicit column to field mapping for the new platform. This is also the natural moment to drop addresses that have not engaged in a year, which is cheaper than paying to warm up dead weight. Our email list cleaning guide covers the thresholds.
  5. Load suppression first. Import opt outs and hard bounces into the new platform’s suppression list, verify the counts match your export, and only then load mailable contacts.
  6. Warm up. Start with your most engaged segment, increase volume gradually, and watch bounce and complaint rates daily. Our email deliverability guide has the sequence in detail.
  7. Run in parallel. Keep Brevo live and sending your critical transactional mail while the new platform handles a growing share of marketing sends. Do not flip both at once.
  8. Verify. Reconcile contact counts, spot check twenty contacts field by field, confirm suppressed contacts are actually suppressed by attempting a test send, and compare a week of send volume against the old platform.
  9. Cut over and keep a rollback. Change DNS and integration endpoints in a window when someone is watching. Keep the Brevo account alive and paid for at least one full billing cycle after cutover, with the exported files stored outside both platforms. That, and not a vendor promise, is your actual rollback plan.

Migrating into Brevo from another platform

The same checklist runs in reverse, with three Brevo specific notes.

Get a real export from the incumbent. Most platforms will give you contacts and their custom fields as CSV. Ask specifically for the suppression list and the bounce list, which are frequently in a separate export that people forget to request. If you are coming from a per contact pricing model, compare what you will actually pay on the way in with our Brevo pricing guide.

Map fields before you upload. Brevo attributes have types (text, number, date, boolean, category), and a date landing in a text attribute will not be filterable later. Create the attributes with the right types first, then import.

Import through the API for anything sizeable. POST /v3/contacts/import accepts inline CSV in fileBody, a JSON array in jsonBody, both capped around 10 MB, or a remote file through fileUrl, plus listIds or a newList object. updateExistingContacts defaults to true and matches on email. Run one import with emailBlacklist set to true for your suppression file, then a second import for mailable contacts. The full working scripts are in our guide to importing CSV contacts to Brevo with a script.

Then rebuild what did not transfer: automations, segments, forms and templates. Send a seed test to a handful of inbox providers before you send to anyone real.

Do not let the next migration be a cliff

The reason a platform migration feels like a cliff is that the platform has become the system of record. Order history, subscriber state and campaign results live inside one vendor, and moving them means an evacuation.

The alternative is to keep your own source of truth and let the sending platform be a destination rather than a vault. If your store data, consent state and engagement events are synchronised continuously into your own systems, switching or adding a channel is a configuration change instead of a project. That is the job Tajo does between Brevo and a merchant’s stack: keep the data flowing both ways so the platform is never the only copy.

Either way, the export jobs described above are worth running on a schedule right now, whether or not you plan to leave. The cheapest migration is the one where the data is already outside the platform when you decide.

Frequently Asked Questions

Can I export all my data from Brevo?
You can export contacts and their attributes as CSV, campaign reports as CSV or PDF, transactional event logs as CSV, and template HTML through the API. Automation workflow structures and segment filter definitions have no export path, so those are rebuilt by hand.
How do I export contacts from Brevo?
Go to CRM, then Contacts. To export everything, make sure no list, segment or filter is loaded. To export one list or segment, click Load a list or segment first. Pick the attributes you want, choose a comma or semicolon separator, then click Start export and download the file from the notifications bell.
What format does Brevo export contacts in?
CSV. You choose the field separator, either a semicolon or a comma. The API export endpoint also delivers a CSV file, and transactional event exports arrive as CSV, compressed into an archive of multiple CSV files when the volume is large.
Does my engagement history come with me when I leave Brevo?
Only partly. Campaign level statistics export as reports, and you can export the openers, clickers, bouncers or unsubscribers of a specific campaign. Raw transactional event logs are limited to a 90 day window through the event report endpoint and 7 days through the bulk export job, so long term per contact history has to be archived before you leave.
Do I have to migrate my unsubscribe list?
Yes. Contacts who opted out of your mail did so with you, not with Brevo, so the suppression obligation follows your brand to the new platform. Mailing them again is both a legal exposure under GDPR and CAN-SPAM and the fastest way to trigger spam complaints on a fresh sending domain.
Can I keep my sender reputation when I switch platforms?
No. Reputation attaches to the sending IPs and the authenticated domain, not to your account. If the new platform uses different IPs, you start a fresh warm up. Keeping the same domain and DKIM selector preserves domain reputation, which helps, but shared IP pools reset the IP side entirely.
How long does a Brevo migration take?
The export and import themselves usually take under a day for accounts below a few hundred thousand contacts. The realistic timeline is two to six weeks, because that is how long a sending warm up and a parallel run of your key automations take before you can safely cut over.
Is there an API for exporting Brevo contacts?
Yes. POST /v3/contacts/export starts an asynchronous job, returns a processId, and delivers a CSV. You can also page through GET /v3/contacts at up to 1000 records per request, which is easier to script against but slower for very large databases.
Can I import my blocklist into Brevo?
Yes. Brevo supports importing a list of blocklisted contacts, and the import API accepts emailBlacklist and smsBlacklist flags so an imported file lands as suppressed rather than mailable. Do this before you import your mailable contacts.

Request early access

Share your first name and an email address or phone number. We will follow up with Tajo access details.

automatic detection
Get Brevo