Logo
Logo
Talk Now

Trusted by 10,000+ businesses

WhatsApp

WhatsApp Cloud API Setup Guide for Developers (2026)

A developer walkthrough for setting up the WhatsApp Cloud API: Meta app, WABA, System User token, phone number registration, webhook verification and signature checks, and your first template send- with curl and Node.js examples.

By Get Click Media · · Updated Oct 30, 2026 · 10 min read

This guide explores whatsapp cloud api setup guide for developers (2026) with practical context, actionable guidance, and answers to common questions for businesses working with WhatsApp.

WhatsApp Cloud API Setup Guide for Developers (2026)

In this article

Explore the key concepts, practical considerations, and frequently asked questions related to whatsapp cloud api setup guide for developers (2026).

Key takeaways

  • You can build and test the whole integration on Meta's test number before business verification is complete- verification only gates going live on your own number.
  • Use a System User token for production. The App Dashboard's temporary token expires after about 24 hours and is a common cause of sudden 401 errors.
  • Subscribing your app to the WABA with POST /{WABA_ID}/subscribed_apps is the most commonly missed step when webhooks verify but no events arrive.

This is a hands-on setup guide for developers integrating directly with Meta's WhatsApp Cloud API. It walks through every step from an empty Meta app to a delivered template message and a working webhook, with the exact API calls at each step.

Not a developer, or don't want to set this up yourself? This guide is for building the integration yourself. If you'd rather have it done for you, see our managed WhatsApp Business API service, or read the plain-English how to get WhatsApp Business API guide.

Before You Start

You will need:

  • A Meta business portfolio (business.facebook.com) where you are an admin
  • A Meta developer account (developers.facebook.com)
  • A phone number that is not currently registered on WhatsApp or the WhatsApp Business app, and that can receive an SMS or voice call
  • An HTTPS endpoint with a valid TLS certificate for your webhook. For local development, use a tunnel such as ngrok.
  • For going live: documents for Meta business verification

Throughout this guide, set these environment variables. Find the current Graph API version in Meta's changelog and use it for API_VERSION:

export API_VERSION="vXX.0"          # current Graph API version
export ACCESS_TOKEN="..."           # System User token (Step 2)
export WABA_ID="..."                # WhatsApp Business Account ID (Step 1)
export PHONE_NUMBER_ID="..."        # Phone Number ID, not the phone number itself (Step 3)
export APP_SECRET="..."             # App Dashboard > App settings > Basic
export VERIFY_TOKEN="..."           # any random string you choose (Step 5)

How the Pieces Fit Together

ComponentWhat it isID you will use
Business portfolioOwns your WABA, apps, and System UsersBusiness ID
Meta appYour integration. It holds webhook settings and permissionsApp ID, App Secret
WhatsApp Business Account (WABA)Holds your phone numbers and templatesWABA_ID
Business phone numberThe number customers see messages fromPHONE_NUMBER_ID
System UserNon-human account that owns your production tokenACCESS_TOKEN
WebhookYour HTTPS endpoint that receives messages and status eventsCallback URL + VERIFY_TOKEN

Step 1- Create a Meta App and Connect a WABA

  1. In the Meta App Dashboard, create a new app of type Business and link it to your business portfolio.
  2. Add the WhatsApp product. Meta creates a test WABA and a test phone number, and shows a temporary access token.
  3. To use your own WABA, connect it in the WhatsApp section of the app. Note the WABA ID shown there.

At this point you can already send a test message from the test number to up to 5 recipient numbers you add to the allowed list. Use this to build Steps 5–7 while business verification runs in the background.

Step 2- Generate a System User Access Token

The temporary token in the App Dashboard expires after about 24 hours, so do not use it in production.

  1. Go to Business Settings > Users > System users and add a System User with the Admin role.
  2. Use Assign assets to give it your app and your WABA (full control).
  3. Click Generate new token, choose your app, set the expiry to Never, and select these permissions:
    • whatsapp_business_messaging- send and receive messages
    • whatsapp_business_management- manage templates, numbers, and WABA settings
  4. Store the token in a secrets manager or environment variable. Never commit it to code.

Check that the token works:

curl "https://graph.facebook.com/$API_VERSION/$WABA_ID/phone_numbers" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The response lists each number on the WABA with its id. That id is your PHONE_NUMBER_ID.

Step 3- Add and Register Your Phone Number

  1. In WhatsApp Manager, add your phone number and display name, then verify it with the SMS or voice code.
  2. Register the number for Cloud API use. This also sets its two-step verification PIN, which you will need if you ever re-register it:
curl -X POST "https://graph.facebook.com/$API_VERSION/$PHONE_NUMBER_ID/register" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "messaging_product": "whatsapp", "pin": "123456" }'

A response of {"success": true} means the number is ready to send. Store the PIN securely.

Choose the number carefully. It becomes your business identity on WhatsApp, and while it is on the Cloud API it cannot be used in the WhatsApp or WhatsApp Business app.

Step 4- Subscribe Your App to the WABA

Your app only receives webhook events for a WABA after it subscribes to it. This step is easy to miss: the webhook verifies but no messages ever arrive.

curl -X POST "https://graph.facebook.com/$API_VERSION/$WABA_ID/subscribed_apps" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

To check it worked, call GET /$WABA_ID/subscribed_apps and confirm your app is listed.

Step 5- Build and Verify Your Webhook

Your endpoint has to handle two things:

  • GET (verification): Meta sends hub.mode, hub.verify_token, and hub.challenge. If the mode is subscribe and the token matches yours, reply with the hub.challenge value as plain text and HTTP 200.
  • POST (events): Check the X-Hub-Signature-256 header against an HMAC-SHA256 of the raw request body, signed with your App Secret. Reply 200 quickly, then process the event asynchronously.
const express = require('express');
const crypto = require('crypto');

const app = express();

// Keep the raw body- signature checks must use the exact bytes Meta sent
app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }));

// GET: verification handshake
app.get('/webhook/whatsapp', (req, res) => {
  const mode = req.query['hub.mode'];
  const token = req.query['hub.verify_token'];
  const challenge = req.query['hub.challenge'];
  if (mode === 'subscribe' && token === process.env.VERIFY_TOKEN) {
    return res.status(200).send(challenge);
  }
  return res.sendStatus(403);
});

// POST: inbound messages and status updates
app.post('/webhook/whatsapp', (req, res) => {
  const signature = req.get('X-Hub-Signature-256') || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.APP_SECRET)
    .update(req.rawBody)
    .digest('hex');

  const valid = signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);

  res.sendStatus(200); // acknowledge first

  for (const entry of req.body.entry || []) {
    for (const change of entry.changes || []) {
      const value = change.value || {};
      for (const msg of value.messages || []) {
        console.log('Inbound message', msg.from, msg.type);
      }
      for (const status of value.statuses || []) {
        console.log('Status', status.id, status.status); // sent, delivered, read, failed
      }
    }
  }
});

app.listen(3000);

Then, in the App Dashboard under WhatsApp > Configuration:

  1. Enter your Callback URL (for example https://yourapp.com/webhook/whatsapp) and Verify token, then click Verify and save.
  2. Under webhook fields, subscribe to messages. This field carries both inbound messages and status updates.

If Meta can't deliver an event, it retries for some time, so your handler should cope with receiving the same event twice. Use the message or status id to remove duplicates.

Step 6- Create a Message Template

Messages that start a conversation outside the 24-hour customer service window must use an approved template. Create one in WhatsApp Manager > Message templates, or through the API:

curl -X POST "https://graph.facebook.com/$API_VERSION/$WABA_ID/message_templates" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order_confirmation",
    "language": "en",
    "category": "UTILITY",
    "components": [
      { "type": "BODY",
        "text": "Hi {{1}}, your order {{2}} is confirmed.",
        "example": { "body_text": [["Asha", "#10234"]] } }
    ]
  }'

Choose the category carefully. Marketing is for promotions, Utility is for transactional updates, and Authentication is for OTPs. Meta can recategorise or reject a template whose content doesn't match its category, and the category also decides pricing. Check the status with GET /$WABA_ID/message_templates?name=order_confirmation, and wait for APPROVED before sending. For approval tips, see our WhatsApp template approval guide.

Step 7- Send a Test Message and Confirm Webhooks

curl -X POST "https://graph.facebook.com/$API_VERSION/$PHONE_NUMBER_ID/messages" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "to": "919876543210",
    "type": "template",
    "template": {
      "name": "order_confirmation",
      "language": { "code": "en" },
      "components": [
        { "type": "body",
          "parameters": [
            { "type": "text", "text": "Asha" },
            { "type": "text", "text": "#10234" }
          ] }
      ]
    }
  }'

Write the recipient number in international format without + (for India, start with 91). A successful response returns a message id (wamid...). This means Meta accepted the message, not that it was delivered.

Go-live checklist:

  • Your webhook receives sent, delivered, and read statuses for that wamid
  • Replying from the test phone triggers an inbound messages event
  • Inside the 24-hour window, you can reply with a free-form "type": "text" message
  • The business display name shows correctly on the recipient's phone
  • Failed sends are logged with their error code, and your retry logic follows our rate limits guide

Common Setup Errors and Fixes

SymptomLikely causeFix
Webhook "Verify and save" failsEndpoint returns JSON or the wrong value, or the verify token doesn't matchReturn the raw hub.challenge value as plain text with HTTP 200, and check that VERIFY_TOKEN matches exactly
Webhook verifies but no events arriveApp not subscribed to the WABA, or messages field not subscribedRun Step 4 and check that the messages webhook field is subscribed
Every POST fails signature checkSignature computed on re-serialised JSON instead of the raw body, or wrong App SecretCompute the HMAC on the raw request body using the App Secret from App settings > Basic
401 / error code 190Temporary token expired, token revoked, or System User not assigned to the WABAUse a System User token with no expiry and check its asset assignment and permissions
Error about permissions on sendToken missing whatsapp_business_messagingRegenerate the token with both WhatsApp permissions
Number registration failsNumber still active on the WhatsApp or WhatsApp Business appDelete the WhatsApp account on that number in the app, then add and register it again
Template send fails with template errorTemplate not yet APPROVED, wrong language code, or wrong number of parametersCheck the template status and send exactly the parameters it defines, in its exact language code
Sends fail after many succeedMessaging limit or throughput reachedSee WhatsApp API rate limits and error codes

Frequently Asked Questions- WhatsApp Cloud API Setup

How long does WhatsApp Cloud API setup take? The technical setup- app, token, webhook, and test send- can be done in a day using Meta's test number. Going live on your own number usually takes 3 to 5 business days, because Meta business verification and template approval each take 1 to 3 days. These two can run in parallel.

Can I test the WhatsApp Cloud API before business verification? Yes. Meta's test number and temporary token let you send to a small allowed list of recipient numbers, which is enough to build your webhook and send logic.

What is a System User token and why do I need one? A System User is a non-human account used for server-to-server calls. Its token can be set to never expire, unlike the App Dashboard's temporary token, which expires after about 24 hours.

Is the On-Premises API still an option? No. Meta has sunset the On-Premises API. Build new integrations on the Cloud API only.

Do I have to do this setup myself? No. Get Click Media's managed WhatsApp Business API service handles verification, number registration, and templates for you.

Official References

Next Steps

Once your integration is live, see WhatsApp API integration for CRM and workflow patterns, the WhatsApp webhooks guide for event handling, and WhatsApp API rate limits before your first large send.

Article topics

whatsapp cloud api setupwhatsapp business api setup guidewhatsapp api webhook setupwhatsapp cloud api send template messagewhatsapp api system user token

Frequently Asked Questions

How long does WhatsApp Cloud API setup take?

The technical setup- app, token, webhook, and test send- can be done in a day using Meta's test number. Going live on your own number usually takes 3 to 5 business days, because Meta business verification and template approval each take 1 to 3 days. These two can run in parallel.

Can I test the WhatsApp Cloud API before business verification?

Yes. When you add the WhatsApp product to a Meta app, Meta gives you a test phone number and a temporary access token. You can send to a small number of recipient numbers you add to an allowed list, which is enough to build and test your webhook and send logic before your own number is live.

What is a System User token and why do I need one?

A System User is a non-human account in your business portfolio used for server-to-server API calls. You can generate its access token with no expiry date, unlike the temporary token in the App Dashboard, which expires after about 24 hours. Production integrations should always use a System User token with the whatsapp_business_messaging and whatsapp_business_management permissions.

Is the On-Premises API still an option?

No. Meta has sunset the On-Premises API, and the Cloud API is the supported way to integrate with the WhatsApp Business Platform. New integrations should be built on the Cloud API only.

Do I have to do this setup myself?

No. If you would rather not configure Meta's portals and APIs yourself, a Business Solution Provider can handle onboarding for you. Get Click Media's managed WhatsApp Business API service covers verification, number registration, and templates- see the WhatsApp Business API page for details.

About the author

Get Click Media creates practical resources for businesses using messaging, automation, analytics, and digital communication to improve customer engagement. This article was published on and was last reviewed on .

Related Articles

Explore more practical resources and insights related to WhatsApp.