WhatsApp Direct Send API
WhatsApp requires every business-initiated message to be sent against an approved template. Direct Send removes the template-creation step for utility messages: you send the message content directly, and WhatsApp generates, classifies, and manages the matching template on your behalf.
This page covers the concepts behind Direct Send, then the exact API and webhook details for using it on the 8x8 platform, an integration checklist, and the limits that apply.
Conceptual Foundation & Core Architecture
Template-First vs Direct Send
Under the standard model, you create a template, wait for it to be approved, and only then send against it. Direct Send changes the order of those steps:
- Standard Template Messaging: you create and submit the template, wait for approval, then reference it by name in each send request.
- Direct Send: you send the content with a
directSendobject. WhatsApp matches or creates the template for you, so there is nothing to create or approve before the first send.
The Key Concept
Direct Send does not remove templates. Every Direct Send message is still delivered against a template, and the same integrity rules apply to it. The difference is that WhatsApp creates and maintains that template, and you can trace every message back to it.
How Template Matching Works
For each Direct Send message, WhatsApp follows this sequence:
- Match: it checks whether the message matches an existing template. If it does, that template is used to send the message.
- Fall back: if no template matches, the message is still sent, using a fallback onboarding template.
- Create: when there is no match, WhatsApp asynchronously creates a new template from the message, so future matching messages use it. The content is redacted for personal information and its language is detected before the template is created.
- Report: the delivery receipt carries the
templateIdof the template that was used.
Platform Send Behavior
The content.whatsApp.directSend object decides which path a WhatsApp message takes on the 8x8 platform.
| Request Scenario | 8x8 Behavior |
|---|---|
directSend present | Sent through Direct Send. WhatsApp matches or creates a template. Charged at utility rates. |
directSend omitted | Sent as a standard WhatsApp message. Follows the normal rules for freeform and template messages. |
Supported Features
Direct Send on 8x8 supports the following. Any message type, button format, header type, or category not listed here is not supported with Direct Send.
| Feature | Supported | Details |
|---|---|---|
| Category | utility only | Charged at utility rates. |
| Text messages | Yes | Set type to text. |
| Interactive CTA URL messages | Yes | One Call-to-Action URL button. Set interactive.type to cta_url. |
| Interactive reply button messages | Yes | 1 to 3 reply buttons. Set interactive.type to button. |
| Interactive headers | Text only | Image, video, and document headers are not supported. |
| Time-to-live (TTL) | Yes | ttlSeconds, from 30 to 43200 seconds. |
| Recipient by phone number or BSUID | Yes | Use msisdn or channelUserId. |
Key Platform Limitations & Constraints
Design your workflows around the following limitations.
Utility Category Only
Direct Send accepts only "category": "utility". Marketing and authentication messages cannot be sent with Direct Send on 8x8. Send them as template messages instead.
No Template Naming
You cannot set the name of the template Direct Send creates. 8x8 matches or creates templates automatically, and the request has no field for a template name.
Generated Templates Are Managed by WhatsApp
- Names: generated template names start with
auto_generated, for exampleauto_generated_1234567890. - No edits: you cannot edit or delete a template generated by Direct Send.
- Cleanup: templates that were created but never used are deleted after 24 hours. Templates that were used but have been inactive for a while are archived.
Language Support
All WhatsApp Cloud API languages are supported. If you send in an unsupported language, the message is still delivered, but WhatsApp uses the onboarding templates instead of creating one. That message has no classification, integrity checks, or metrics.
Link Previews
Link previews are not rendered for messages sent with Direct Send. Use a CTA URL button when you want the recipient to open a link.
Sample Submission
Direct Send messages do not require a sample submission step. You can send as soon as your request is ready.
Pricing
Direct Send messages are charged at utility rates. A utility message opens a 24-hour utility conversation if one is not already open between you and the recipient. Utility conversations are separate from service conversations and are billed independently.
8x8 Developer & API Reference
8x8 exposes Direct Send through the content.whatsApp.directSend object on the existing Send Message endpoint. No separate endpoint or setup call is required.
Sending a Direct Send Message
Endpoint:
POST https://chatapps.8x8.com/api/v1/subaccounts/{subAccountId}/messages
Path Parameters:
{subAccountId}: the ID of the subaccount you send from.
Authenticate as described in WhatsApp over 8x8 API. The complete request and response schema is in the Send Message API reference.
The directSend Object
content.whatsApp.directSend.category(required): the category of the message. The only supported value isutility.content.whatsApp.directSend.ttlSeconds(optional): how long, in seconds, the message stays eligible for delivery. See Time-to-Live.
Example A: Text Message
{
"user": {
"msisdn": "+6500000000"
},
"type": "text",
"channels": [
{
"channel": "WhatsApp"
}
],
"content": {
"text": "Hi Jane, your order #12345 has been shipped and is expected to arrive on March 20.",
"whatsApp": {
"directSend": {
"category": "utility",
"ttlSeconds": 600
}
}
}
}
Key Fields:
type:"text"content.text: the message body.content.whatsApp.directSend.category:"utility"content.whatsApp.directSend.ttlSeconds: optional. In this example, the message expires after 600 seconds (10 minutes) if it cannot be delivered.
Example B: Interactive Message with a CTA URL Button
{
"user": {
"msisdn": "+6500000000"
},
"type": "interactive",
"channels": [
{
"channel": "WhatsApp"
}
],
"content": {
"interactive": {
"type": "cta_url",
"header": {
"type": "text",
"text": "Order #12345"
},
"body": {
"text": "Your order has been shipped. Tap below to track your package."
},
"footer": {
"text": "Thank you for shopping with 8x8."
},
"action": {
"parameters": {
"display_text": "Track Order",
"url": "https://www.example.com/track/12345"
}
}
},
"whatsApp": {
"directSend": {
"category": "utility"
}
}
}
}
Key Fields:
type:"interactive"content.interactive.type:"cta_url"content.interactive.header: optional. Must be"type": "text".content.interactive.body.text: the message body.content.interactive.footer.text: optional footer text.content.interactive.action.parameters.display_text: the button label.content.interactive.action.parameters.url: the URL the button opens.
Example C: Interactive Message with Reply Buttons
{
"user": {
"msisdn": "+6500000000"
},
"type": "interactive",
"channels": [
{
"channel": "WhatsApp"
}
],
"content": {
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "Appointment Reminder"
},
"body": {
"text": "Your appointment is scheduled for tomorrow at 3 PM. Would you like to confirm or reschedule?"
},
"footer": {
"text": "Reply within 24 hours."
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "confirm",
"title": "Confirm"
}
},
{
"type": "reply",
"reply": {
"id": "reschedule",
"title": "Reschedule"
}
}
]
}
},
"whatsApp": {
"directSend": {
"category": "utility"
}
}
}
}
Key Fields:
content.interactive.type:"button"content.interactive.header: optional. Must be"type": "text".content.interactive.action.buttons: 1 to 3 reply buttons.content.interactive.action.buttons[].reply.id: the identifier returned to you in the inbound message when the recipient taps the button.content.interactive.action.buttons[].reply.title: the button label.
Success Response
A successful request returns the standard Send Message response, and the message is queued for delivery.
{
"umid": "82188ee0-109f-e811-8150-020897df5459",
"user": {
"msisdn": "+6512341234"
},
"clientMessageId": "1234_id",
"status": {
"state": "queued",
"timestamp": "2021-01-04T08:19:45.99Z"
}
}
Addressing the Recipient
Direct Send accepts both recipient identifiers in the user object.
| Recipient Identifier Scenario | 8x8 Routing Behavior |
|---|---|
msisdn only | Delivered via standard phone routing. |
channelUserId only | Delivered to the matching Business-Scoped User ID. |
| Both identifiers provided | msisdn takes precedence. To send using only the BSUID, omit msisdn from the request. |
Time-to-Live
ttlSeconds sets how long the message stays eligible for delivery. If the message cannot be delivered within this window, it is dropped.
| Setting | Value |
|---|---|
| Default | 30 days (when ttlSeconds is omitted) |
| Minimum | 30 seconds |
| Maximum | 43200 seconds (12 hours) |
Important: TTL Applies to Direct Send Only
WhatsApp rejects a TTL value on a message that is not a Direct Send message. Set
ttlSecondsonly insidecontent.whatsApp.directSend. Values below 30 or above 43200 are also rejected.
For TTL on pre-approved templates, see Template Validity Period (TTL).
Delivery Receipts
Delivery receipts for Direct Send messages follow the standard format for outbound Chat Apps. One field is specific to Direct Send.
| Field Path | Standard Message | Direct Send Message |
|---|---|---|
whatsapp.templateId | Not present | String. The ID of the template WhatsApp used to deliver the message |
"whatsapp": {
"pricingCategory": "utility",
"templateId": "1281032340757288"
}
Use templateId to identify which template a message used, to find that template in your template list, and to match receipts to template-level reporting.
Note
A message whose TTL elapses before delivery is dropped and not delivered.
Template Pauses
WhatsApp pauses templates that receive low-quality feedback, and the same rule applies to templates generated by Direct Send. If you send a message that matches a paused template, the message fails and the failed delivery receipt carries WhatsApp error code 132015 in providerErrorCode.
A paused template also raises a template_status_update event with status set to PAUSED on the WhatsApp Template Change webhook.
To avoid pauses, send messages only to recipients who expect them, and write content they recognize as expected, such as an appointment reminder.
Category Misuse Detection
WhatsApp monitors how Direct Send messages are categorized. When it detects that a message looks like marketing content, a template_correct_category_detection event is sent to the WhatsApp Template Change webhook.
{
"eventId": "0f88f5c4-fae7-4dcf-8ff2-b2990133edea",
"timestamp": "2025-01-01T00:00:00.00Z",
"provider": "WhatsApp",
"businessAccountId": "<BUSINESS_ACCOUNT_ID>",
"accountId": "<ACCOUNT_ID>",
"eventType": "template_correct_category_detection",
"eventDetails": {
"templateId": "<TEMPLATE_ID>",
"templateName": "<TEMPLATE_NAME>",
"templateLanguage": "<TEMPLATE_LANGUAGE>",
"meta": {
"category": "UTILITY",
"correctCategory": "MARKETING"
}
}
}
Key Fields:
eventDetails.meta.category: the category the message was sent under, for exampleUTILITY.eventDetails.meta.correctCategory: the category WhatsApp detected,MARKETINGorAUTHENTICATION.
Review the content of every flagged template. If you believe a flag is a mistake, request a review from WhatsApp support by email, including the IDs or names of the flagged templates. Persistent misuse leads to restrictions on Direct Send.
Account Restrictions
Persistent category misuse escalates in stages. Each stage is delivered as an ACCOUNT_RESTRICTION event on the WhatsApp Account Update webhook, in violationInfo.violationType.
| Stage | violationType | Effect |
|---|---|---|
| Warning | DIRECT_SEND_UTILITY_CATEGORY_ABUSE_WARN | Notification only. No restriction is applied. |
| Strike 1 | DIRECT_SEND_UTILITY_CATEGORY_ABUSE_STRIKE_1 | Direct Send is restricted for 7 days. |
| Strike 2 | DIRECT_SEND_UTILITY_CATEGORY_ABUSE_STRIKE_2 | Direct Send is restricted for 30 days. |
| Offboard | DIRECT_SEND_UTILITY_CATEGORY_ABUSE_OFFBOARD | Direct Send is permanently restricted. |
| Unban | DIRECT_SEND_UTILITY_CATEGORY_ABUSE_UNBAN | The restriction is lifted. |
For strike and offboard events, restrictionInfo contains a restrictionType of RESTRICTED_DIRECT_SEND_UTILITY_TEMPLATES and the expiration time of the restriction.
Example Payload: Strike 1 Restriction
{
"eventId": "9ac6f2cb-abb7-43e6-b533-b3d7017846fd",
"timestamp": "2026-01-19T13:50:20.00Z",
"provider": "WhatsApp",
"businessAccountId": "950523421983857",
"accountId": "IntegrationTestCampaign",
"eventDetails": {
"event": "ACCOUNT_RESTRICTION",
"violationInfo": {
"violationType": "DIRECT_SEND_UTILITY_CATEGORY_ABUSE_STRIKE_1"
},
"restrictionInfo": [
{
"restrictionType": "RESTRICTED_DIRECT_SEND_UTILITY_TEMPLATES",
"expiration": "2026-01-26T13:50:20.00Z"
}
]
}
}
Important: Restrictions Apply per WhatsApp Business Account
A restriction applies to the WhatsApp Business Account (WABA) that triggered it. Other WABAs are not affected.
Message Limits
Direct Send messages follow the WhatsApp limits for business-initiated template messages.
| Element | Limit |
|---|---|
| Body text | 1024 characters |
| Header text | 60 characters |
| Footer text | 60 characters |
| Button text | 20 characters |
| Reply buttons | 3 (8x8 maximum) |
| CTA URL buttons | 1 (8x8 maximum) |
| Throughput | Standard WhatsApp Cloud API throughput |
Integration Checklist
Complete these before you send Direct Send messages in production.
- Use the utility category only. Direct Send accepts
"category": "utility". Route marketing and authentication messages through template messages. - Subscribe to the WhatsApp Template Change webhook. It delivers template pauses and category misuse events, which are your earliest signals that content needs review.
- Subscribe to the WhatsApp Account Update webhook. It delivers the warning, strike, offboard, and unban events for Direct Send restrictions.
- Store
whatsapp.templateIdfrom delivery receipts. It is the only link between a message and the template that carried it. - Handle error
132015in your send pipeline. A message that matches a paused template fails, so retry later or adjust the content rather than letting the send silently fail. - Set
ttlSecondsfor time-sensitive messages. Without it, a message stays eligible for delivery for 30 days. - Keep content utility-only. Review order, shipping, and appointment content so it does not read as marketing, to avoid category misuse flags.
- Test your send path in a non-critical flow first, covering text, CTA URL, and reply button messages.
Related Resources
API Reference:
- Send Message API - Full request and response schema, including the Direct Send examples.
- WhatsApp over 8x8 API - Authentication, endpoints, and the rest of the Send Message payloads.
Webhooks:
- Delivery Receipts for Outbound Chat Apps - Receipt fields, including
templateId. - WhatsApp Template Change Webhook - Template pauses and category misuse events.
- WhatsApp Account Update Webhook - Direct Send restriction events.
Conceptual Foundation:
- Concepts & Fundamentals - How conversations and message categories work.
- Message Types & Templates - Pre-approved template messages.
- Business-Scoped User IDs - Addressing recipients by
channelUserId.
External:
- Meta: Direct Send API - Meta's own reference.