> ## Documentation Index
> Fetch the complete documentation index at: https://koreai-ai-for-service-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Set up WhatsApp

<Badge icon="arrow-left" color="gray">[Back to messaging or digital channels](/agent-platform/channels#messaging-or-digital)</Badge>

Connect your agent to a WhatsApp Business sender so customers reach it from WhatsApp. Artemis reaches WhatsApp through a Business Solution Provider, and the provider you choose decides which credentials you collect, which webhook route you register, and where the sender lives.

## Choose a provider first

The provider selector changes the whole setup rather than one field. Pick the provider before you collect anything, and keep the identifier, credentials, webhook route, and provider-side sender on that single path. Credentials from one provider never work with another's route.

| Provider           | Routing identifier                                      | Credentials                                                                                         |
| ------------------ | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Meta Cloud API** | Phone Number ID                                         | Access Token and Phone Number ID for outbound, App Secret and Verify Token for inbound verification |
| **Infobip**        | WhatsApp phone number, digits only                      | Base URL with an API key or basic auth, plus a network allowlist for inbound verification           |
| **Gupshup**        | Business number the provider sends in the callback body | API username and password, plus an optional bearer token secret for inbound verification            |

Each provider also has its own webhook route. Meta uses the generic WhatsApp route, while Infobip and Gupshup each add their provider slug to the URL. Copy the route that matches the provider you selected in Artemis rather than assuming one URL serves all three.

The rest of this article follows Meta Cloud API, which is the path most projects start on because Meta issues a test sender and test credentials without a business account.

## Set up the Meta app

Everything in this section happens in Meta, before you open Artemis. Work through it in order, because each screen depends on the one before it. Meta covers the same ground in its own words in the [Cloud API get started guide](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started).

<Steps>
  <Step title="Register as a Meta developer">
    Go to [Meta for Developers](https://developers.facebook.com/) and sign in with your Facebook account. Meta walks you through developer registration the first time, which asks you to confirm an email address and a phone number.

    A personal Facebook account gets you started. You need a Meta Business portfolio only when you move past the test sender.
  </Step>

  <Step title="Create the app">
    Open [My Apps](https://developers.facebook.com/apps/) and select **Create App**.

    Meta asks what you want the app to do. Choose the business messaging use case, or choose **Other** and then **Business** as the app type if Meta shows you that older flow. The app type matters, because only a business app exposes the WhatsApp product.

    Enter an app name and a contact email, attach a Meta Business portfolio if you have one, and create the app. Meta opens the App Dashboard.
  </Step>

  <Step title="Add the WhatsApp product">
    On the App Dashboard, scroll the **Add products to your app** list to **WhatsApp** and select **Set up**. If you've navigated away from that screen, the left menu carries an **Add product** entry that returns you to the same list.

    Meta provisions several things at once: a test WhatsApp Business Account, a test business phone number that reaches up to five verified recipients at no cost, and a set of pre-approved message templates. The left menu now shows a **WhatsApp** section containing **API Setup** and **Configuration**, which are the two screens you'll use.

    All of this is test infrastructure. It works for development and none of it works for production.
  </Step>

  <Step title="Find the Access Token and Phone Number ID">
    Go to **WhatsApp** -> **API Setup** in the left menu. This screen carries most of what Artemis needs.

    Select **Generate access token** and complete the prompt, then copy the token. Meta issues a fresh one each time you open this panel, and it expires within 24 hours.

    Below the **From** field, Meta shows the test business phone number, and directly beneath that, a numeric **Phone Number ID**. Copy the ID.

    <Warning>The Phone Number ID isn't the phone number. It's Meta's internal identifier for the sender, and entering the displayed number instead is the most common reason a connection never receives traffic. The two values sit next to each other on this screen, which is exactly why they get swapped.</Warning>

    See [Create a permanent access token](#create-a-permanent-access-token) before you move past testing.
  </Step>

  <Step title="Find the App Secret">
    The App Secret lives outside the WhatsApp section, so the left menu is the only way to reach it. Go to **App settings** -> **Basic**.

    Select **Show** beside **App secret**. Meta asks you to re-enter your Facebook password, then reveals the value. Copy it.

    Meta signs every inbound callback with this secret, and Artemis checks that signature. A wrong value here means every inbound message fails verification even though the webhook itself verified successfully, which makes it a confusing failure to diagnose later.
  </Step>

  <Step title="Choose a Verify Token">
    Choose any secret string. Meta doesn't issue this one, so you invent it and use the same value in two places: the Artemis connection, and the webhook configuration in Meta. A mismatch fails webhook verification.

    Treat it as a secret rather than a label, and store it where you can retrieve it, because Meta shows it back to you only while you edit the webhook.
  </Step>

  <Step title="Add a test recipient">
    While the app stays in development mode, Meta delivers only to numbers you register, so your own number receives nothing until you add it.

    Return to **WhatsApp** -> **API Setup**. Select the **To** field, choose **Manage phone number list**, and add your WhatsApp number. Meta sends a confirmation code in WhatsApp, which you enter to verify the number.

    You can register up to five recipients. Select your number in the **To** field once it verifies.
  </Step>
</Steps>

## Create the channel connection in Artemis

Create the connection before you register the webhook in Meta. Provider callbacks can arrive as soon as you save the webhook, and the runtime has to resolve an inbound sender to a saved connection before it can authenticate the event.

<Steps>
  <Step title="Enter the connection details">
    Open Artemis, select the project, and go to **Deployments** -> **Channels** -> **WhatsApp** -> **+ New**.

    | Field                              | What it controls                                                                                                                                                                                                                             |
    | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Display Name**                   | The label operators see in the connections list. Name it for the sender and the environment it serves, because a project can hold several WhatsApp connections. Routing ignores this value.                                                  |
    | **Phone Number ID**                | Routes inbound messages to this connection. The runtime matches the sender identifier on each callback to this value, so a wrong entry here produces a connection-not-found result rather than an authentication error.                      |
    | **Provider**                       | Selects the Business Solution Provider. It decides which credential fields the dialog shows and which webhook route you register later, so set it before you fill in anything below it.                                                      |
    | **Access Token**                   | Authenticates every outbound message Artemis sends.                                                                                                                                                                                          |
    | **Phone Number ID**                | Identifies the sender on outbound messages. For Meta Cloud API this takes the same value as the routing identifier above.                                                                                                                    |
    | **App Secret**                     | Verifies the signature Meta puts on each inbound callback. Without it, Artemis can't confirm that a callback came from Meta.                                                                                                                 |
    | **Verify Token**                   | The string you chose. Meta echoes it during the webhook handshake, and Artemis compares the two.                                                                                                                                             |
    | **Environment**                    | The published environment whose active deployment answers incoming messages. Leave the default to use the working copy while you develop, and bind the connection to an environment later from the **Deployment** tab.                       |
    | **Provider Verification Strength** | How far the runtime trusts the provider's identity assertion when it links a sender to an existing session. Choose **Strong** only when you trust the provider's assertions enough to base continuity and account-linking decisions on them. |
    | **Initial Status**                 | Whether the connection starts handling messages. **Active** takes traffic immediately. **Inactive** saves the configuration in a disabled state, which suits a connection you're staging ahead of a launch.                                  |

    <Tip>Meta Cloud API asks for the Phone Number ID twice, once as the routing identifier and once as an outbound credential. Enter the same value in both. Other providers use different values in each field, which is why they stay separate.</Tip>

    Select **Create**.
  </Step>

  <Step title="Copy the webhook URL">
    Open the connection and copy the **Webhook URL** from the **Overview** tab.

    The URL carries the route for the provider you selected, so copy it rather than constructing it. If the dialog reports that the runtime URL is unavailable, configure Runtime first, then reopen the connection.
  </Step>
</Steps>

## Configure the webhook in Meta

The webhook is what turns a one-way integration into a conversation. Until Meta has a callback URL, your agent can send but never receives.

<Steps>
  <Step title="Register the callback URL">
    In your Meta app, go to **WhatsApp** -> **Configuration** in the left menu. The **Webhook** row sits at the top of this screen.

    Select **Edit**. Meta opens a dialog with two fields. Paste the Artemis **Webhook URL** into the callback URL field, and the same **Verify Token** you entered in Artemis into the verify token field.

    Select **Verify and save**. Meta immediately calls the URL with a challenge and expects your verify token back, so the dialog stays open with an error when the handshake fails. A dialog that closes means the URL verified.
  </Step>

  <Step title="Subscribe to message events">
    Verification alone delivers nothing. Below the webhook row, find the webhook fields list, select **Manage**, and subscribe to the **messages** field.

    Meta verifies the URL whether or not you subscribe to anything, so a verified webhook with no subscription looks correct on screen and still sends your agent no traffic. Check this first when the setup looks right and nothing arrives.
  </Step>
</Steps>

## Test the connection

Artemis doesn't synthesize provider callbacks, so a real WhatsApp message is the only way to confirm the integration works end to end.

<Steps>
  <Step title="Send an inbound message">
    From a WhatsApp account you registered as a test recipient, send the business sender a short message you can search for later. A distinctive string makes the message easy to find in session records.
  </Step>

  <Step title="Confirm a single reply">
    Check that the agent replies once, from the intended sender and the intended environment. Duplicate replies point to duplicate provider subscriptions, another automation on the same number, or repeated webhook delivery rather than an agent fault.

    If no reply arrives, open **Sessions** and search for the message you sent. A session that exists tells you the webhook works and the outbound path failed, while no session tells you nothing reached the runtime at all. The two need different fixes, so make this check before you change any configuration.
  </Step>

  <Step title="Exercise interactive outputs">
    If the agent sends buttons or lists, select a button and a list row and confirm the action returns to the same session. WhatsApp limits how many reply buttons a message carries and how long their labels run, so check that your authored content renders in WhatsApp rather than only in preview.
  </Step>

  <Step title="Exercise each enabled media type">
    Test only the message types your provider enables, then confirm the agent handles the downloaded attachment rather than only acknowledging it.
  </Step>
</Steps>

<Warning>A webhook that returns 2xx proves only that Meta reached the runtime. It says nothing about whether your outbound credentials work. Always confirm a real two-way conversation before you call the channel done.</Warning>

## Create a permanent access token

The token on the API Setup page expires within 24 hours, which is enough to test and not enough to run. Replace it with a system user token, which lasts until you revoke it. Meta explains how the token types differ under [access tokens](https://developers.facebook.com/docs/whatsapp/access-tokens).

This work happens in Meta Business Suite rather than the App Dashboard, and it needs a Meta Business admin.

<Steps>
  <Step title="Create a system user">
    Open [Meta Business Suite](https://business.facebook.com/), select your business portfolio from the dropdown at the top of the page, and select its settings icon to open **Business settings**.

    Go to **Users** -> **System users** and select **Add**. Name the system user, set its role to **Admin**, and create it. A system user represents your integration rather than a person, which is why its token survives staff changes.
  </Step>

  <Step title="Assign the app and the WhatsApp account">
    Select the system user you created and select **Assign assets**.

    Assign your app and your WhatsApp Business account, granting full control on each. Reload the page and confirm both show as assigned before you continue, because a token generated before the assets attach can't reach them.
  </Step>

  <Step title="Generate and store the token">
    Select **Generate token**, choose your app, and set the expiration to never.

    Select the `whatsapp_business_messaging` permission so the token can send and receive messages, and `whatsapp_business_management` so it can manage templates and account settings. Generate the token.

    Meta displays the token once and never again, so copy it straight into your secret manager. Then update the **Access Token** on the Artemis connection from the **Credentials** tab.
  </Step>
</Steps>

## Move to production

A test sender covers development and nothing else. Before real customers reach the agent, complete business verification, add a payment method, register a business phone number in WhatsApp Manager, and get your display name approved. Each of these waits on review from Meta, so start them well ahead of your launch date.

Two WhatsApp rules shape what your agent can say:

**The customer service window.** After a customer messages you, you can reply freely for 24 hours. Outside that window, an outbound message needs an approved template, so an agent that reaches out first needs templates approved before it can start a conversation at all. Template approval is its own review, and a rejected template blocks the conversation you wrote it for.

**Separate senders per environment.** Use different apps, senders, credentials, webhooks, and connections for development and production. Sharing a sender means test traffic reaches the same conversation history as customer traffic.

## Manage the channel connection

Opening a WhatsApp connection from **Deployments** -> **Channels** shows four tabs. The header carries the connection name, its environment, its status, and a delete control.

<Tabs>
  <Tab title="Overview">
    **Connection Summary** records what the connection is and when it changed.

    | Field                       | Description                                                                   |
    | --------------------------- | ----------------------------------------------------------------------------- |
    | **Status**                  | Whether the connection currently handles messages.                            |
    | **Created** and **Updated** | Date and time of creation, and of the last change.                            |
    | **Environment**             | The environment whose deployment answers messages.                            |
    | **Source Type**             | Reads `Channel Connection`.                                                   |
    | **Source ID**               | Identifies the connection uniquely. Quote it when you raise a support ticket. |

    **Setup Instructions** below the summary carries the two values you need on the Meta side, each with a copy control.

    | Value               | Description                                                                                                                                   |
    | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Webhook URL**     | The callback URL to register in Meta. It already carries the route for the provider you selected, so copy it rather than building it by hand. |
    | **Phone Number ID** | The routing identifier this connection matches inbound messages to. Check it here first when messages arrive and no session appears.          |
  </Tab>

  <Tab title="Credentials">
    The platform encrypts credentials after you save them, so every field reads as saved rather than showing its value. Leave a field empty to keep the current value, or enter a new value to replace it.

    | Field                | Description                                                                                                                                                                                  |
    | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Use Auth Profile** | Switches the connection to a saved auth profile in place of the fields below. Prefer it when the same credentials serve more than one connection, since a rotation then touches one profile. |
    | **Access Token**     | Authenticates outbound messages. Replace it here when you move from a temporary token to a system user token.                                                                                |
    | **Phone Number ID**  | Identifies the sender for outbound messages.                                                                                                                                                 |
    | **App Secret**       | Verifies the signature on inbound callbacks.                                                                                                                                                 |
    | **Verify Token**     | The string the webhook handshake compares. Changing it here breaks the webhook until you change it in Meta as well.                                                                          |

    Select **Save Credentials** to apply your changes.
  </Tab>

  <Tab title="Configuration">
    Under **General**, update the **Display Name** and the **Provider Verification Strength**.

    Under **WhatsApp Settings**, the **Phone Number ID** appears read-only. You can't change it after creation, so a connection pointed at the wrong sender needs replacing rather than editing.

    **Authorization message**

    The connection sends this message when a tool needs the user to authorize before the conversation continues. Edit the template to match your agent's voice, since the default reads as system text rather than as the agent talking.

    The editor lists the variables you can insert, offers a preview, and expands to show every available variable. The variables cover the number of outstanding authorizations, the profile each one belongs to, and the link the user follows.

    Select **Save Changes** to apply your changes.
  </Tab>

  <Tab title="Deployment">
    **Agent Version** carries an **Environment** dropdown that selects which deployed version handles incoming messages.

    **Active Deployment** shows the bound version and when someone deployed it. Check this pair when the channel connects but the agent behaves like an older build: the connection follows whatever the environment currently has deployed, not the version you last edited.

    Select **Save Changes** after you switch the environment.
  </Tab>
</Tabs>

## Key values reference

Each value sits on a different Meta screen, and two of them look alike enough to swap by accident. Use this table to collect everything in one pass.

| Value               | Where to find it in Meta                                                                                                                 | Where it goes                                                                |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| **Phone Number ID** | **WhatsApp** -> **API Setup**, directly below the test business phone number                                                             | The routing identifier and the outbound credential field in Artemis          |
| **Access Token**    | **WhatsApp** -> **API Setup** for testing. For production, **Business settings** -> **Users** -> **System users** in Meta Business Suite | The **Access Token** field in Artemis                                        |
| **App Secret**      | **App settings** -> **Basic**, revealed by selecting **Show**                                                                            | The **App Secret** field in Artemis                                          |
| **Verify Token**    | You choose it                                                                                                                            | The **Verify Token** field in Artemis, and the webhook configuration in Meta |
| **Webhook URL**     | The **Overview** tab of the Artemis connection                                                                                           | The callback URL in **WhatsApp** -> **Configuration** in the Meta app        |

## Troubleshooting

| Symptom                                                 | Where to look                                                                                                                                                                                                                                                   |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The agent never replies, and a session exists           | Meta accepts inbound messages from anyone in development mode but delivers only to verified recipients. Add your number under **WhatsApp** -> **API Setup** in the Meta app.                                                                                    |
| The agent never replies, and no session exists          | Nothing reached the runtime. Confirm the webhook subscribes to the `messages` field, that the callback URL verified successfully, and that the App Secret matches the one in the Meta app.                                                                      |
| The runtime reports no connection found                 | Compare the sender identifier on the inbound callback with the value saved in Artemis, and confirm the provider selector matches the provider that sent it.                                                                                                     |
| Inbound messages arrive but no reply goes out           | Check the outbound credential, the sender identifier, the account-specific base URL where your provider uses one, the connection status, and whether a runnable deployment exists. A temporary Meta token that expired overnight produces exactly this symptom. |
| Customers receive duplicate replies                     | Remove duplicate provider subscriptions, disable any other automation on the number, and account for provider retry behavior.                                                                                                                                   |
| Text works but buttons or lists fail                    | Check the provider's limits, the reply payload IDs, whether your provider supports the interactive type, and how the agent handles the returned action.                                                                                                         |
| Text works but media fails                              | Confirm the provider enabled that message type, the credentials can download media, size and host policies allow it, and the agent handles attachments.                                                                                                         |
| Outbound sends fail outside the customer service window | Send an approved WhatsApp template instead.                                                                                                                                                                                                                     |
