> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fonoster.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Link a WhatsApp Business number

> Link a WhatsApp Business number from the dashboard or the CLI, and send the calls WhatsApp users make to it to an agent, an app or a SIP agent.

Link a WhatsApp Business number, and calls from WhatsApp users reach the agent, app or SIP agent
you choose. Fonoster sets up a SIP trunk to Meta in your workspace and, with a Meta access token,
turns on SIP calling for the number in Meta and points it at Fonoster. You can also place outbound
calls to a WhatsApp user from it, once that user has granted call permission.

## Before you begin

You need:

* A WhatsApp Business number with Meta's
  [Calling API](https://developers.facebook.com/docs/whatsapp/cloud-api/calling) enabled for it.
  Calling is a Meta feature with its own eligibility; Fonoster can't request it for you.
* The number's **Phone number ID**, from WhatsApp Manager under **Phone numbers**, or from the
  App Dashboard under **API Setup**.
* A Meta **System User access token** with the `whatsapp_business_management` permission.
  Fonoster uses it twice, to read the number and to turn on SIP calling, and doesn't store it. If
  you'd rather not hand over a token, see
  [Link with the SIP password instead](#link-with-the-sip-password-instead).
* An agent, an app or a SIP agent to send calls to. See
  [Build an Autopilot agent](https://docs.fonoster.com/autopilot/build-an-agent.md) or
  [Build a stream with the Voice SDK](https://docs.fonoster.com/streams/voice-sdk.md).
* For the CLI: [Node.js](https://nodejs.org/) 22 or later.

## Link the number

**Dashboard**

**1. Open the link drawer**

Go to **Numbers**, click **Link number**, then **WhatsApp number**.

**2. Choose where calls go**

Under **When this number is called, send it to**, pick the agent, app or SIP agent.

**3. Enter the Meta credentials**

Under **Credentials**, keep **Meta access token** selected. Enter the **Phone number ID**
and the **Access token**.

**4. Link it**

Click **Link number**. The drawer shows the number, its verified business name, and that
SIP calling is on in WhatsApp, pointed at Fonoster with SDES. The number shows in the list
on its **WhatsApp Trunk**.

WhatsApp now sends the number's calls to Fonoster.

If the number is already in your workspace, linking moves it to its WhatsApp trunk and the
route you choose. A new number is named after Meta's verified name; rename it under
**Numbers**.

**CLI**

**1. Install the CLI and log in**

In the dashboard, go to **API keys** and create a key. Then install the `fonoster` CLI and log
in to your workspace with the key ID and secret:

```bash theme={"system"}
npm install -g @fonoster/ctl
fonoster workspaces:login
```

**2. Run the link command**

Start the command with the number's Phone number ID:

```bash theme={"system"}
fonoster sipnet:numbers:linkWhatsApp --phone-number-id 106612345678901
```

It asks only for what your flags leave out:

| Prompt | What to enter | Flag |
| - | - | - |
| Application | The Autopilot agent or stream that answers the number. Pick **None** to choose later. To send calls to a SIP agent, pass `--agent` instead. | `--app <ref>` or `--agent <aor>` |
| Meta access token | Your System User token, typed without echo. | The `META_ACCESS_TOKEN` variable |

The number is named after Meta's verified name. To name it yourself, pass
`--name "Support desk"`.

Confirm the link. The command prints the number and its trunk, and that Meta is set up:

```text theme={"system"}
Linked +525512345678 (Acme Dental) (number 7d1c3b2a-5e4f-4a6b-8c9d-0e1f2a3b4c5d) on WhatsApp Trunk +525512345678 (a91e0f44-2b3c-4d5e-8f6a-7b8c9d0e1f2a).
SIP calling is on in WhatsApp, pointed at wa-wo7d2kq9x4m1c8b3n6p0r5t2v9y4z7a1e3-525512345678.pstn.fonoster.ai:5061 with SDES.
```

**3. Check the number**

List your numbers. The linked number is there, on its **WhatsApp Trunk**, pointing at the
application you picked:

```bash theme={"system"}
fonoster sipnet:numbers:list
```

Call the business from WhatsApp. Your agent, app or SIP agent answers.

> [!TIP]
>
> Your WhatsApp Business number rings in Fonoster.

### Link from a script

Without a terminal, the command never prompts: pass every value as a flag and the token in an
environment variable. This links a number to an application:

```bash theme={"system"}
export META_ACCESS_TOKEN=...
fonoster sipnet:numbers:linkWhatsApp \
  --phone-number-id 106612345678901 \
  --app 4a2f8c1e-0b7d-4a51-9e3c-2f6d7a1b9c00 \
  --yes
```

A missing token stops the command with exit code 1 and `Set META_ACCESS_TOKEN to link without a
terminal.`; a missing `--yes` stops it with `Pass --yes to link without confirmation.`

## Link with the SIP password instead

If you don't want to give Fonoster a Meta token, link the number by itself and set up Meta by hand.
Fonoster then calls no Meta API.

**1. Link the number in Fonoster**

In the dashboard, under **Credentials** choose **SIP password** and enter the **Number** in
E.164, leaving the password empty for now. Or run:

```bash theme={"system"}
fonoster sipnet:numbers:linkWhatsApp +525512345678 --app <ref>
```

Leave the password prompt empty. Both print the SIP server to register:

```text theme={"system"}
Linked +525512345678 (number 7d1c3b2a-…) on WhatsApp Trunk +525512345678 (a91e0f44-…).
Register this SIP server in WhatsApp Manager: wa-wo7d2kq9x4m1c8b3n6p0r5t2v9y4z7a1e3-525512345678.pstn.fonoster.ai (port 5061).
SIP password: not set yet. Run the command again with WHATSAPP_SIP_PASSWORD once you have it from Meta.
```

**2. Point Meta at Fonoster**

In WhatsApp Manager, open the number's **Call settings**, then **Developer settings**, turn on
**Use Session Initiation Protocol (SIP)** and click **Set up**. Enter the SIP server Fonoster
printed as the hostname (there is no port field; Meta uses 5061) and your Meta app's **App
ID**, which can't be edited later. See Meta's
[SIP guide](https://developers.facebook.com/docs/whatsapp/cloud-api/calling/sip).

Fonoster's trunks negotiate SRTP with SDES, and Meta's default is DTLS, so set it with your
token:

```bash theme={"system"}
curl -X POST "https://graph.facebook.com/v23.0/<PHONE_NUMBER_ID>/settings" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"calling":{"srtp_key_exchange_protocol":"SDES"}}'
```

Then read the SIP password Meta issued for the number (WhatsApp Manager doesn't show it):

```bash theme={"system"}
curl "https://graph.facebook.com/v23.0/<PHONE_NUMBER_ID>/settings?include_sip_credentials=true" \
  -H "Authorization: Bearer $META_ACCESS_TOKEN"
```

The password is `calling.sip.servers[].sip_user_password` in the response.

**3. Set the password in Fonoster**

Link the number again with the password. In the dashboard, open **Link number** → **WhatsApp
number** again, choose **SIP password**, enter the same number and the password. Or:

```bash theme={"system"}
WHATSAPP_SIP_PASSWORD=... fonoster sipnet:numbers:linkWhatsApp +525512345678 --app <ref> --yes
```

The last line now reads `SIP password: set.`

> [!TIP]
>
> Your WhatsApp Business number rings in Fonoster.

## What linking sets up

Linking names everything after your workspace's access key ID in lowercase, shown here as
`wo7d2kq9x4m1c8b3n6p0r5t2v9y4z7a1e3`, and the number's digits.

**In Fonoster:**

* A trunk named **WhatsApp Trunk +525512345678**, with the inbound URI
  `wa-wo7d…-525512345678.pstn.fonoster.ai` (one hostname per linked WhatsApp number) and an
  outbound URI to `wa.meta.vc:5061` over TLS. Meta sends the number's calls to the inbound URI;
  Fonoster sends your outbound calls to Meta.
* A credential named **WhatsApp +525512345678** on that trunk, with the number's digits as the
  username and the SIP password Meta issued.
* The number, on that trunk, pointing at the application you picked.

**In Meta** (with a token, or by hand): SIP calling on for the number, with the trunk's inbound
URI as its SIP server and SRTP set to SDES.

If the number is already in your workspace, linking moves it to its WhatsApp trunk and the route
you choose. To link more WhatsApp numbers, link each one: every number gets its own trunk and
credential, since Meta issues one SIP password per number.

If you disable and re-enable SIP in Meta, Meta issues a new password. Link the number again with
the token, or with the new password, and Fonoster updates the credential in place.

## Change where calls go

The linked number is a normal number in your workspace. To send its calls somewhere else, go to
**Numbers**, open it, and pick a new destination under **When this number is called, send it to**.
See [Numbers and routing](https://docs.fonoster.com/telephony/numbers.md).

## On your own install

Meta reaches your install over SIP over TLS only. A self-hosted Fonoster must accept SIP over TLS
on `5061` with a certificate that covers `*.pstn.<domain>`, and reach `wa.meta.vc:5061` outbound.
Set that up first: [SIP over TLS](https://docs.fonoster.com/self-hosting/https.md#sip-over-tls) and
[Carriers and phones](https://docs.fonoster.com/self-hosting/carriers-and-phones.md). Linking fails with
`This install has no public SIP over TLS address for WhatsApp to send calls to` until the install
declares one.

## Troubleshooting

* **`Meta didn't accept this access token`.** The token is wrong, expired or revoked. Generate a
  new System User token.
* **`This access token can't manage WhatsApp calling settings`.** The token lacks
  `whatsapp_business_management`. Use a System User token with that permission.
* **`No WhatsApp number with id … is reachable with this access token`.** Check the Phone number ID,
  and that the token's System User has access to the number's WhatsApp Business Account.
* **`The number is on messaging tier …`.** Meta requires a messaging limit of 2,000 or more for
  calling. See Meta's [Calling API](https://developers.facebook.com/docs/whatsapp/cloud-api/calling)
  eligibility.
* **`Meta didn't accept … as the SIP server`** or **`Meta is unavailable; try again`.** Try again in
  a few minutes.
* **`… is already linked in another workspace`** or **`… is already in use`.** The number, or its
  hostname, belongs to another workspace on this install. Link it from that workspace.
* **Calls don't arrive.** With the password path, the hostname registered in WhatsApp Manager must
  match the one Fonoster printed, SRTP must be set to SDES, and the password must be set (the
  command's last line says `SIP password: not set yet` until it is).
* **Outbound calls fail.** A WhatsApp user must grant your business
  [call permission](https://developers.facebook.com/documentation/business-messaging/whatsapp/calling/user-call-permissions)
  before you can call them, and Meta restricts calling in some
  [countries](https://developers.facebook.com/documentation/business-messaging/whatsapp/support#country-restrictions).
  Fonoster doesn't request call permission for you.
* **Transfers with mode `refer` don't work on WhatsApp calls.** Meta doesn't accept SIP REFER. Use
  a cold or warm transfer instead. See [Transfer calls](https://docs.fonoster.com/telephony/transfers.md).

## Next steps

> **[Numbers and routing](https://docs.fonoster.com/telephony/numbers.md)**
>
> Send each number to the right agent, stream or SIP agent.

> **[Make outbound calls](https://docs.fonoster.com/telephony/outbound-calls.md)**
>
> Call WhatsApp users who granted call permission.

> **[SIP over TLS](https://docs.fonoster.com/self-hosting/https.md#sip-over-tls)**
>
> What your own install needs before Meta can reach it.

> **[Link a Twilio number](https://docs.fonoster.com/telephony/link-twilio.md)**
>
> Bring a number from Twilio the same way.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.