Sign inGet started

Guide per AI builder

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. Questi cinque pattern coprono le modalità di errore che compromettono le integrazioni con agenti: trattare l'accettazione come consegna, ritentare senza contesto e analizzare testo libero invece di strutture. Ogni pattern funziona allo stesso modo sia che il vostro agente utilizzi il server MCP sia la bird CLI. Gli esempi qui sotto riguardano l'email, perché è dove il tooling attorno a un invio è più completo, e i pattern si applicano a SMS e WhatsApp senza modifiche: lo stesso 202 sull'invio, la stessa sequenza di eventi accepted-then-terminal, lo stesso envelope di errore. L'unica eccezione è il Pattern 3, i cui indirizzi magici sono una sandbox email.

Pattern 1: Eseguire un'operazione alla volta nel loop

I tool di Bird sono volutamente granulari: inviare un messaggio, ottenere un messaggio, elencare i domini o creare un endpoint webhook. Ogni tool restituisce JSON strutturato i cui campi possono essere verificati dal passo successivo. Costruite il loop in modo che la condizione di uscita di ogni passo venga 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 branching non richiede parsing del messaggio. Vedere 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: un agente che può verificare lo stato tra un passo e l'altro si riprende da qualsiasi singolo errore; un agente che guida un'unica mega-operazione può solo ricominciare da capo.

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

Effettuate un POST di invio e ottenete 202 Accepted con un ID messaggio. Accepted 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 202 perde silenziosamente ogni bounce. Strutturate il task come invio-poi-attesa:
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
Correlate su email_id. I payload dei webhook riportano i vostri tag e metadati insieme ai campi identificativi, quindi il vostro contesto torna indietro senza un lookup aggiuntivo. Le consegne sono at-least-once e non ordinate; deduplicare sull'header webhook-id e ordinare per il timestamp del payload. Se il vostro agente non ha un ricevitore webhook, fate polling del messaggio con GET (o bird email get) fino a quando il suo stato si risolve. Il polling è più lento, ma la rilettura rimane la fonte di verità.

Pattern 3: Usare la sandbox come harness di test

Mentre sviluppate il loop, usate gli indirizzi magici della sandbox email su messagebird.dev invece di caselle reali. L'indirizzo determina l'esito (delivered@ consegna sempre, bounce@ genera 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 contrassegna 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 rischio per la reputazione, nessuna scrittura nelle liste di soppressione e indirizzi riutilizzabili in ogni esecuzione. Un agente che supera la matrice della sandbox ha esercitato l'intero percorso del Pattern 2 (invio, attesa e branching) prima di toccare una casella reale.

Pattern 4: Recupero con l'envelope di errore standard

Ogni errore dell'API Bird ha la stessa struttura, quindi un unico percorso di recupero da errore funziona per 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 loop. Fare branching su type/code (stabili e leggibili dalla macchina), mostrare message all'umano e recuperare doc_url quando l'agente ha bisogno della pagina per quell'errore specifico. L'URL si risolve in Markdown che l'agente può leggere. Registrare request_id affinché un umano possa fornirlo al supporto Bird. Poi separare gli errori ritentabili 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 errori. Con la CLI, l'envelope arriva su stderr e il codice di uscita lo pre-classifica (vedere Pattern 1 e la tabella completa in CLI). Un agente che guida una shell può quindi fare branching prima di analizzare qualsiasi cosa.

Pattern 5: Retry sicuri con Idempotency-Key e Retry-After

I retry possono duplicare il lavoro quando un invio va in timeout e l'agente riprova. Il supporto idempotency di Bird rende i retry sicuri. Generate un Idempotency-Key per operazione logica e riutilizzatelo ad 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 indica un replay della risposta originale, così il vostro agente può registrare "recuperato" invece di "inviato due volte". Gli SDK di Bird iniettano automaticamente una chiave su ogni richiesta mutante, quindi gli agenti basati su SDK ottengono questo gratuitamente; con la CLI, passate --idempotency-key sulle mutazioni che potrebbero essere ritentate.
Un 429 significa che l'agente deve rallentare. La risposta contiene un header Retry-After; usatelo come backoff minimo invece di inventare uno schedule separato:
Esempio di codice
on 429: sleep max(Retry-After, backoff(attempt)); retry with the same key
Non ritentate altre risposte 4xx senza modifiche. L'idempotency le memorizza nella cache e le replica perché la stessa richiesta produce lo stesso errore. Correggete la richiesta (Pattern 4) e usate una nuova chiave; riutilizzare una chiave con un body diverso restituisce 409 IdempotencyKeyReuse.

Prossimi passi

  • Server MCP: la superficie di tool che questi pattern guidano, ospitata su mcp.bird.com o eseguita localmente con la CLI
  • CLI per agenti: le stesse operazioni per agenti con capacità shell
  • Webhook ed eventi: semantica di consegna, firme e catalogo eventi dietro al Pattern 2
  • Idempotency: semantica di replay e modalità di errore dietro al Pattern 5
  • Errori: l'envelope e il catalogo completo dei codici di errore
  • Sandbox email: la matrice degli indirizzi magici dietro al Pattern 3