Sign inGet Started

Guías para constructores de IA

La superficie API de Bird está diseñada para agentes: una operación por herramienta, JSON de entrada y salida, y resultados verificables por máquina. Un agente fiable aún necesita los patrones correctos a su alrededor. Estos cinco patrones cubren los modos de fallo que rompen las integraciones de agentes: tratar la aceptación como entrega, reintentar sin contexto y parsear prosa en lugar de estructura. Cada patrón funciona igual tanto si tu agente usa el servidor MCP como la bird CLI. Los ejemplos son de email, porque es donde las herramientas alrededor de un envío son más completas, y los patrones se trasladan a SMS y WhatsApp sin cambios: el mismo 202 en el envío, la misma secuencia de eventos aceptado-luego-terminal, la misma respuesta de error. La única excepción es el Patrón 3, cuyas direcciones mágicas son un sandbox de email.

Patrón 1: Ejecuta una operación a la vez en el bucle

Las herramientas de Bird son deliberadamente granulares: enviar un mensaje, obtener un mensaje, listar dominios o crear un endpoint de webhook. Cada herramienta devuelve JSON estructurado cuyos campos el siguiente paso puede verificar. Construye el bucle de modo que la condición de salida de cada paso provenga de la salida del paso anterior:
Ejemplo de código
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 categoría del fallo es el código de salida, así que la bifurcación no necesita parsear mensajes. Consulta la tabla completa en CLI:
Ejemplo de código
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 granularidad es lo importante: un agente que puede verificar el estado entre pasos se recupera de cualquier fallo individual; un agente que ejecuta una mega-operación solo puede empezar de cero.

Patrón 2: Un envío devuelve 202; el resultado llega después

POST un envío y obtienes 202 Accepted con un ID de mensaje. Aceptado significa que Bird tomó el mensaje y la entrega está pendiente. El resultado final llega como eventos de webhook: email.delivered cuando el servidor del destinatario lo acepta, email.bounced cuando la entrega falla permanentemente, email.complained, y así sucesivamente.
Un agente que declara éxito en 202 pierde silenciosamente cada rebote. Estructura la tarea como enviar-luego-esperar:
Ejemplo de código
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
Correlaciona con email_id. Los payloads de webhook repiten tus tags y metadatos junto a los campos de identidad, así que tu propio contexto regresa sin una consulta adicional. Las entregas son at-least-once y sin orden; deduplica con el encabezado webhook-id y ordena por el timestamp del payload. Si tu agente no tiene receptor de webhooks, consulta el mensaje con GET (o bird email get) hasta que su estado se resuelva. El polling es más lento, pero la lectura sigue siendo la fuente de verdad.

Patrón 3: Usa el sandbox como tu entorno de pruebas

Mientras desarrollas el bucle, usa las direcciones mágicas del sandbox de correo en messagebird.dev en lugar de buzones reales. La dirección determina el resultado (delivered@ siempre entrega, bounce@ siempre genera un rebote duro y complaint@ siempre genera una queja). Todo lo demás usa el pipeline de producción: el mismo 202, la misma secuencia de eventos y entregas de webhook firmadas, sin ninguna marca que identifique el mensaje como prueba.
Ejemplo de código
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)
El sandbox proporciona resultados deterministas, cero riesgo de reputación, ninguna escritura en listas de supresión y direcciones reutilizables entre ejecuciones. Un agente que pasa la matriz del sandbox ha ejercitado la ruta completa del Patrón 2 (enviar, esperar y bifurcar) antes de tocar una bandeja de entrada real.

Patrón 4: Recuperación contra la respuesta de error estándar

Cada error API de Bird tiene la misma forma, así que una sola ruta de recuperación de errores funciona en todos los endpoints:
Ejemplo de código
{
  "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"
  }
}
Cada campo tiene una función en el bucle. Bifurca según type/code (estable y legible por máquina), muestra message al humano y obtén doc_url cuando el agente necesite la página de ese error exacto. La URL resuelve a Markdown que el agente puede leer. Registra request_id para que un humano pueda proporcionarlo al soporte de Bird. Luego separa los errores reintentables de los errores de solicitud:
Ejemplo de código
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)
El catálogo completo de códigos está en la página de errores. Con la CLI, la respuesta de error llega por stderr y el código de salida la preclasifica (consulta el Patrón 1 y la tabla completa en CLI). Un agente que controla el shell puede bifurcar antes de parsear nada.

Patrón 5: Reintenta de forma segura con Idempotency-Key y Retry-After

Los reintentos pueden duplicar trabajo cuando un envío expira y el agente lo intenta de nuevo. El soporte de idempotencia de Bird hace que los reintentos sean seguros. Genera un Idempotency-Key por operación lógica y reutilízalo en cada intento:
Ejemplo de código
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
El encabezado de respuesta Idempotency-Replay: true marca una repetición de la respuesta original, para que tu agente pueda registrar "recovered" en lugar de "sent twice". Los SDKs de Bird inyectan una clave automáticamente en cada solicitud mutante, así que los agentes basados en SDK obtienen esto gratis; con la CLI, pasa --idempotency-key en mutaciones que podrían reintentarse.
Un 429 significa que el agente debe reducir la velocidad. La respuesta incluye un encabezado Retry-After; úsalo como backoff mínimo en lugar de inventar un esquema aparte:
Ejemplo de código
on 429: sleep max(Retry-After, backoff(attempt)); retry with the same key
No reintentes otras respuestas 4xx sin modificar. La idempotencia las almacena en caché y las repite porque la misma solicitud produce el mismo error. Corrige la solicitud (Patrón 4) y usa una clave nueva; reutilizar una clave con un cuerpo diferente devuelve 409 IdempotencyKeyReuse.

Próximos pasos

  • Servidor MCP: la superficie de herramientas que estos patrones utilizan, alojada en mcp.bird.com o ejecutada localmente con la CLI
  • CLI para agentes: las mismas operaciones para agentes con acceso a shell
  • Webhooks y eventos: semántica de entrega, firmas y el catálogo de eventos detrás del Patrón 2
  • Idempotencia: semántica de repetición y modos de fallo detrás del Patrón 5
  • Errores: la respuesta de error y el catálogo completo de códigos de error
  • Sandbox de correo: la matriz de direcciones mágicas detrás del Patrón 3