WhatsApp API in Postman: Setup, Collections and Fixes
Before you write a line of integration code, you want proof that a message actually lands on a phone. And when your code later fails with an opaque Graph API error, you want to replay the exact request outside your app and change one thing at a time. Postman is the fastest tool for both.
It is also easy to set up badly. Tokens end up pasted into twelve requests, shared with the whole workspace, or silently expired, and the phone number ID gets confused with the account ID. This WhatsApp API Postman guide sets it up properly: one environment, Meta's official collection or four requests of your own, Tenashi's OpenAPI spec, and a table of the mistakes that cost people the most time.
Set up an environment first
Create an environment called something like WhatsApp Cloud API (test) and add these variables. Every request then references them, so switching from the test number to production is a dropdown change, not an edit to every URL.
| Variable | Example value | Notes |
|---|---|---|
version | v23.0 | Use the current Graph API version from Meta's changelog. |
phone_number_id | 106540352242922 | The ID of the sending number, from the app's WhatsApp API Setup panel. |
waba_id | 102290129340398 | The WhatsApp Business Account ID. Used for account-level calls only. |
token | your system user token | Keep this value local, never shared. |
recipient | +919811122233 | Your own phone, with country code. |
The token deserves care. In Postman, a variable's value stays local to your machine by default and only syncs to the Postman cloud when someone with editor access shares it. Leave the token's value unshared. Better still, store it in Postman Vault, whose local vault secrets are not synced to the cloud at all.
Use a system user token rather than the temporary one from the dashboard, which expires quickly. Getting a permanent WhatsApp API access token walks through creating the system user and assigning the WhatsApp permissions.
Then open the collection's Authorization tab, choose Bearer Token and enter {{token}}. Every request set to "Inherit auth from parent" now sends Authorization: Bearer ... without you pasting anything.
Meta's official collection, or four requests of your own
Meta publishes an official Postman collection for the WhatsApp Business Platform, linked from its platform overview and hosted at postman.com/meta/whatsapp-business-platform. It covers far more than messaging: templates, phone number management, business profiles, media and more. Fork it into your own workspace rather than editing it in place, then point it at your environment. The collection's own variable names may differ from the table above, so check its Variables tab and map your values to whatever it expects.
If you only need to send and debug messages, four requests of your own are easier to reason about. Use https://graph.facebook.com/{{version}} as the start of every URL.
1. Check the token and find your numbers. GET .../{{waba_id}}/phone_numbers. A 200 listing your number, its display name and quality rating proves the token works and shows the ID to put in phone_number_id.
2. Send the hello_world template. New test numbers come with an approved hello_world template, and templates are the only messages allowed before the user has written to you.
POST https://graph.facebook.com/{{version}}/{{phone_number_id}}/messages
Content-Type: application/json
{
"messaging_product": "whatsapp",
"to": "{{recipient}}",
"type": "template",
"template": {
"name": "hello_world",
"language": { "code": "en_US" }
}
}
3. Send free-form text. Reply to the hello_world message from your phone first. That opens the 24-hour customer service window, and only then will this succeed:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{{recipient}}",
"type": "text",
"text": { "body": "Hello from Postman" }
}
4. List your templates. GET .../{{waba_id}}/message_templates?fields=name,status,language,category shows each template's exact name, language code and approval status, which is the fastest way to debug a template send. The WhatsApp message templates guide covers what each status means.
Add a post-response script to the send requests so the message ID is captured for later steps:
pm.test("Meta accepted the message", () => pm.response.to.have.status(200));
const body = pm.response.json();
if (body.messages) {
pm.environment.set("last_wamid", body.messages[0].id);
console.log("wamid", body.messages[0].id);
}
Remember what a 200 means here: Meta accepted the request. Delivery shows up later in a status webhook, which Postman cannot receive. If a send returns 200 and nothing arrives, the answer is in the webhook, not in Postman.
Import Tenashi's OpenAPI 3.1 spec
If you are testing Tenashi's API instead, there is nothing to build by hand. The spec is public at https://usetenashi.com/api/v1/openapi.json (OpenAPI 3.1).
- In Postman, choose Import, paste the URL, and import it as a Postman Collection.
- Open the new collection's Variables tab. Postman usually turns the spec's server URL into a base URL variable; confirm it reads
https://usetenashi.com/api/v1. - On the collection's Authorization tab, choose Bearer Token and set it to
{{tenashi_key}}, with yourtk_live_...key as a local value in your environment. Keys are created by workspace admins in Settings and shown once. - Run "List WhatsApp numbers" to confirm the key works and the number is connected.
Then send a message with an idempotency key generated by Postman's dynamic variables:
POST https://usetenashi.com/api/v1/messages
Authorization: Bearer {{tenashi_key}}
Content-Type: application/json
Idempotency-Key: {{$guid}}
{
"to": "{{recipient}}",
"text": "Hi, this is a test from Postman."
}
Expect 202 Accepted with the message in status queued. It leaves the number 4 to 12 seconds later. Run "Get a message and its status" with the returned id a few times and you can watch it move from queued to sent to delivered.
To see idempotency for yourself, replace {{$guid}} with a fixed string such as postman-test-1 and send twice. The second response is identical to the first and only one message arrives. The guide to duplicate WhatsApp API messages explains why every production sender should do this.
One Tenashi-specific trap when testing: ban protection pauses the exact same text once it has gone to 5 chats within 10 minutes, returning 422 send_blocked. If you are firing "test" at several colleagues, vary the text.
Test your own webhook handler from Postman
Postman cannot receive webhooks, but it is a good way to send fake ones to your own handler while you develop it. The catch is the signature. Your handler should reject unsigned requests, so you need to sign the test body yourself.
Compute the signature in a terminal, using the exact body you will paste into Postman:
# Meta: X-Hub-Signature-256 = "sha256=" + hex HMAC of the raw body with your app secret
BODY='{"object":"whatsapp_business_account","entry":[{"id":"1","changes":[{"field":"messages","value":{"messaging_product":"whatsapp","metadata":{"phone_number_id":"1"},"messages":[{"from":"919811122233","id":"wamid.TEST1","timestamp":"1761644466","type":"text","text":{"body":"hi"}}]}}]}]}'
printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$APP_SECRET" | awk '{print $NF}'
# Tenashi: X-Tenashi-Signature = "v1=" + hex HMAC of "timestamp.body" with the whsec_ secret
TS=$(date +%s); echo "$TS"
printf '%s' "$TS.$BODY" | openssl dgst -sha256 -hmac "$TENASHI_WEBHOOK_SECRET" | awk '{print $NF}'
In Postman, create a POST to http://localhost:3000/webhook, set the body to raw JSON and paste the body exactly as it was signed: same spacing, no pretty-printing, no trailing newline. Add the header X-Hub-Signature-256: sha256= followed by the hex. Change one character in the body, send again, and your handler should return 401. That second test is the one that proves the check works.
For the Tenashi variant, send X-Tenashi-Timestamp and X-Tenashi-Signature: v1=..., and re-sign after 5 minutes because handlers should reject stale timestamps. For real deliveries, Tenashi's Settings page has a Send test button that posts a signed ping event to your endpoint.
Common mistakes and how to read them
| What you see | Usual cause | Fix |
|---|---|---|
Error 190, access token expired | The temporary dashboard token, which expires quickly | Switch to a system user token |
Error 100, invalid parameter | Missing messaging_product, a misspelt field, or the WABA ID in the messages URL | Messages go to /{{phone_number_id}}/messages |
Error 132001 | Template name or language code does not match an approved template | Copy both from the message_templates request |
Error 131047 on a text message | More than 24 hours since the user last wrote | Send a template, or reply from the phone to reopen the window |
| 200, but nothing on the phone | Accepted is not delivered; on a test number, the recipient may not be on the allowed list | Add the recipient in API Setup and check status webhooks |
| Body arrives as text, Meta errors | Raw body set to Text instead of JSON, or a stray Content-Type header | Set raw type to JSON |
Tenashi 401 key_owner_removed | The teammate who created the key left the workspace | Create a new key |
Tenashi 429 new_chat_limit | 50 new chats per number per day via the API | Wait, or test with people who have written to you |
Error 131047 may come back in the response or only in a failed status webhook. Meta reports some errors both ways. The full list with fixes is in the WhatsApp API error codes reference, and if you have not finished onboarding, the Cloud API setup guide covers the test number and recipient list.
Where Tenashi fits
Postman is often where people discover that the Cloud API's model does not match what they wanted: the first free-form message fails because the window is closed, templates wait for approval, and the number cannot also be used on the phone. If your real need is sending from the number your team already uses, those steps are overhead.
Tenashi links an existing WhatsApp or WhatsApp Business number by QR scan. Its API needs one bearer key, has no templates or window to manage, and imports into Postman from the OpenAPI spec in under a minute. Messages you send show up in the team's shared inbox. The trade-offs are real: it is not Meta's platform, it has no buttons, Flows or green tick, and sends are paced for conversation rather than bulk. WhatsApp can still ban numbers that spam. From $18/mo.
Read the API docs · Get started
FAQ
Is there an official Postman collection for the WhatsApp API?
Yes. Meta's platform overview links an official Postman collection for the WhatsApp Business Platform, hosted in Meta's public Postman workspace. Fork it into your own workspace so you can set variables and keep your changes, and check its variable names against your environment, because they may not match the names you chose.
Why does my first text message from Postman fail?
Free-form text is only allowed inside the 24-hour customer service window, which opens when the user messages you. On a fresh test setup nobody has written yet, so send the hello_world template first, reply to it from your phone, and then the text request works for the next 24 hours.
Where do I find the phone number ID?
In the App Dashboard's WhatsApp API Setup panel, under the sending number, or by calling GET /WABA_ID/phone_numbers with your token. It is a long numeric ID, not the phone number itself and not the WhatsApp Business Account ID. Putting the WABA ID in the messages URL is a frequent cause of error 100.
Can Postman receive WhatsApp webhooks?
No. Postman sends requests; it does not host a public endpoint for Meta or Tenashi to call. Use it to send signed test events to your own handler on localhost, and for real deliveries run your handler behind an HTTPS tunnel. Tenashi's settings page also offers a Send test button and the last 100 deliveries per endpoint.
Is it safe to keep my WhatsApp token in a Postman environment?
It is safe enough if the value stays local and unshared, and safer in Postman Vault, whose local secrets are not synced to the cloud. Never export an environment with the token filled in or commit it to a repo. If a token leaks, revoke it in Business Settings and generate a new one.
With an environment, a handful of saved requests and a signed test event, you can reproduce almost any WhatsApp API problem in a minute. For the platform as a whole, read the complete guide to the WhatsApp API, and to try sending from your own number, import the Tenashi API.