Channels and fallback API

iMessage, SMS and email next to WhatsApp, sends that fall back between them, and AI conversation summaries by email. 7 ops: connect_channel, list_channels, disconnect_channel, send_routed_message, get_message_route, list_message_routes, get_contact_channels.

iMessage, SMS and email next to WhatsApp, sends that fall back between them, and AI conversation summaries by email.

connect_channel

writeowner or admin

Connect iMessage, SMS or email · POST /api/v1/connect_channel · scope channels:write

Connects a channel next to WhatsApp: iMessage through a bridge (provider bridge: base_url and api_token of a Mac running Rio, Photon or any bridge implementing Wabi's bridge contract), SMS through the organization's own Twilio account (provider twilio: account_sid, auth_token and the number or messaging_service_sid), email through AgentMail (provider agentmail: give username and Wabi creates a managed inbox, or api_key and address for an inbox of your own), or a free simulated one (provider sandbox). Wabi registers its webhook with the provider when it can and returns `webhook` with the URL and, when it could not, what to set by hand. Credentials are encrypted and never returned. Then send_routed_message and reply_to_conversation use it, and inbound messages on it land in the inbox.

curl -X POST https://getwabi.dev/api/v1/connect_channel \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"channel":"imessage","provider":"bridge"}'

List channels · POST /api/v1/list_channels · scope channels:read or GET …?input=

Lists the organization's iMessage, SMS and email connections (no secrets): channel, provider, sender address, webhook URL, status and when the last webhook arrived. WhatsApp numbers are list_whatsapp_accounts.

curl -X POST https://getwabi.dev/api/v1/list_channels \  -H "Authorization: Bearer wabi_…"

disconnect_channel

writeowner or admin

Disconnect a channel · POST /api/v1/disconnect_channel · scope channels:write

Disconnects an iMessage, SMS or email connection: its credentials are deleted, routed sends stop using it and its webhooks are refused. Messages already sent keep their history. Connect again with connect_channel.

curl -X POST https://getwabi.dev/api/v1/disconnect_channel \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"channel_id":"6f1c2e0a-4b7d-4c2e-9a51-0d3b8e7f9a10"}'

Send with fallback across channels · POST /api/v1/send_routed_message · scope channels:write

Sends one message to a customer over the best channel, falling back to the next when one cannot deliver: by default iMessage → WhatsApp → SMS → email, over the organization's connected channels. Address them by phone (to), email, or contact_id; channels the contact has no address for are left out. It skips channels this contact was definitively unreachable on lately, tries the channel they last wrote on first, asks the iMessage bridge whether the number is on iMessage before sending (when the bridge can tell), and falls back at once on a definitive failure (not on iMessage, not on WhatsApp, a landline, a bounce, a WhatsApp safeguard such as a closed window) or after fallback_after_seconds without a delivered receipt. Returns the route: its steps, each attempt's outcome and message, and status routing → delivered | failed | unconfirmed. Poll get_message_route or subscribe to the route.completed webhook. Use idempotency_key to make retries safe.

curl -X POST https://getwabi.dev/api/v1/send_routed_message \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"text":"Hi, where is my order?"}'

Get a routed send · POST /api/v1/get_message_route · scope channels:read or GET …?input=

Returns one routed send (send_routed_message): status, the channel that delivered, each step with its outcome (sent, delivered, failed, timed_out, skipped) and the reason, the planning notes, and every attempt's message with its status timeline fields.

curl -X POST https://getwabi.dev/api/v1/get_message_route \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"route_id":"6f1c2e0a-4b7d-4c2e-9a51-0d3b8e7f9a10"}'

List routed sends · POST /api/v1/list_message_routes · scope channels:read or GET …?input=

Lists recent routed sends, newest first, optionally for one contact or status.

curl -X POST https://getwabi.dev/api/v1/list_message_routes \  -H "Authorization: Bearer wabi_…"

Which channels reach a contact · POST /api/v1/get_contact_channels · scope channels:read or GET …?input=

What Wabi learned about one contact per channel (WhatsApp, iMessage, SMS, email) from what actually happened: reachable (a message was delivered or they wrote on it), unreachable (a definitive failure, skipped by routing until it expires) or unknown, with the last delivered, inbound and failed times, and the channel they last wrote on. Give contact_id, phone or email.

curl -X POST https://getwabi.dev/api/v1/get_contact_channels \  -H "Authorization: Bearer wabi_…"