---
title: "Add a WhatsApp account"
method: POST
path: "/v3/channels/whatsapp"
tags: ["Channels"]
---

# Add a WhatsApp account

`POST /v3/channels/whatsapp`

## Request

- Base URL: `https://api.sent.dm`
- URL: `https://api.sent.dm/v3/channels/whatsapp`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

Connects a WhatsApp Business Account shared with us through a Multi-Partner Solution to the calling sender profile. Send `x-profile-id` for the profile the account belongs to.

**Two fields, because everything else is derived.** `waba_id` says which of your organization's shared accounts this is — you hold one per client, and nothing else can say which. `phone_number_id` names the account's number, which is what assigns it to the profile as the number it sends from.

The solution the account arrived through, the client business portfolio that owns it, the access token and its expiry are all resolved from your organization. They are not accepted here: the first two are Meta's answer about provenance, and the token is minted per client business and rotates roughly every sixty days, so a value you sent would be stale before it was useful.

`phone_number_id` is optional. Omit it to connect the account now and settle the number later — the channel reads as `ACTION_NEEDED` with `reason_code` `CHANNEL_007`, and the profile's WhatsApp messages fail until a number is named. They do not fall back to your organization's account. Call this endpoint again with `phone_number_id` to name one.

The same resolution runs behind `channels.whatsapp` on `POST /v3/sender-profiles`, so connecting at create and connecting afterwards fill the same fields.

Returns **the account**, not every channel you have — adding one cannot change a market or an RCS agent, and `GET /v3/channels` is the whole picture. Giving an account up is not self-service: ask support, because deregistering a number lands in your own Meta business.

## Headers

- `Idempotency-Key` string
- `x-profile-id` string, uuid

## Request body

- SentDmServicesEndpointsCustomerAPIv3ChannelsRequestsAddWhatsappChannelRequest: Connects a WhatsApp Business Account shared through a Multi-Partner Solution. The same two fields channels.whatsapp takes on POST /v3/sender-profiles, so a block lifts verbatim between them and both resolve the rest the same way — the solution the account arrived through, the client business portfolio that owns it, the access token and its expiry all come from the organization rather than from the request. Only these two cannot be inferred: the organization holds one account per client, so nothing but the caller says which is meant, and the account's number is assigned to the profile only when the caller names it.
  - `sandbox` boolean: Sandbox flag - when true, the operation is simulated without side effects Useful for testing integrations without actual execution
  - `waba_id` string, required: WhatsApp Business Account id — one of the accounts shared into your organization. Required: the organization holds one per client, and nothing but the caller says which is meant here.
  - `phone_number_id` string, nullable: The Meta phone-number id of the number on WabaId, which assigns it to this profile as the number it sends from. It is not checked against the account here, so name the account's number; it is refused if another profile already uses it. Optional: omit it to connect the account and settle the number later. Nothing picks one on your behalf.

## Response `200`

The account is connected to the profile

- SentDmServicesEndpointsCustomerAPIv3SharedApiResponseOfWhatsappChannelState: Standard API response envelope for all v3 endpoints
  - `success` boolean: Indicates whether the request was successful
  - `data` SentDmServicesCommonChannelsContractsWhatsappChannelState: The profile's WhatsApp account. Its status is Meta's verification state.
    - `waba_id` string, nullable
    - `phone_number_id` string, nullable: The Meta phone-number id the profile sends from, or null when the account is connected but no number has been named yet — which is what a provisioning status means here.
    - `solution_id` string, nullable: Derived, not echoed. The request no longer accepts this — it is read off the organization's shared-account listing at connect time and reported back so a caller can see which partnership the account actually arrived through.
    - `owner_business_id` string, nullable: Derived from the organization's shared-account listing, like SolutionId.
    - `status` 'PROVISIONING' | 'ACTION_NEEDED' | 'PENDING_REVIEW' | 'ACTIVE' | 'INACTIVE', nullable: Read-only. Never carries a token — the row holds that and it is not returned. ACTION_NEEDED when no account is connected or the account has no phone number: both are yours to do.
    - `reason_code` string, nullable: Why the account is not ACTIVE, as a stable code: an ErrorCodes CHANNEL_xxx value such as CHANNEL_001 (something you owe) or CHANNEL_009 (under review). Switch on this rather than on reason. Omitted while ACTIVE. Read-only; when nothing more specific is known it is the generic reason for the status.
    - `reason` string, nullable: A sentence for reason_code, saying what to do where it is yours. Omitted while ACTIVE.
  - `error` SentDmServicesEndpointsCustomerAPIv3SharedApiError: Error information
    - `code` string: Machine-readable error code (e.g., "RESOURCE_001")
    - `message` string: Human-readable error message
    - `details` object, nullable: Additional validation error details (field-level errors)
    - `doc_url` string, nullable: URL to documentation about this error
  - `meta` SentDmServicesEndpointsCustomerAPIv3SharedApiMeta: Request and response metadata
    - `request_id` string: Unique identifier for this request (for tracing and support)
    - `timestamp` string, date-time: Server timestamp when the response was generated
    - `version` string: API version used for this request

## Other responses

- `400`: waba_id is missing, the call was not scoped to a sender profile with x-profile-id, the account is not one this organization can reach, Meta would not issue a token for it, or the number is already in use by another profile
- `401`: Unauthorized
- `403`: Forbidden
- `500`: The account was connected but could not be read back

## Changes

- **2026-10-16** `6c829543a93e`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/sentdm/apis/sent-dm-api-v3/changes/v3/channels/whatsapp/post.md)

---

[API](https://skmtc.dev/sentdm/apis/sent-dm-api-v3.md) - [All operations](https://skmtc.dev/sentdm/apis/sent-dm-api-v3/llms.txt) - [OpenAPI document](https://skmtc.dev/sentdm/apis/sent-dm-api-v3/revisions/bdcca958cac7?raw)
