# WhatsApp and Gmail

Connect an existing WhatsApp account or Gmail / Google Workspace mailbox to RouterGrowth, then use it through REST, the CLI or MCP. Each connection belongs to your workspace. Your agent can list connections, send messages and read replies using the same RouterGrowth key.

Gmail connects a mailbox you already own. To provision a new agent inbox on your own domain, use the separate `email.domain` and `email.inbox` capabilities instead.

## Capabilities

| Capability | Action |
| --- | --- |
| `whatsapp.accounts` | List accounts and refresh connection status; free |
| `whatsapp.account` | Connect, reconnect or check status |
| `whatsapp.profile` | Look up a phone number's WhatsApp profile |
| `whatsapp.message` | Send text to a person or reply in a chat |
| `whatsapp.messages` | List conversations or read a thread |
| `gmail.accounts` | List mailboxes and refresh connection status; free |
| `gmail.account` | Connect, reconnect or check status |
| `gmail.send` | Send an email or reply to an existing email |
| `gmail.messages` | List, search or read email |

Use [inspect](/docs/api/inspect) for each capability's current schema and quote. The calls below use a live key; test keys return labeled simulated results and cannot connect or message real accounts.

## Connect once

Open **Connected accounts** in the [dashboard](/dashboard) and choose WhatsApp or Gmail. WhatsApp uses a hosted QR/pairing flow. Gmail opens Google OAuth, where the mailbox owner authorizes access. Passwords and OAuth tokens are handled by Unipile, not supplied to RouterGrowth API calls.

An agent can also request the hosted connection link:

```bash
routergrowth run -c whatsapp.accounts -i '{}'
routergrowth run -c whatsapp.account -i '{"name":"sales"}'

routergrowth run -c gmail.accounts -i '{}'
routergrowth run -c gmail.account -i '{"name":"work"}'
```

Open the returned `connect_url`, finish the provider flow, and run the same `.account` call again to confirm `connected: true`. The connection callback also updates the dashboard. If the link expires, request another one using the same name. Run `.accounts` before connecting so you reuse an existing account.

Pass `account_id` as the account's workspace name or its returned ID. You may omit it only when exactly one account of that channel is connected. WhatsApp and Gmail can both have an account named `sales`; their connections remain separate.

## WhatsApp

Look up a recipient, send a message, then read conversations:

```bash
routergrowth run -c whatsapp.profile -i '{"account_id":"sales","phone":"+14155550123"}'
routergrowth run -c whatsapp.message -i '{"account_id":"sales","phone":"+14155550123","text":"Here is the information you requested."}'
routergrowth run -c whatsapp.messages -i '{"account_id":"sales","unread":true,"limit":20}'
routergrowth run -c whatsapp.messages -i '{"account_id":"sales","chat_id":"CHAT_ID","limit":20}'
routergrowth run -c whatsapp.message -i '{"account_id":"sales","chat_id":"CHAT_ID","text":"Thanks for confirming."}'
```

Replace sample numbers and IDs with your intended recipient and returned IDs. Phone numbers must start with `+` and include a country code. Alternatively, use `provider_id` from a profile or conversation. Preserve IDs ending in `@s.whatsapp.net` or `@lid` exactly as returned. Existing chats, including supported group conversations, can be read and replied to by `chat_id`; creating or managing groups is not exposed.

`whatsapp.messages` returns `chats` when no `chat_id` is supplied, and `messages` for a thread. Pass the returned `cursor` for another page. `after` accepts an ISO 8601 timestamp with a timezone. Thread text is limited to 2,000 characters per message in the normalized response.

This integration exposes text sending. Attachments, voice notes, Channels, Communities, Broadcasts and business-template management are not exposed. WhatsApp account restrictions still apply; stop when a send returns `provider_rate_limited`.

## Gmail

Send from the connected mailbox using REST:

```bash
curl -X POST https://api.routergrowth.com/v1/run \
  -H "Authorization: Bearer $ROUTERGROWTH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: gmail-introduction-001" \
  -d '{
    "capability":"gmail.send",
    "input":{
      "account_id":"work",
      "to":["recipient@example.com"],
      "subject":"Requested information",
      "text":"Hello,\n\nHere is the information you requested."
    },
    "routing":{"provider":"unipile","max_cost":"0.01"}
  }'
```

Supply `text` or `html`. HTML takes precedence when both are present; plain text is escaped and line breaks are preserved. Optional `cc` and `bcc` are arrays of email addresses. At most 50 recipients are accepted across all three recipient lists. The connected mailbox determines the sender.

Read or search messages, then reply:

```bash
routergrowth run -c gmail.messages -i '{"account_id":"work","limit":20}'
routergrowth run -c gmail.messages -i '{"account_id":"work","search":"Requested information","from":"recipient@example.com"}'
routergrowth run -c gmail.messages -i '{"account_id":"work","message_id":"EMAIL_ID"}'
routergrowth run -c gmail.send -i '{"account_id":"work","to":["recipient@example.com"],"in_reply_to":"EMAIL_ID","text":"Thanks, received."}'
```

Use the email's `message_id` returned by `gmail.messages` for `in_reply_to`. The email must belong to the selected mailbox. If you omit `subject` on a reply, the original subject is reused. Recipients must still be supplied explicitly.

A send returns `tracking_id` and, when available, `provider_id`. The tracking ID is not an email ID: list emails to obtain `message_id`. Listing includes sent and received email, with full text and HTML bodies when available. Supported list filters are `search`, `from`, `to`, `folder`, `thread_id`, `after`, `limit` and `cursor`. `message_id` selects a single email instead of listing.

Google sending quotas apply. Attachments, drafts, label changes, deletion and Calendar operations are not exposed by this release. Read replies by polling `gmail.messages`; these capabilities do not deliver incoming-message webhooks to your application.

## Billing and retries

Account listings, connection links, reconnection and status checks settle free. A connection call may reserve the standard minimum before releasing it. Each connected WhatsApp or Gmail account costs **$9.625 per 30 days**, charged to your RouterGrowth balance until disconnected. Successful sends are **$0.00875** each; profile and inbox reads use the **$0.002** minimum under the current pricing configuration. Inspect always gives the current quote. The monthly account charge is separate from per-call charges. An empty inbox is a successful read; failed sends are not billed.

Use a unique `Idempotency-Key` on REST send calls and reuse it when retrying the same operation. Do not retry an uncertain send with a new key: it may have reached the recipient. The adapter does not automatically retry sends.

## Account management API

| Method | Endpoint | Authentication |
| --- | --- | --- |
| GET | `/v1/whatsapp/accounts` or `/v1/gmail/accounts` | Workspace key or dashboard session |
| POST | `/v1/whatsapp/accounts` or `/v1/gmail/accounts` | Dashboard session; body contains `name` and optional `return_url` |
| DELETE | `/v1/whatsapp/accounts/{name}` or `/v1/gmail/accounts/{name}` | Dashboard session |

The GET routes show recorded status; `.accounts` capabilities also refresh status from Unipile. Account creation and deletion through these REST management routes require a dashboard session, not an API key. Agents use the `.account` capability to request a connection link. A management-route `return_url` must use the RouterGrowth dashboard origin.

Disconnect from the dashboard to release the Unipile connection and stop future RouterGrowth account charges. This does not delete your WhatsApp account or Google mailbox.

## Provider setup

The server uses the existing `UNIPILE_DSN` and `UNIPILE_API_KEY`. Its public connection callback must be reachable. Gmail uses Unipile's hosted Google OAuth credentials by default; custom branded Google OAuth is optional and requires configuration in Unipile. Verify that Gmail read/send access is enabled in the subscription's Google OAuth settings before testing with a real mailbox. No new RouterGrowth Google client secret is required for the default hosted flow.

Provider references: [hosted authentication](https://developer.unipile.com/docs/hosted-auth), [WhatsApp identifiers](https://developer.unipile.com/docs/users-overview), [email sending](https://developer.unipile.com/docs/send-email), [email retrieval](https://developer.unipile.com/docs/retrieving-emails), [Google OAuth](https://developer.unipile.com/docs/google-oauth).
