Sign inGet Started

Route messages to your AI agent

Bird sends each message you receive on WhatsApp, SMS, Apple Messages or an agent mailbox to your AI agent. Connect the agent once with its details and credentials, and every new message reaches it.

Two agents are supported:

  • Claude Managed Agents: each message starts a session of an agent you created in the Claude Console.
  • Grok Bot: each message wakes one of your Grok Bot routines.

Bird sends each matching message to your agent and retries a delivery that fails, so a retried message can start another run. The agent receives the message's event JSON, the same payload a plain webhook endpoint receives, and replies through whatever tools you gave it, such as the Bird MCP server.

Choose the messages your agent answers

Your agent can answer incoming messages only: whatsapp.received, sms.received, amb.received (Apple Messages) and email_mailbox.message_received. Pick the ones the agent should handle. Delivery receipts, status changes and other events are not sent to an agent.

Claude Managed Agents

  1. In the Claude Console, create an agent, an environment and an API key.
  2. In Bird, create a webhook, choose Claude Managed Agents and select the messages under Triggers.
  3. Under Connect, enter the agent ID, environment ID and API key, then create the webhook.
  4. Select Send test.
  5. (Optional) To let the agent reply through Bird, open the agent in the Claude Console, select + MCP Server and pick Bird.
  6. (Optional) Open Managed Agents > Credential vaults, create a vault, select + Add credential, set Type to MCP OAuth, pick Bird and select Connect.
  7. (Optional) Enter the vault ID (it starts with vlt_) under Connect, or edit an existing webhook to add it.

Grok Bot

Choose a Bot:

Download the complete templates folder. Give Grok Bot the chosen bot.md and shared/message-safety.md as lasting instructions and ask it to remember both. Choose its Your settings options, fill its knowledge section and enable its channel skill. The skill uses the safety rules in the Bot’s instructions; it does not need files outside its installed folder. These are manual source files, not a native import manifest. Connect your booking system separately for booking enquiries; keep credentials in connection settings.

  1. Install Bird in Grok Bot and connect your workspace and mailbox or AMB business.
  2. Give Grok Bot the routine prompt from bot.md to create a routine with a webhook trigger. Open the routine’s Webhook section and copy its URL and sender key.
  3. In Bird, create a webhook, choose Grok Bot and select the incoming message events under Triggers. For the templates, use amb.received for AMB Booking Desk or email_mailbox.message_received for Email Support Desk; for email, select the mailbox too. Under Connect, paste the URL and sender key, then create the webhook.
  4. Select Send test, then send a real message to your business or mailbox.

Keep one routine owner per channel scope. Reply mode defaults to drafts; choose whether to send replies and whether bookings need your approval by editing your Bot. Before enabling automatic replies, use controlled accounts to check normal requests, missing knowledge, a foreign mailbox/business and instructions embedded in messages. Replay a message concurrently: expect one reply with the same key. Interrupt a send: expect reconciliation, not a fresh send.

For bookings, also test changed availability, repeated confirmation and an uncertain write: expect no duplicate booking or unsupported confirmation. Booking writes always require current availability, customer agreement and a successful receipt; your Bot’s setting decides whether to ask you first. With Bookings not set, it must not write a booking. Native import and live messaging/booking have not been verified for these bundles.

Create it from the CLI or API

bird webhooks create --help lists each connector with its fields, which of them are secret, the events it accepts and the setup to do first. Pass nonsecret fields with --field name=value and each secret from an environment variable with --secret-env name=ENV_VAR, or pipe it with --secret-stdin name, so it stays out of your shell history. --events defaults to every message event the connector accepts.

For Claude, create an API key in the workspace your agent runs in, then read it into the environment without echoing it, so it never appears in a command line or your shell history:

Code example
read -rs ANTHROPIC_API_KEY && export ANTHROPIC_API_KEY  # paste the key, then press Enter
bird webhooks create --connector claude_managed_agents \
  --field agent_id=agent_123 --field environment_id=env_123 \
  --field vault_id=vlt_123 --secret-env api_key=ANTHROPIC_API_KEY

The API takes the same destination on POST /v1/webhooks. Leave url out: Bird builds it from the connector. No response includes the credentials.

Test the connection

Right after creating the webhook, select Send test. Later, use Send test event on the webhook's page or in its row actions, or call POST /v1/webhooks/{webhook_id}/test. Check in Claude or Cursor that a session or run started. Then send a real message to one of your numbers or channels and confirm the agent handles it; for Claude, confirm the reply arrives on the sender's channel and the session shows no session.error.

Operate it

  • Rotate a credential. Edit the webhook and enter only the new value; a field you leave blank keeps its stored value. Through the API, send the changed key in PATCH /v1/webhooks/{webhook_id} destination.connector.credentials. The next delivery uses it, retries included.
  • Change its settings. Edit the webhook to change a setting such as the agent ID, the vault ID or a Grok Bot routine's webhook URL; the next delivery uses it. To switch platforms, create a new webhook.
  • Pause or remove it. Pausing a webhook stops its deliveries. Deleting it erases its credentials.
  • Read failures. A webhook's attempts list each delivery with the platform's response status and body, or none when the platform could not be reached. An attempt that failed before Bird sent anything, such as a connection changed after the event, carries a failure_reason instead.

Next steps