WhatsApp API Documentation
API key authentication, template creation for every header and button type, sending approved templates, webhook configuration, and the full template lifecycle — everything you need to integrate.
1. Introduction
The WhatsApp Business API enables organizations to manage and automate customer communication through secure, scalable endpoints. This documentation covers template creation, message sending, webhook configuration, and full template lifecycle management.
Every request in this guide uses https://api.accelbiz.in as the host and {{User-Access-Token}} for the bearer token. Replace the token with your actual API key when integrating.
Workflow at a glance
POST /message_templates and wait for approval2. API Key Setup
An API Key is required for every request. It authenticates the caller and authorizes access to your WhatsApp Business Account resources.
Steps to retrieve your key
- Sign in to the WhatsApp Business dashboard.
- Open the Account menu and click My Profile.
- Locate the API Key section.
- Copy the key and store it in a secure secret manager.
Security: never commit API keys to version control or share them publicly. Use environment variables or a secret manager, and rotate keys if a leak is suspected.
3. Create Template API
Templates must be created and approved by WhatsApp before they can be sent to users. This section shows the create-template payload for every supported header type and every interactive button type.
POST /{version}/{wabaId}/message_templatesv23.0Authorization: Bearer {{User-Access-Token}}
Content-Type: application/json3.1 Create Template with TEXT Header
Text headers display a single line of text at the top of the message.
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"name": "welcome_message",
"language": "en_US",
"category": "MARKETING",
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Welcome to Our Service!" },
{ "type": "BODY", "text": "Hi {{1}}! Thank you for joining us. We are excited to have you onboard.", "example": { "body_text": [["Pablo"]] } },
{ "type": "FOOTER", "text": "Reply STOP to unsubscribe" }
]
}'
3.2 Create Template with IMAGE Header
Image headers add a banner visual — ideal for product promotions.
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"name": "product_promotion",
"language": "en_US",
"category": "MARKETING",
"components": [
{ "type": "HEADER", "format": "IMAGE", "example": { "header_handle": ["https://example.com/product-image.jpg"] } },
{ "type": "BODY", "text": "Check out our {{1}} with {{2}} off! Limited time offer.", "example": { "body_text": [["Premium Headphones", "50%"]] } },
{ "type": "FOOTER", "text": "Offer valid until stock lasts" }
]
}'
Note — media handle vs. media ID:
At template creation, header_handle accepts a public URL or a media ID returned by the Media Upload API (section 8.2). At send time, the header parameter switches to { "type": "image", "image": { "id": "<MEDIA_ID>" } } — reuse the same media ID, or upload a fresh one per send.
3.3 Create Template with VIDEO Header
Video headers engage users with tutorials, demos, or promotional clips.
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"name": "tutorial_video",
"language": "en_US",
"category": "UTILITY",
"components": [
{ "type": "HEADER", "format": "VIDEO", "example": { "header_handle": ["https://example.com/setup-guide.mp4"] } },
{ "type": "BODY", "text": "Watch this quick {{1}} tutorial to get started with your new device.", "example": { "body_text": [["5-minute"]] } },
{ "type": "FOOTER", "text": "Need help? Contact support" }
]
}'
Note — media handle vs. media ID:
Video must be MP4, max 16 MB. At template creation, header_handle accepts a public URL or a media ID from the Media Upload API. At send time, pass the media ID as { "type": "video", "video": { "id": "<MEDIA_ID>" } }.
3.4 Create Template with DOCUMENT Header
Document headers attach PDFs, invoices, reports, or catalogs.
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"name": "invoice_delivery",
"language": "en_US",
"category": "UTILITY",
"components": [
{ "type": "HEADER", "format": "DOCUMENT", "example": { "header_handle": ["https://example.com/invoice-sample.pdf"] } },
{ "type": "BODY", "text": "Your invoice {{1}} for amount {{2}} is ready. Please download the attached document.", "example": { "body_text": [["INV-2026-001", "$1,250.00"]] } },
{ "type": "FOOTER", "text": "Thank you for your business" }
]
}'
Note — media handle vs. media ID:
Supported: PDF, DOC, DOCX, PPT, PPTX, XLS, XLSX (max 100 MB). At send time, pass the media ID as { "type": "document", "document": { "id": "<MEDIA_ID>", "filename": "invoice.pdf" } }.
3.5 Create Template with LOCATION Header
Location headers show map pins for stores or service locations.
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"name": "store_location",
"language": "en_US",
"category": "UTILITY",
"components": [
{ "type": "HEADER", "format": "LOCATION" },
{ "type": "BODY", "text": "Visit our {{1}} store! We are open from {{2}}.", "example": { "body_text": [["Ahmedabad", "10:00 AM - 9:00 PM"]] } },
{ "type": "FOOTER", "text": "See you soon!" }
]
}'
Note: Latitude, longitude, name, and address are supplied at send time, not during template creation (see section 4.2).
4. Send Message API
Once a template is approved, send it to a recipient using this endpoint. The payload varies depending on the template's components, but the endpoint and response shape are consistent.
POST /{version}/{phoneNumberId}/messagesv23.0Using media IDs at send time: for templates with IMAGE / VIDEO / DOCUMENT headers, first upload the file via the Media Upload API to receive a media id. The same media ID can be reused across multiple sends; alternatively a public link can be supplied instead of id.
4.1 Send Template with IMAGE Header
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{phoneNumberId}}/messages' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "91XXXXXXXXXX",
"type": "template",
"template": {
"name": "product_promotion",
"language": { "code": "en_US" },
"components": [
{ "type": "header", "parameters": [{ "type": "image", "image": { "id": "1234567890" } }] },
{ "type": "body", "parameters": [
{ "type": "text", "text": "Premium Headphones" },
{ "type": "text", "text": "50%" }
] }
]
}
}'
4.2 Send Template with LOCATION Header
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{phoneNumberId}}/messages' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "91XXXXXXXXXX",
"type": "template",
"template": {
"name": "store_location",
"language": { "code": "en_US" },
"components": [
{ "type": "header", "parameters": [{ "type": "location", "location": {
"latitude": "23.0225", "longitude": "72.5714",
"name": "Flagship Store - Ahmedabad", "address": "C.G. Road, Ahmedabad, Gujarat 380009"
} }] },
{ "type": "body", "parameters": [
{ "type": "text", "text": "Ahmedabad" },
{ "type": "text", "text": "10:00 AM - 9:00 PM" }
] }
]
}
}'
Success response
{
"messaging_product": "whatsapp",
"contacts": [{ "input": "91XXXXXXXXXX", "wa_id": "91XXXXXXXXXX" }],
"messages": [{ "id": "wamid.HBgMOTE..." }]
}Failure response
{
"isValid": false,
"response": [{
"status": "Invalid phone number in template message.",
"message": "An unexpected error occurred.",
"statusCode": 500
}]
}5. Webhook Configuration
Inbound messages and delivery events are pushed to your configured Webhook URL. Configure the endpoint to acknowledge receipt with HTTP 200 within a few seconds — do heavy processing asynchronously.
POST /api/v1/meta/webhookAuthorization: Bearer {{User-Access-Token}}Each webhook event delivers
- Sender's WhatsApp number
- Message type (text, image, interactive, button, location, etc.)
- Timestamp
- Message ID
- Business phone number ID
- Metadata for template responses and button interactions
Reference: developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components
6. Template Management Endpoints
These endpoints cover the rest of the template lifecycle: listing, fetching, editing, and deleting templates.
6.1 Get All Templates
curl --location --globoff 'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates' \
--header 'Authorization: Bearer {{User-Access-Token}}'
{
"data": [{
"name": "test1234",
"language": "en",
"category": "UTILITY",
"id": "865679666122280",
"status": "APPROVED",
"components": [{ "type": "BODY", "text": "Hello customer, your replacement order is confirmed." }]
}]
}6.2 Get Template by ID
curl --location --globoff 'https://api.accelbiz.in/v23.0/<TEMPLATE_ID>' \
--header 'Authorization: Bearer {{User-Access-Token}}'
6.3 Edit Template
Editing reuses the template ID as the path parameter. Send only the components you want to update; the category cannot be changed once approved unless allow_category_change was set.
curl --location --globoff 'https://api.accelbiz.in/v23.0/<TEMPLATE_ID>' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--header 'Content-Type: application/json' \
--data '{
"components": [
{ "type": "BODY", "text": "Updated body for {{1}} with new offer {{2}}.", "example": { "body_text": [["Pablo", "30%"]] } },
{ "type": "FOOTER", "text": "Updated footer text" }
]
}'
Tip: Edits put the template back into review. The status returns to PENDING until WhatsApp re-approves it.
6.4 Delete Template
Delete by name (removes all language variants) or by ID (removes a single language). Pass the template name or hsm_id as a query parameter.
curl --location --globoff --request DELETE \
'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates?name=order_confirmation' \
--header 'Authorization: Bearer {{User-Access-Token}}'
Delete a single language variant by ID
curl --location --globoff --request DELETE \
'https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates?hsm_id=<TEMPLATE_ID>&name=order_confirmation' \
--header 'Authorization: Bearer {{User-Access-Token}}'
7. Channel Management
7.1 Get Channels
curl --location --globoff 'https://api.accelbiz.in/v23.0/channels' \
--header 'Authorization: Bearer {{User-Access-Token}}'
{
"data": [{
"id": "123456789",
"name": "Customer Support",
"phone_number": "+917912345678",
"status": "ACTIVE"
}]
}8. Additional APIs
8.1 Get Wallet Balance
curl --location --globoff --request GET 'https://api.accelbiz.in/api/v1/user/balance' \
--header 'Authorization: Bearer {{User-Access-Token}}'
{
"walletBalance": 83.2649
}8.2 Upload WhatsApp Media
Upload media before referencing it in template headers or send-message payloads. The returned id is what you pass in subsequent calls.
curl --location --globoff --request POST 'https://api.accelbiz.in/v23.0/{{phoneNumberId}}/media' \
--header 'Authorization: Bearer {{User-Access-Token}}' \
--form 'file=@product_image.jpg' \
--form 'type=image/jpeg' \
--form 'messaging_product=whatsapp'
{
"id": "2171225710283963",
"error": null
}Supported media types & size limits
| Type | Formats | Max size |
|---|---|---|
| Image | JPG, JPEG, PNG | 5 MB |
| Video | MP4, 3GPP | 16 MB |
| Audio | AAC, MP3, AMR, OGG, OPUS | 16 MB |
| Document | PDF, DOC(X), PPT(X), XLS(X), TXT | 100 MB |
| Sticker | WEBP (static & animated) | 100 KB / 500 KB |
Appendix: Calling the API from Postman
- Open Postman, click New → HTTP Request.
- Set the request type to POST (or the verb required by the endpoint).
- Enter the URL, e.g.
https://api.accelbiz.in/v23.0/{{wabaId}}/message_templates. - In the Headers tab add:
Authorization: Bearer {{User-Access-Token}}andContent-Type: application/json. - In the Body tab choose raw → JSON and paste the payload.
- Click Send and inspect the response.
Style note for curl examples
Throughout this document, curl examples use --location --globoff (follow redirects and disable URL globbing so brace placeholders survive) and the standard Authorization: Bearer header. Replace {{User-Access-Token}} with your actual API key before running.
