Migrasi dari Mailjet
Halaman ini memetakan payload Send API v3.1, blocklist, dan Event API Mailjet ke Bird. Ikuti panduan migrasi utama secara berurutan, dan gunakan pemetaan ini untuk langkah 1, 3, dan 4.
Perubahan struktur terbesar ada pada envelope. Mailjet membungkus setiap pengiriman dalam array Messages berisi objek PascalCase (POST /v3.1/send). Kami menerima satu objek JSON flat dan lowercase per POST /v1/email/messages, dan banyak pesan independen dikirim ke batch endpoint alih-alih array Messages.
Serahkan ini ke agent Anda
Tempelkan ini ke Claude Code, Cursor, atau Codex. Agent akan memproses halaman ini terhadap repositori Anda, menggunakan surface Bird mana pun yang sudah tersedia: server MCP jika sudah terhubung, atau CLI jika sudah terinstal dan login.
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.Petakan panggilan send
| Fungsi | Mailjet (Send API v3.1) | Bird |
|---|---|---|
| Pengirim | From: { "Email", "Name" } | from: string atau { "email", "name" } |
| Penerima | To / Cc / Bcc: [{ "Email", "Name" }] | to / cc / bcc: array |
| Subjek | Subject | subject |
| Isi | TextPart / HTMLPart | text / html (minimal satu) |
| Reply-to | ReplyTo: { "Email", "Name" } | reply_to: array |
| Header kustom | Headers | headers: objek string → string |
| Konteks round-trip | EventPayload (string), di-echo pada event | metadata: JSON arbitrer |
| Send ID Anda sendiri | CustomID, di-echo pada event | metadata atau tags |
| Template tersimpan | TemplateID + Variables | template + template.parameters |
| Lampiran | Attachments: { "ContentType", "Filename", "Base64Content" } | attachments: { "content_type", "filename", "content" } |
| Gambar inline | InlinedAttachments, dengan ContentID | attachments dengan content_id |
| Pelacakan | pengaturan akun/template | track_opens / track_clicks (default true) |
| Kategori | (tidak ada) | category: marketing (default) atau transactional |
Batas field dan nilai default kami (jumlah penerima, batas tag dan metadata) ada di Mengirim email.
Catatan porting:
- Lepaskan array
Messages. Satu pengiriman Mailjet adalah satu entri dalamMessages. Di sini, itu menjadi seluruh body request. ArrayMessagesdengan beberapa entri dipetakan ke batch endpoint kami. Field yang diulang dalam satu request tidak dapat merepresentasikan batch. - Case berubah dari PascalCase ke lowercase. Setiap field berganti nama:
HTMLPart→html,TextPart→text,From.Email→from.email. Ini mekanis tetapi menyentuh setiap pengiriman. EventPayloadmenjadimetadata. Mailjet mengembalikan satu stringEventPayloadpada setiap event. Kami mengembalikanmetadata(JSON) dantagsterstruktur pada setiap webhook event, sehingga Anda bisa memecah data korelasi ke dalam field bertipe. Lihat tags vs metadata.CustomIDadalah handle korelasi, dan retry memerlukan solusi terpisah.CustomIDMailjet diteruskan ke event untuk pelacakan; ia tidak melakukan deduplikasi. Deduplikasi Mailjet adalahX-Mailjet-DeduplicateCampaign, boolean yang digunakan denganX-Mailjet-Campaignuntuk mencegah kampanye menjangkau penerima yang sama dua kali, yaitu jaminan berskala kampanye dan bukan retry aman untuk satu request. Di sini, taruh ID korelasi Anda dimetadataatautags, dan gunakan headerIdempotency-Keyuntuk membuat request yang di-retry menjadi aman.- Template tersimpan dapat diporting langsung.
TemplateID+VariablesMailjet dipetakan ke fieldtemplatekami (direferensikan berdasarkan ID atau slug) dengan nilai ditemplate.parameters. Lihat mengirim dengan template. Logika templating selain substitusi variabel juga dapat diporting: kondisional dan loopTemplateLanguageMailjet menjadi{% if %}dan{% for %}Liquid di template kami. - Lampiran dapat diporting langsung.
Base64ContentMailjet adalahcontentbase64 kami, danInlinedAttachments+ContentIDmenjadi entriattachmentsdengancontent_id. Lihat lampiran.
Ekspor supresi
Mailjet menyimpan alamat yang tidak dapat dijangkau dan tidak diinginkan di blocklist-nya (hard/soft bounce dan pengiriman yang diblokir) dan melacak sinyal spam serta unsubscribe secara terpisah. Ekspor alamat yang diblokir dan bounce dari halaman statistik kontak Mailjet, atau tarik melalui API manajemen kontak, lalu jalankan daftarnya melalui loop impor. Jika Anda mengirim email marketing, pindahkan juga kontak yang ditandai unsubscribe agar preferensi tersebut tetap terjaga setelah migrasi.
Terjemahkan webhook event
Event API Mailjet mengirimkan satu trigger per tipe event. Pemetaan ke kosakata event kami:
| Hasil | Mailjet | Bird |
|---|---|---|
| Diterima/diproses | (tidak ada) | email.accepted → email.processed |
| Terkirim | sent | email.delivered |
| Bounce permanen | bounce | email.bounced / email.out_of_band_bounce |
| Diblokir | blocked | email.rejected |
| Keluhan spam | spam | email.complained |
| Dibuka | open | email.opened |
| Klik | click | email.clicked |
| Unsubscribe | unsub | email.unsubscribed / email.list_unsubscribed |
Dua perbedaan yang perlu Anda tangani dalam kode:
- Kami melaporkan tahap pra-pengiriman secara eksplisit.
sentMailjet aktif setelah server email penerima menerima pesan, yang sesuai denganemail.deliveredkami. Kami juga mengirimkanemail.accepteddanemail.processedsebelumnya, sehingga Anda bisa melihat progres pengiriman sebelum konfirmasi pengiriman. Jangan perlakukan event awal tersebut sebagai pengiriman. - Event berskala per penerima. Mailjet mengunci event berdasarkan
MessageID. Event pengiriman kami memilikirecipient_iddi sampingemail_id, sehingga pengiriman multi-penerima menghasilkan satu aliran event per penerima. Kami menandatangani pengiriman sesuai spesifikasi Standard Webhooks. Lihat Webhooks & events untuk verifikasi.
Cutover
Ikuti domain & DNS dan sandbox smoke test di panduan utama. Keduanya tidak bergantung pada penyedia tertentu.
Langkah selanjutnya
- Domain pengiriman: pendaftaran, siklus verifikasi, dan catatan DNS yang sedang Anda arahkan ulang
- Webhook & event: pengaturan endpoint dan verifikasi Standard Webhooks
- Sandbox pengujian: uji coba integrasi baru sebelum cutover
- Supresi: konfirmasi daftar yang telah diimpor dan cara kami mengelolanya selanjutnya
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini.