Migreren van Mailjet
Deze pagina vertaalt de Send API v3.1-payload, blokkeerlijst en Event API van Mailjet naar Bird. Volg de hoofdmigratiegids op volgorde en gebruik deze vertalingen voor stap 1, 3 en 4.
De grootste structurele verandering is de envelope. Mailjet verpakt elke verzending in een Messages-array van PascalCase-objecten (POST /v3.1/send). Wij nemen één plat, lowercase JSON-object per POST /v1/email/messages, en meerdere onafhankelijke berichten gaan naar het batch-endpoint in plaats van de Messages-array.
Geef dit aan je agent
Plak dit in Claude Code, Cursor of Codex. De agent werkt deze pagina door tegen je eigen repository, met het Bird-oppervlak dat hij al heeft: de MCP-server als er een verbonden is, de CLI als die geïnstalleerd en ingelogd is.
Codevoorbeeld
I am moving an email integration from Mailjet 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/mailjet.md for the payload, suppression and event mapping, and https://bird.com/docs/guides/email/migrate.md for the order the steps go in.
3. Find and list my Mailjet usage in this repository before you change anything: the POST /v3.1/send call sites and any SDK wrappers around them, the event handler and the URL it is registered at, and every domain I send from.
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 my current provider 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 blocklist from Mailjet and import it into Bird before any production traffic goes through Bird, so my first sends do not reach addresses that already bounced or complained. Read it through the contact-management API, or from the contact statistics pages if that is what I have access to. 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 event handler using the mapping tables on the provider page. Mailjet posts a Messages array of PascalCase objects, and each entry becomes either one flat Bird send or one entry in a batch, so tell me which shape my call sites map onto before you rewrite them. EventPayload becomes metadata. Bird signs deliveries per Standard Webhooks rather than Mailjet's scheme, so treat verification as a rewrite rather than a URL change: 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 Mailjet path is a separate step that comes later: ask me again and wait for me to reply with the words retire the Mailjet 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.Vertaal de send-call
| Wat het doet | Mailjet (Send API v3.1) | Bird |
|---|---|---|
| Afzender | From: { "Email", "Name" } | from: string of { "email", "name" } |
| Ontvangers | To / Cc / Bcc: [{ "Email", "Name" }] | to / cc / bcc: arrays |
| Onderwerp | Subject | subject |
| Body | TextPart / HTMLPart | text / html (minstens één) |
| Reply-to | ReplyTo: { "Email", "Name" } | reply_to: array |
| Aangepaste headers | Headers | headers: string → string object |
| Round-trip-context | EventPayload (string), meegestuurd bij events | metadata: willekeurig JSON |
| Eigen verzend-ID | CustomID, meegestuurd bij events | metadata of tags |
| Opgeslagen template | TemplateID + Variables | template + template.parameters |
| Bijlagen | Attachments: { "ContentType", "Filename", "Base64Content" } | attachments: { "content_type", "filename", "content" } |
| Inline-afbeeldingen | InlinedAttachments, met ContentID | attachments met content_id |
| Tracking | account-/template-instelling | track_opens / track_clicks (standaard true) |
| Categorie | (geen) | category: marketing (standaard) of transactional |
Onze veldlimieten en standaardwaarden (aantal ontvangers, tag- en metadatalimieten) staan in E-mail verzenden.
Opmerkingen bij het porten:
- Pak de Messages-array uit. Een enkele Mailjet-verzending is één entry in Messages. Hier is dat de hele request body. Een Messages-array met meerdere entries vertaalt naar ons batch-endpoint. Herhaalde velden in één request kunnen de batch niet representeren.
- Case verandert van PascalCase naar lowercase. Elk veld wordt hernoemd: HTMLPart → html, TextPart → text, From.Email → from.email. Dit is mechanisch maar raakt elke verzending.
- EventPayload wordt metadata. Mailjet stuurt een enkele EventPayload-string mee bij elk event. Wij sturen gestructureerde metadata (JSON) en tags mee bij elk webhook-event, zodat je correlatiedata kunt opsplitsen in getypeerde velden. Zie tags vs metadata.
- CustomID is een correlatiehandle; voor retries heb je een apart antwoord nodig. Mailjet's CustomID wordt doorgegeven aan de events voor tracking; het dedupliceert niet. Hun deduplicatie is X-Mailjet-DeduplicateCampaign, een boolean die samen met X-Mailjet-Campaign voorkomt dat een campagne dezelfde ontvanger twee keer bereikt. Dat is een campagne-gebonden garantie, geen veilige retry van één request. Zet hier je correlatie-ID in metadata of tags, en gebruik de Idempotency-Key-header om een herhaald request veilig te maken.
- Opgeslagen templates porten direct. Mailjet's TemplateID + Variables vertalen naar ons template-veld (op ID of slug) met waarden in template.parameters. Zie verzenden met een template. Templatelogica voorbij variabelevervanging port ook: Mailjet's TemplateLanguage-conditionals en -loops worden Liquid {% if %} en {% for %} in ons template.
- Bijlagen porten direct. Mailjet's Base64Content is onze base64 content, en InlinedAttachments + ContentID worden attachments-entries met content_id. Zie bijlagen.
Suppressies exporteren
Mailjet houdt onbereikbare en ongewenste adressen op zijn blokkeerlijst (harde/zachte bounces en geblokkeerde verzendingen) en volgt spam- en uitschrijfsignalen apart. Exporteer de geblokkeerde en gebouncete adressen uit Mailjet's contactstatistiekpagina's, of haal ze op via de contactbeheer-API, en verwerk de lijst via de importloop. Als je marketingmail verstuurt, neem dan ook contacten mee die als uitgeschreven staan, zodat die voorkeuren de migratie overleven.
Webhook-events vertalen
Mailjet's Event API stuurt één trigger per eventtype. De vertaling naar ons eventvocabulaire:
| Resultaat | Mailjet | Bird |
|---|---|---|
| Geaccepteerd/verwerkt | (geen) | email.accepted → email.processed |
| Afgeleverd | sent | email.delivered |
| Permanente bounce | bounce | email.bounced / email.out_of_band_bounce |
| Geblokkeerd | blocked | email.rejected |
| Spamklacht | spam | email.complained |
| Geopend | open | email.opened |
| Klik | click | email.clicked |
| Uitschrijving | unsub | email.unsubscribed / email.list_unsubscribed |
Twee verschillen om rekening mee te houden in je code:
- Wij rapporteren de stappen vóór aflevering expliciet. Mailjet's sent vuurt zodra de mailserver van de ontvanger het bericht accepteert, wat overeenkomt met onze email.delivered. Wij sturen ook email.accepted en email.processed daarvóór, zodat je een verzending ziet vorderen vóór de afleverbevestiging. Behandel die eerdere events niet als aflevering.
- Events zijn per ontvanger. Mailjet koppelt events aan MessageID. Onze afleverevents bevatten recipient_id naast email_id, dus een verzending aan meerdere ontvangers levert één eventstroom per ontvanger op. We ondertekenen afleveringen volgens de Standard Webhooks-spec. Zie Webhooks & events voor verificatie.
Overschakelen
Doorloop domeinen & DNS en de sandbox-rooktest in de hoofdgids. Beide zijn provideronafhankelijk.
Volgende stappen
- Verzenddomeinen: registratie, verificatielevenscyclus en de DNS-records die je omzet
- Webhooks & events: endpoint-setup en Standard Webhooks-verificatie
- Testsandbox: rooktest de nieuwe integratie vóór de overschakeling
- Suppressies: controleer je geïmporteerde lijst en hoe wij die vanaf hier onderhouden
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.
Bekijk de gidsGetting started with emailOntdek de mogelijkheidEmailVolg het leerpadBuild your first integrationImplementatiegidsSend your first email
Probeer de oefening en ontvang een implementatieoverzicht