# Migracja z Brevo

Ta strona mapuje payload wysyłki transakcyjnej Brevo, listy blokad i webhooki na Bird. Wykonuj [główny przewodnik migracji](/docs/guides/email/migrate) po kolei i użyj tych mapowań do kroków 1, 3 i 4.

Brevo przechowuje supresje w dwóch niezależnych miejscach, jednym dla poczty transakcyjnej i jednym dla marketingowej. Przeczytaj [Eksport supresji](#eksport-supresji), zanim zaplanujesz krok 3: wyeksportowanie jednej listy bez drugiej to błąd, do którego ta migracja zachęca.

## Przekaż to swojemu agentowi

Wklej to do Claude Code, Cursor lub Codex. Agent przechodzi przez tę stronę w kontekście Twojego repozytorium, korzystając z dowolnego interfejsu Bird, który już ma: serwera MCP, jeśli jest podłączony, lub CLI, jeśli jest zainstalowany i zalogowany.

```text
I am moving an email integration from Brevo to Bird. Route through it with me.
1. Check what you already have before setting anything up. If Bird's MCP server is connected, use its tools. If the Bird CLI is installed and signed in, use that. Either one is enough, and every step below is an action you take with whichever you have. Only if neither is present, follow https://bird.com/docs/ai/set-up-your-agent.md to set one up and sign me in. Every Bird docs page serves Markdown at its own URL with `.md` appended, so fetch that rather than the HTML.
2. Read https://bird.com/docs/guides/email/migrate/brevo.md for the payload, suppression and webhook mapping, and https://bird.com/docs/guides/email/migrate.md for the order the steps go in.
3. Find and list my Brevo usage in this repository before you change anything: calls to /v3/smtp/email and any SDK wrappers around them, whether I send with templateId or with htmlContent, the webhook handler and the URL it is registered at, and every domain I send from. Tell me the list before you edit anything.
4. Register each of those sending domains with Bird and give me the DNS records to publish, following https://bird.com/docs/guides/email/sending-domains.md. Leave every DNS record Brevo uses exactly as it is: Bird's records are published alongside them and both providers authenticate side by side until I switch traffic. Publishing DNS affects mail for the whole domain, so show me the records and let me publish them.
5. Export my suppressions and import them into Bird before any production traffic goes through Bird, so my first sends do not reach addresses that already bounced or complained. Brevo holds these in two separate places and I need both: GET /v3/smtp/blockedContacts for transactional blocks and unsubscribes, and the marketing blocklist, which lives on the contact records as emailBlacklisted rather than on a suppression endpoint. Page through both. The Bird import takes one address per request and is idempotent, so a partial re-run is safe. https://bird.com/docs/guides/email/suppressions.md has the reason taxonomy.
6. Port the send call and the webhook handler using the mapping tables on the provider page. Brevo's webhook security page documents credentials I configure on the endpoint rather than a payload signature, so check what my endpoint actually relies on today: if it is a username and password in the webhook URL, take them out and tell me to rotate that pair rather than reusing it, because a credential that has lived in a URL should be treated as exposed. Bird signs every delivery instead. https://bird.com/docs/guides/webhooks.md and https://bird.com/docs/guides/email/events.md.
7. Run my whole integration against Bird's mail sandbox before any production traffic, following https://bird.com/docs/guides/email/testing-sandbox.md. Sandbox sends run the real pipeline without reaching an inbox or touching my sending reputation.
8. Stop and ask me wherever a step needs a decision. Do not point production traffic at Bird until I have seen the sandbox results and replied with the words cut over to Bird. Retiring the Brevo path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Brevo path. A reply that agrees without naming what it is authorising is not authorisation. Finish by telling me what is left that only a person can do.
```

## Zamapuj wywołanie wysyłki

`POST /v3/smtp/email` Brevo i nasze [`POST /v1/email/messages`](/docs/api/reference/create-email-message) mają zbliżoną strukturę. Większość pracy polega na rozpakowaniu obiektów adresowych Brevo do zwykłych stringów.

| Co robi              | Brevo                                         | Bird                                                                 |
| -------------------- | --------------------------------------------- | -------------------------------------------------------------------- |
| Autoryzacja          | Nagłówek `api-key`                            | `Authorization: Bearer`                                              |
| Nadawca              | `sender` (`{email, name}`)                    | `from`                                                               |
| Odbiorcy             | `to` / `cc` / `bcc` (tablice `{email, name}`) | `to` / `cc` / `bcc` (tablice adresów)                                |
| Temat                | `subject`                                     | `subject`                                                            |
| Treść                | `htmlContent` / `textContent`                 | `html` / `text` (co najmniej jedno)                                  |
| Reply-to             | `replyTo` (`{email, name}`)                   | `reply_to` (tablica)                                                 |
| Własne nagłówki      | `headers` (klucze w Title-Case)               | `headers` (obiekt string → string)                                   |
| Filtrowalne etykiety | `tags` (tablica stringów)                     | `tags`: pary `{name, value}`                                         |
| Zapisany szablon     | `templateId` + `params`                       | `template` + `template.parameters`                                   |
| Załączniki           | `attachment` (`url` lub base64 `content`)     | `attachments` (tylko base64, patrz niżej)                            |
| Planowanie           | `scheduledAt`                                 | `scheduled_at`                                                       |
| Uchwyt wsadowy       | `batchId`                                     | (brak odpowiednika, patrz niżej)                                     |
| Kopia per odbiorca   | `messageVersions`                             | jedna wysyłka na wersję lub [batch](/docs/guides/email/sending-bulk) |
| Kategoria            | (brak)                                        | `category`: `marketing` (domyślnie) lub `transactional`              |

Limity pól i wartości domyślne (liczba odbiorców, limity tagów i metadanych) znajdziesz w [Wysyłanie e-maili](/docs/guides/email/sending-email).

Uwagi dotyczące portowania:

- **Adresy tam są obiektami, a tutaj stringami.** `{"email": "a@x.com", "name": "A"}` staje się `"A <a@x.com>"` lub po prostu `"a@x.com"`. To samo rozpakowanie dotyczy `sender` i `replyTo`.
- **`tags` to zwykłe stringi. Nasze tagi to pary.** Tag taki jak `"welcome"` staje się `{"name": "category", "value": "welcome"}`. Wybierz stabilny `name`, żeby Twoje dashboardy filtrowały tak samo jak statystyki tagów w Brevo.
- **`params` to dane szablonu, a nie kontekst dwukierunkowy.** Staje się `template.parameters`. Jeśli używałeś go też do przekazywania własnych identyfikatorów do zdarzeń, przenieś je do [`metadata`](/docs/guides/email/sending-email), które zwracamy w każdym zdarzeniu webhookowym wraz z `email_id`/`recipient_id`.
- **`messageVersions` nie ma odpowiednika w jednym wywołaniu.** Każda wersja to odrębny zestaw odbiorców i payload, więc staje się albo osobną wysyłką, albo jednym wpisem w [batchu](/docs/guides/email/sending-bulk).
- **`batchId` nie ma odpowiednika.** `batchId` w Brevo grupuje zaplanowane wiadomości, żebyś mógł je anulować lub przełożyć jako zestaw. Zaplanowane wysyłki tutaj są adresowane indywidualnie po ich identyfikatorze wiadomości; nie ma uchwytu grupowego do przekazania ani anulowania.
- **Załącznik przez URL nie jest obsługiwany.** Brevo akceptuje wpis `attachment` jako URL, z którego sam pobiera plik. Pobierz plik samodzielnie i wyślij go zakodowany w base64; patrz [załączniki](/docs/guides/email/attachments).

## Eksport supresji

Brevo rozdziela supresje między dwa systemy, które nie mają wspólnego endpointu ani schematu paginacji, a migracja pobierająca tylko pierwszy cicho traci każdy marketingowy unsubscribe:

- **Blokady i unsubscriby transakcyjne**: `GET /v3/smtp/blockedContacts`, paginowany (domyślnie 50 na stronę, maksymalnie 100), każdy wpis zawiera powód blokady.
- **Marketingowa lista blokad**: to w ogóle nie jest endpoint supresji. Znajduje się w rekordzie kontaktu jako `emailBlacklisted`, więc paginuj `GET /v3/contacts` (do 1000 na stronę z `offset`) i zachowaj kontakty, w których ta flaga ma wartość true.

Przepuść obie listy przez [pętlę importu](/docs/guides/email/migrate#3-import-suppressions). Powody blokad Brevo mapują się na nasze powody `hard_bounce`, `complaint` i `manual`; [Supresje](/docs/guides/email/suppressions) zawierają pełną taksonomię.

## Przetłumacz zdarzenia webhookowe

| Rezultat                   | Brevo                       | Bird                                             |
| -------------------------- | --------------------------- | ------------------------------------------------ |
| Zaakceptowane/przetworzone | `request`                   | `email.accepted` → `email.processed`             |
| Dostarczone                | `delivered`                 | `email.delivered`                                |
| Błąd tymczasowy            | `deferred` / `soft_bounce`  | `email.deferred`                                 |
| Trwały bounce              | `hard_bounce`               | `email.bounced` / `email.out_of_band_bounce`     |
| Zgłoszenie spamu           | `spam`                      | `email.complained`                               |
| Zablokowane/wstrzymane     | `blocked` / `invalid_email` | `email.rejected`                                 |
| Otwarcie                   | `opened` / `unique_opened`  | `email.opened`                                   |
| Kliknięcie                 | `click`                     | `email.clicked`                                  |
| Wypisanie się              | `unsubscribed`              | `email.unsubscribed` / `email.list_unsubscribed` |

Dwie różnice decydują o tym, jak bardzo zmieni się Twój handler.

**Sprawdź, na czym Twój endpoint polega dziś, zanim zaczniesz go portować.** Strona bezpieczeństwa webhooków Brevo dokumentuje dane uwierzytelniające konfigurowane na endpoincie: nazwę użytkownika i hasło dołączane do URL jako `https://username:password@example.com/`, token bearer, własne nagłówki żądań i zakresy IP. My podpisujemy każde dostarczenie zgodnie ze schematem HMAC [Standard Webhooks](https://www.standardwebhooks.com), więc weryfikacja przenosi się z czegoś, co niesie wywołujący, na coś, co oblicza Twój handler. Jeśli Twój obecny endpoint przechowuje dane uwierzytelniające w URL, usuń je i zrotuj tę parę zamiast jej ponownie używać: dane uwierzytelniające, które żyły w URL, trafiły do logów dostępu, eksportów konfiguracji i konsoli dostawcy. Instrukcja jest w [Webhooki i zdarzenia](/docs/guides/webhooks).

**Brevo rozróżnia otwarcia i kliknięcia od ich wariantów unikalnych. My nie.** `opened` i `unique_opened` przychodzą jako `email.opened`, więc handler, który liczył tylko wariant unikalny, musi deduplikować po `recipient_id`. Nasze zdarzenia dostarczenia są w zakresie odbiorcy, więc wysyłka do trzech odbiorców generuje trzy wyniki dostarczenia, a nie jeden.

## Przełączenie

Przejdź przez [domeny i DNS](/docs/guides/email/migrate#2-re-point-domains-and-dns) oraz [test sandbox](/docs/guides/email/migrate#5-verify-in-the-sandbox-before-cutover) w głównym przewodniku. Oba są niezależne od dostawcy.

## Następne kroki

- [Domeny wysyłkowe](/docs/guides/email/sending-domains): rejestracja, cykl życia weryfikacji i rekordy DNS, które publikujesz
- [Webhooki i zdarzenia](/docs/guides/webhooks): konfiguracja endpointu i weryfikacja Standard Webhooks
- [Sandbox testowy](/docs/guides/email/testing-sandbox): przetestuj nową integrację przed przełączeniem
- [Supresje](/docs/guides/email/suppressions): potwierdź zaimportowaną listę i sposób, w jaki utrzymujemy ją od teraz

## Related resources

- [Getting started with email](/learn/email/getting-started-with-email) (video)
- [Email](/products/email) (product)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=email)
