Migrare da Mailjet
Questa pagina mappa il payload Send API v3.1, la blocklist e l'Event API di Mailjet su Bird. Segui la guida principale alla migrazione nell'ordine indicato e usa queste corrispondenze per i passaggi 1, 3 e 4.
Il cambiamento strutturale più grande riguarda l'envelope. Mailjet racchiude ogni invio in un array Messages di oggetti PascalCase (POST /v3.1/send). Noi accettiamo un singolo oggetto JSON flat e lowercase per POST /v1/email/messages, e più messaggi indipendenti vanno al batch endpoint anziché nell'array Messages.
Passa questo al tuo agente
Incolla questo in Claude Code, Cursor o Codex. L'agente lavora su questa pagina nel tuo repository, usando qualsiasi superficie Bird già disponibile: il server MCP se è connesso, la CLI se è installata e autenticata.
Esempio di codice
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.Mappa la chiamata di invio
| Funzione | Mailjet (Send API v3.1) | Bird |
|---|---|---|
| Mittente | From: { "Email", "Name" } | from: stringa o { "email", "name" } |
| Destinatari | To / Cc / Bcc: [{ "Email", "Name" }] | to / cc / bcc: array |
| Oggetto | Subject | subject |
| Corpo | TextPart / HTMLPart | text / html (almeno uno) |
| Reply-to | ReplyTo: { "Email", "Name" } | reply_to: array |
| Header personalizzati | Headers | headers: oggetto stringa → stringa |
| Contesto round-trip | EventPayload (stringa), restituito sugli eventi | metadata: JSON arbitrario |
| ID invio personalizzato | CustomID, restituito sugli eventi | metadata o tags |
| Template salvato | TemplateID + Variables | template + template.parameters |
| Allegati | Attachments: { "ContentType", "Filename", "Base64Content" } | attachments: { "content_type", "filename", "content" } |
| Immagini inline | InlinedAttachments, con ContentID | attachments con content_id |
| Tracciamento | impostazione account/template | track_opens / track_clicks (default true) |
| Categoria | (nessuna) | category: marketing (default) o transactional |
I limiti e i valori predefiniti dei campi (numero di destinatari, limiti di tag e metadati) si trovano in Invio email.
Note di porting:
- Estrai dall'array Messages. Un singolo invio Mailjet è una voce in Messages. Qui corrisponde all'intero corpo della richiesta. Un array Messages con più voci corrisponde al nostro batch endpoint. Campi ripetuti in una singola richiesta non rappresentano il batch.
- Il case cambia da PascalCase a lowercase. Ogni campo viene rinominato: HTMLPart → html, TextPart → text, From.Email → from.email. È meccanico, ma tocca ogni invio.
- EventPayload diventa metadata. Mailjet restituisce una singola stringa EventPayload su ogni evento. Noi restituiamo metadata strutturati (JSON) e tags su ogni evento webhook, così puoi suddividere i dati di correlazione in campi tipizzati. Vedi tag vs metadati.
- CustomID è un handle di correlazione, e i retry richiedono una soluzione separata. Il CustomID di Mailjet viene propagato agli eventi per il tracciamento; non deduplica. La loro deduplicazione è X-Mailjet-DeduplicateCampaign, un booleano usato con X-Mailjet-Campaign che impedisce a una campagna di raggiungere lo stesso destinatario due volte: una garanzia a livello di campagna, non un retry sicuro di una singola richiesta. Qui, inserisci il tuo ID di correlazione in metadata o tags, e usa l'header Idempotency-Key per rendere sicura una richiesta ripetuta.
- I template salvati si portano direttamente. TemplateID + Variables di Mailjet corrispondono al nostro campo template (referenziato per ID o slug) con i valori in template.parameters. Vedi invio con un template. Anche la logica di templating oltre la sostituzione di variabili si porta: i condizionali e i cicli TemplateLanguage di Mailjet diventano {% if %} e {% for %} Liquid nel nostro template.
- Gli allegati si portano direttamente. Il Base64Content di Mailjet è il nostro content in base64, e InlinedAttachments + ContentID diventano voci attachments con content_id. Vedi allegati.
Esporta le soppressioni
Mailjet conserva gli indirizzi irraggiungibili e indesiderati nella sua blocklist (hard/soft bounce e invii bloccati) e traccia separatamente i segnali di spam e cancellazione. Esporta gli indirizzi bloccati e rimbalzati dalle pagine di statistiche contatti di Mailjet, oppure recuperali tramite l'API di gestione contatti, e passa la lista attraverso il ciclo di importazione. Se invii email di marketing, trasferisci anche i contatti contrassegnati come cancellati, in modo che le loro preferenze sopravvivano alla migrazione.
Traduci gli eventi webhook
L'Event API di Mailjet invia un trigger per tipo di evento. La corrispondenza con il nostro vocabolario degli eventi:
| Esito | Mailjet | Bird |
|---|---|---|
| Accettato/elaborato | (nessuno) | email.accepted → email.processed |
| Consegnato | sent | email.delivered |
| Bounce permanente | bounce | email.bounced / email.out_of_band_bounce |
| Bloccato | blocked | email.rejected |
| Segnalazione spam | spam | email.complained |
| Apertura | open | email.opened |
| Clic | click | email.clicked |
| Cancellazione | unsub | email.unsubscribed / email.list_unsubscribed |
Due differenze da gestire nel codice:
- Riportiamo esplicitamente le fasi precedenti alla consegna. Il sent di Mailjet scatta quando il server di posta del destinatario accetta il messaggio, corrispondente al nostro email.delivered. Noi emettiamo anche email.accepted e email.processed prima, così vedi l'invio progredire prima della conferma di consegna. Non trattare quegli eventi precedenti come consegna.
- Gli eventi sono a livello di destinatario. Mailjet identifica gli eventi tramite MessageID. I nostri eventi di consegna hanno recipient_id insieme a email_id, quindi un invio multi-destinatario produce un flusso di eventi per ciascun destinatario. Le consegne sono firmate secondo la specifica Standard Webhooks. Vedi Webhook ed eventi per la verifica.
Cutover
Segui domini e DNS e il test sandbox nella guida principale. Entrambi sono indipendenti dal provider.
Prossimi passaggi
- Domini di invio: registrazione, ciclo di vita della verifica e i record DNS da aggiornare
- Webhook ed eventi: configurazione dell'endpoint e verifica Standard Webhooks
- Sandbox di test: testa la nuova integrazione prima del cutover
- Soppressioni: verifica la lista importata e come la manteniamo da qui in avanti
Risorse correlate
Prosegui con la documentazione, le guide e gli esempi per questo argomento. Le risorse sono in inglese.
Guarda la guidaGetting started with emailEsplora la funzionalitàEmailSegui il percorso di apprendimentoBuild your first integrationGuida all'implementazioneSend your first email
Prova l'esercitazione e ottieni un brief di implementazione