Sign inGet Started

Guide per chi sviluppa con l'AI

La superficie API di Bird è progettata per gli agenti: un'operazione per tool, JSON in ingresso e in uscita, ed esiti verificabili dalla macchina. Un agente affidabile ha comunque bisogno dei pattern giusti attorno a sé. Questi cinque pattern coprono le modalità di errore che compromettono le integrazioni degli agenti: trattare l'accettazione come consegna, riprovare senza contesto, e interpretare testo libero invece di strutture. Ogni pattern funziona allo stesso modo sia che il tuo agente utilizzi il server MCP sia la bird CLI. Gli esempi qui sotto riguardano l'email, perché è il canale dove gli strumenti attorno a un invio sono più completi, e i pattern si applicano a SMS e WhatsApp senza modifiche: lo stesso 202 sull'invio, la stessa sequenza di eventi accettato-poi-terminale, la stessa risposta di errore. L'unica eccezione è il Pattern 3, i cui indirizzi magici sono una sandbox email.

Pattern 1: Esegui un'operazione alla volta nel ciclo

I tool di Bird sono volutamente granulari: invia un messaggio, recupera un messaggio, elenca i domini o crea un endpoint webhook. Ogni tool restituisce JSON strutturato i cui campi possono essere verificati dal passo successivo. Costruisci il ciclo in modo che la condizione di uscita di ogni passo derivi dall'output del passo precedente:
Esempio di codice
loop:
  result = run_tool(next_operation)        # one operation per call
  if result.ok: advance using result.data  # for example, the em_… ID or verified domain
  else: branch on the failure category     # see Pattern 4
Con la CLI, la categoria di errore è il codice di uscita, quindi il ramo decisionale non richiede analisi del messaggio. Consulta la tabella completa in CLI:
Esempio di codice
bird email get "$id" --format json > msg.json
case $? in
  0) jq .status msg.json ;;     # advance
  3) echo "wrong ID: fix the value instead of retrying" ;;
  4) bird auth login ;;          # recover, then re-run
esac
La granularità è il punto chiave: un agente che può verificare lo stato tra un passo e l'altro recupera da qualsiasi singolo errore; un agente che guida una mega-operazione unica può solo ricominciare da capo.

Pattern 2: Un invio restituisce 202; l'esito arriva dopo

Esegui POST un invio e ottieni 202 Accepted con un ID messaggio. Accettato significa che Bird ha preso in carico il messaggio e la consegna è in corso. L'esito finale arriva come eventi webhook: email.delivered quando il server del destinatario lo accetta, email.bounced quando la consegna fallisce permanentemente, email.complained, e così via.
Un agente che dichiara successo al momento di 202 perde silenziosamente ogni bounce. Struttura il compito come invio-poi-attendi:
Esempio di codice
send → 202 + em_… ID            # record the ID; delivery is still pending
await webhook event where data.email_id == em_… id:
  email.delivered → done
  email.bounced   → report failure with bounce_type / bounce_description
Correla su email_id. I payload dei webhook riportano i tuoi tag e metadati insieme ai campi identificativi, così il tuo contesto torna indietro senza una ricerca aggiuntiva. Le consegne sono at-least-once e non ordinate; deduplica sull'header webhook-id e ordina per il timestamp del payload. Se il tuo agente non ha un ricevitore webhook, interroga il messaggio con GET (o bird email get) finché il suo stato non si risolve. Il polling è più lento, ma la rilettura resta la fonte di verità.

Pattern 3: Usa la sandbox come ambiente di test

Durante lo sviluppo del ciclo, usa gli indirizzi magici della sandbox email su messagebird.dev al posto di caselle reali. L'indirizzo determina l'esito (delivered@ consegna sempre, bounce@ produce sempre un hard-bounce e complaint@ genera sempre un reclamo). Tutto il resto usa la pipeline di produzione: lo stesso 202, la stessa sequenza di eventi e le stesse consegne webhook firmate, senza alcun flag che segni il messaggio come test.
Esempio di codice
for address in [delivered@, bounce@, suppressed@] @messagebird.dev:
  send to address+run42@…                  # +label correlates the test case
  assert the expected terminal event arrives (delivered / bounced / rejected)
La sandbox fornisce esiti deterministici, zero rischi per la reputazione, nessuna scrittura nelle liste di soppressione e indirizzi riutilizzabili tra un'esecuzione e l'altra. Un agente che supera la matrice della sandbox ha esercitato l'intero percorso del Pattern 2 (invio, attesa e ramificazione) prima di toccare una casella reale.

Pattern 4: Recupera gli errori con la risposta di errore standard

Ogni errore API di Bird ha la stessa struttura, quindi un unico percorso di recupero funziona su tutti gli endpoint:
Esempio di codice
{
  "error": {
    "type": "validation_error",
    "code": "E04006",
    "name": "DomainNotVerified",
    "message": "The from address uses a domain that is not verified in this workspace.",
    "doc_url": "https://bird.com/docs/api/errors/E04006",
    "request_id": "req_01krdgeqcxet5s7t44vh8rt9mg"
  }
}
Ogni campo ha un ruolo nel ciclo. Ramifica su type/code (stabile e leggibile dalla macchina), mostra message all'utente e recupera doc_url quando l'agente ha bisogno della pagina per quello specifico errore. L'URL punta a un Markdown che l'agente può leggere. Registra request_id così un operatore può fornirlo al supporto Bird. Poi separa gli errori riprovabili dagli errori di richiesta:
Esempio di codice
4xx (except 429) → a request bug: fix the input, never retry as-is
429              → back off, then retry (Pattern 5)
5xx / timeout    → retry with the same Idempotency-Key (Pattern 5)
Il catalogo completo dei codici si trova nella pagina degli errori. Con la CLI, la risposta di errore arriva su stderr e il codice di uscita la pre-classifica (vedi Pattern 1 e la tabella completa in CLI). Un agente che guida una shell può quindi ramificare prima di analizzare qualsiasi cosa.

Pattern 5: Riprova in sicurezza con Idempotency-Key e Retry-After

Le ripetizioni possono duplicare il lavoro quando un invio va in timeout e l'agente riprova. Il supporto all'idempotenza di Bird rende sicure le ripetizioni. Genera un Idempotency-Key per operazione logica e riutilizzalo a ogni tentativo:
Esempio di codice
key = uuid()                                  # once per logical send
attempt with Idempotency-Key: key
on 5xx / timeout: backoff, retry with SAME key
on 2xx with Idempotency-Replay: true → the first attempt had succeeded; do not treat as a new send
L'header di risposta Idempotency-Replay: true segnala un replay della risposta originale, così il tuo agente può registrare "recovered" invece di "sent twice". Gli SDK Bird iniettano automaticamente una chiave su ogni richiesta mutante, quindi gli agenti basati su SDK ottengono questo gratis; con la CLI, passa --idempotency-key sulle mutazioni che potrebbero essere ripetute.
Un 429 significa che l'agente deve rallentare. La risposta contiene un header Retry-After; usalo come backoff minimo invece di inventare una pianificazione separata:
Esempio di codice
on 429: sleep max(Retry-After, backoff(attempt)); retry with the same key
Non riprovare altre risposte 4xx senza modifiche. L'idempotenza le memorizza e le riproduce perché la stessa richiesta produce lo stesso errore. Correggi la richiesta (Pattern 4) e usa una chiave nuova; riutilizzare una chiave con un body diverso restituisce 409 IdempotencyKeyReuse.

Prossimi passi

  • Server MCP: la superficie di tool che questi pattern utilizzano, ospitata su mcp.bird.com o eseguibile in locale con la CLI
  • CLI per agenti: le stesse operazioni per agenti capaci di usare la shell
  • Webhook ed eventi: semantica di consegna, firme e catalogo degli eventi dietro il Pattern 2
  • Idempotenza: semantica di replay e modalità di errore dietro il Pattern 5
  • Errori: la risposta di errore e il catalogo completo dei codici di errore
  • Sandbox email: la matrice degli indirizzi magici dietro il Pattern 3