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 ya sea que tu agente utilice el servidor MCP o el bird CLI. Los ejemplos a continuación 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, el mismo sobre de error. La única excepción es el Patrón 3, cuyas direcciones mágicas son un sandbox de email.
Patrón 1: Ejecutar una operación a la vez en 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 puede verificar el siguiente paso. 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 4Con el CLI, la categoría de fallo es el código de salida, por lo 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
esacLa granularidad es el punto clave: 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
Haz POST de un envío y obtienes 202 Accepted con un ID de mensaje. Accepted significa que Bird aceptó 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 con el 202 pasa por alto silenciosamente cada rebote. Estructura la tarea como enviar-y-esperar en su lugar:
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_descriptionCorrelaciona con email_id. Los payloads de webhook incluyen tus tags y metadata junto con los campos de identidad, así que tu propio contexto regresa sin una consulta adicional. Las entregas son at-least-once y desordenadas; deduplica con el header 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. La consulta es más lenta, pero la lectura posterior 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, 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, sin escrituras en listas de supresión y direcciones reutilizables en cada ejecución. 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: Recuperarse usando el sobre de error estándar
Cada error de la API de Bird tiene la misma estructura, por lo 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 un rol en el bucle. Bifurca según type/code (estables y legibles por máquina), muestra message al humano y consulta 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 el CLI, el sobre llega por stderr y el código de salida lo preclasifica (ver Patrón 1 y la tabla completa en CLI). Por lo tanto, un agente que controla el shell puede bifurcar antes de parsear nada.
Patrón 5: Reintentar 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 sendEl header de respuesta Idempotency-Replay: true marca una repetición de la respuesta original, para que tu agente pueda registrar "recuperado" en lugar de "enviado dos veces". Los SDK de Bird inyectan una clave automáticamente en cada solicitud mutante, por lo que los agentes basados en SDK obtienen esto gratis; con el CLI, pasa --idempotency-key en las mutaciones que podrían reintentarse.
Un 429 significa que el agente debe reducir la velocidad. La respuesta incluye un header Retry-After; úsalo como el backoff mínimo en lugar de inventar un esquema separado:
Ejemplo de código
on 429: sleep max(Retry-After, backoff(attempt)); retry with the same keyNo reintentes otras respuestas 4xx sin cambios. La idempotencia las cachea y replica 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 el CLI
- CLI para agentes: las mismas operaciones para agentes con capacidad de 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: el sobre 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