# Numbers and Embedded Signup

> Connect WhatsApp numbers with Embedded Signup, an existing WABA token, or a hosted link; connection states and what makes a number connected.

Canonical: https://docs.whabuzz.com/guides/numbers/

A **number** is a WhatsApp Business phone number registered on a WhatsApp Business Account (WABA). Its id is the Meta `phone_number_id`, which you pass as `from` when sending. The resource is read with [`GET /v1/numbers`](https://docs.whabuzz.com/api/numbers.md#listNumbers) and [`GET /v1/numbers/{phone_number_id}`](https://docs.whabuzz.com/api/numbers.md#getNumber).

There are three ways to connect one. All end in the same state.

| You are | Use |
|---|---|
| A business connecting your own number, in the console | Embedded Signup in the console (it calls the first endpoint below for you) |
| A developer who already has a WABA and a token | [`connect`](#connect-existing) |
| A platform connecting your customers' numbers | [hosted connect session](#hosted-link) |

## Embedded Signup {#embedded-signup}

Meta's Embedded Signup is a popup run in a browser. The person logs in with Facebook, picks or creates a WABA, adds a number, and verifies it by SMS or voice. When it closes, the page receives a one-time `code` and the ids of the WABA and phone number.

Send those to [`POST /v1/numbers/embedded-signup`](https://docs.whabuzz.com/api/numbers.md#completeEmbeddedSignup):

```json
{ "code": "AQD…", "waba_id": "26059971920328384", "phone_number_id": "1013622581841046" }
```

WhaBuzz exchanges the code for a business token, checks it (the token must belong to our Meta app, carry `whatsapp_business_management` and `whatsapp_business_messaging`, and cover this WABA), stores the token encrypted, subscribes the WABA to our webhooks, and registers the number. The token never reaches your server.

## Connect an existing WABA {#connect-existing}

[`POST /v1/numbers/connect`](https://docs.whabuzz.com/api/numbers.md#connectExisting) takes the `waba_id` and either a system-user `access_token`, or an Embedded Signup `code`. WhaBuzz runs the same token checks, then connects the numbers on that WABA.

```bash
curl -X POST https://api.whabuzz.com/v1/numbers/connect \
  -H "Authorization: Bearer $WHABUZZ_KEY" -H "Content-Type: application/json" \
  -d '{"access_token":"EAAG…","waba_id":"26059971920328384"}'
```

A token rejected by those checks answers `422 invalid_request` with the failing check in `details`.

## Hosted link for your customers {#hosted-link}

Platforms should not run Meta's popup in their own app. Create a session:

```bash
curl -X POST https://api.whabuzz.com/v1/connect-sessions \
  -H "Authorization: Bearer $WHABUZZ_APP_KEY" -H "X-WhaBuzz-Tenant: $TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{"return_url":"https://yourapp.example/whatsapp/done"}'
```

The response carries `url` (`https://app.whabuzz.com/connect/<token>`), valid for one hour. Send your customer there. After the popup, they are redirected to `return_url?session_id=…&status=connected` (or `failed`). Poll [`GET /v1/connect-sessions/{session_id}`](https://docs.whabuzz.com/api/connect-sessions.md#getConnectSession) or wait for the `number.connection` event ([WhaBuzz events](https://docs.whabuzz.com/events/whabuzz-events.md)).

## Connection state {#connection-state}

A number is `connected` only when all of these hold:

1. The WABA is subscribed to WhaBuzz's webhooks.
2. The number is registered with Meta.
3. At least one of your webhook endpoints is `active` and subscribed to `message.inbound` or `*`.
4. The business token is not invalid.
5. The tenant is `active`.

Otherwise the state is `pending` (never completed) or `disconnected`, and `connection_detail` says why: `waba_not_subscribed`, `not_registered`, `no_verified_endpoint`, `token_invalid` or `tenant_inactive`. Sending from a number that is not connected answers `409 number_not_connected` with that detail. Fix the detail, and the state recovers by itself; each change emits a `number.connection` event.

## Maintenance calls {#maintenance}

These pass through to Meta with the number's stored token:

- [`register`](https://docs.whabuzz.com/api/numbers.md#registerNumber) and [`deregister`](https://docs.whabuzz.com/api/numbers.md#deregisterNumber)
- [`request-code`](https://docs.whabuzz.com/api/numbers.md#requestVerificationCode) and [`verify-code`](https://docs.whabuzz.com/api/numbers.md#verifyCode) (SMS or voice)
- [`two-step`](https://docs.whabuzz.com/api/numbers.md#setTwoStepPin) sets the six-digit PIN
- [`subscribe`](https://docs.whabuzz.com/api/numbers.md#resubscribeWaba) re-subscribes the WABA if the state shows `waba_not_subscribed`
- [`business-profile`](https://docs.whabuzz.com/api/numbers.md#getBusinessProfile) read and [update](https://docs.whabuzz.com/api/numbers.md#updateBusinessProfile)
- [`migrate`](https://docs.whabuzz.com/api/numbers.md#migrateNumber) moves a number between WABAs you control

Because they are Meta calls, their errors come back as `"source":"meta"`.
