Skip to content

Channels

WhatsApp Business

Send and receive WhatsApp messages from your own WhatsApp Business Platform number, including templates and interactive messages.

Requirements#

  • A Meta Business portfolio with a WhatsApp Business Account (WABA).
  • A Facebook login with admin access to that portfolio, and a phone number that can receive a verification code by SMS or call.
  • Only for the credential path: a number already registered on the WhatsApp Business Platform (Cloud API) and a system user access token that does not expire, with the whatsapp_business_messaging and whatsapp_business_management permissions.
  • At least one approved message template if you intend to start conversations.

Connect the channel#

Continue with Facebook (recommended)#

In the console, open Channels, choose WhatsApp Business and continue with Facebook. A Meta window opens (Embedded Signup): choose or create the WhatsApp Business account, pick or add the phone number and verify it. When the window closes the number is connected; it shows as pending for a moment and then as connected. The identifier is the phone number.

  • You can optionally choose a data storage region for the number before you start.
  • Nothing has to be copied: no IDs and no tokens.
  • This path needs a person at a browser, so it is not available with an API key.

With credentials#

For a number that is already on the Cloud API, choose "Enter credentials manually" in the console, or post the credentials to POST /v1/channels with type: "whatsapp". The identifier is the phone number in E.164 format.

FieldWhere to find it
wab_account_idWhatsApp Business Account ID, shown in WhatsApp Manager and in the API setup page of your Meta app.
phone_number_idPhone number ID of the sender. It is an ID assigned by Meta, not the phone number itself.
access_tokenSystem user access token, created under Business settings, System users.
data_localization_regionOptional. Two-letter region in which Meta stores message data at rest: AU, ID, IN, JP, SG, KR, DE, CH, GB, BR, BH, ZA, AE or CA.
curl https://api.omnimessage.co/v1/channels \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "whatsapp",
    "name": "Support line",
    "identifier": "+971800123456",
    "credentials": {
      "wab_account_id": "104857600123456",
      "phone_number_id": "209715200654321",
      "access_token": "EAAG..."
    }
  }'

Recipients#

to is the phone number of the recipient in E.164 format: a plus sign, the country code and the number, without spaces, for example +971501234567. The recipient must have a WhatsApp account and must have opted in to hear from your business, as WhatsApp policy requires.

Supported message types#

TypeUse it for
textPlain text of up to 4096 characters.
attachmentsOne image, video, document, audio file, voice note or sticker, fetched from an HTTPS URL.
templateA pre-approved template, required outside the 24-hour customer service window.
buttonText with one to three quick-reply buttons.
listA menu of rows grouped into sections, opened by one button.
cta_urlText with one button that opens a URL.
locationA map pin with a name and an address.
contactsOne or more contact cards.

This channel also accepts the pass-through types flow, product, product_list, catalog, carousel, location_request. Their content is forwarded in the provider format without validation: see Channel-specific types.

Channel rules#

The 24-hour customer service window#

WhatsApp lets a business send free-form content (text, media, buttons, lists and so on) only within 24 hours of the last message the user sent to it. Each inbound message restarts the window.

SituationWhat you can send
Within 24 hours of the last inbound message from the userAny supported message type.
Outside the window, or the user has never written to youOnly template messages.

A free-form message sent outside the window is refused by WhatsApp. Depending on when the refusal is reported, the request fails with 422 policy_violation or the message is accepted and then moves to failed with a provider_error. In both cases you are not charged. Track the time of the last message.received event per recipient to know whether the window is open.

Templates#

Templates are created and submitted for approval in WhatsApp Manager. Only templates with status APPROVED can be sent. List the templates of a channel, with their languages and components, through the API:

curl https://api.omnimessage.co/v1/channels/ch_7Hq2mN5vB8cX1zL0pK3j/templates \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx"
200 OK
{
  "object": "list",
  "data": [
    {
      "id": "1203948571029384",
      "name": "order_shipped",
      "language": "en",
      "category": "UTILITY",
      "status": "APPROVED",
      "components": [
        {
          "type": "BODY",
          "text": "Hi {{1}}, your order {{2}} has shipped."
        },
        {
          "type": "BUTTONS",
          "buttons": [
            {
              "type": "URL",
              "text": "Track order",
              "url": "https://example.com/track/{{1}}"
            }
          ]
        }
      ],
      "variables": {
        "header": [],
        "body": [
          {
            "key": "1",
            "example": null
          },
          {
            "key": "2",
            "example": null
          }
        ],
        "buttons": [
          {
            "index": 0,
            "type": "url",
            "variables": [
              {
                "key": "1",
                "example": null
              }
            ]
          }
        ],
        "count": 3
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}

To send one, reference it by name and language.code and fill its variables through components, in the order they appear in the template. The components array follows the WhatsApp Cloud API format and is forwarded unchanged.

curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "template",
    "template": {
      "name": "order_shipped",
      "language": {
        "code": "en"
      },
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "Layla"
            },
            {
              "type": "text",
              "text": "#1042"
            }
          ]
        }
      ]
    }
  }'

Interactive messages#

  • button carries one to three reply buttons with titles of up to 20 characters.
  • list opens a menu of rows; the label of the opening button is limited to 20 characters.
  • cta_url shows one button that opens a URL.
  • A tap on a button or a list row arrives as a message.received event carrying the id you assigned.

Fees charged by Meta#

Meta bills WhatsApp usage to the payment method on your WhatsApp Business Account. Those charges are separate from the OmniMessage per-message price.

Example request#

curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "button",
    "button": {
      "body": {
        "text": "Your delivery is scheduled for tomorrow, 10:00-12:00. Does that work?"
      },
      "footer": {
        "text": "Order #1042"
      },
      "action": {
        "buttons": [
          {
            "reply": {
              "id": "confirm",
              "title": "Confirm"
            }
          },
          {
            "reply": {
              "id": "reschedule",
              "title": "Reschedule"
            }
          }
        ]
      }
    }
  }'

Delivery statuses#

WhatsApp reports sent, delivered and read. Read receipts arrive only if the recipient has them enabled. When a message fails, error.provider_code contains the WhatsApp error code, for example 131026 when the recipient cannot receive the message.

Pricing#

Each accepted outbound message on a whatsapp channel consumes one package credit or the whatsapp price from the wallet. Read your effective price from GET /v1/pricing. Inbound messages are free. Fees charged by the provider are separate. See Billing.

    Loading