WhatsApp Templates API

WhatsApp Templates API

Create and send WhatsApp message templates programmatically for meta-direct companies.

Authentication

Every request must include an X-API-KEY header containing your company's API secret. This authenticates and identifies your company — no company ID is needed in the URL.

X-API-KEY: your-api-secret

Always include Accept: application/json

Without this header, Laravel treats the request as a browser request. Any error (validation failure, auth issue) will return an HTML redirect instead of a JSON error response — making debugging impossible in Postman or curl.

Base URL

https://hooks.chatworks.co.za/api

Create Template

POST /api/templates/whatsapp-templates

Creates a new WhatsApp template in a single request. If the header is a media file, you can upload it inline — no separate upload call is required. Set auto_submit=true to also submit the template to Meta for approval in the same call.

Content-Type: multipart/form-data

Request Fields

Field Type Required Notes
name string yes Lowercase letters, digits and underscores only. Unique per company.
display_name string yes Human-readable label. Max 255 chars.
category string yes marketing · utility · authentication
language string yes BCP-47 code, e.g. en, en_US, af.
body string yes Template body text. Max 1024 chars. Use {{1}}, {{2}} for variables.
header_type string no none · text · image · video · document
header_content string conditional Text value when header_type=text (max 60 chars). Pre-uploaded file handle when header_type is a media type and you already have a handle.
header_file file conditional Raw file upload for media headers. Alternative to passing a pre-uploaded header_content handle. Max 20 MB.
footer string no Footer text. Max 60 chars. Not allowed for authentication templates.
buttons array no Up to 10 buttons for marketing/utility; 1 button for authentication.
auto_submit boolean no Submits to Meta immediately after creation. Status is set to pending. Default: draft only. Use 1 for true and 0 for false — string values like true/false are not accepted.
add_security_recommendation boolean no Authentication templates only.
code_expiry_minutes integer no Authentication templates only. 1–90 minutes.

cURL Samples

No Header — draft only

curl --location 'https://hooks.chatworks.co.za/api/templates/whatsapp-templates' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json' \
--form 'name=order_confirmed' \
--form 'display_name=Order Confirmed' \
--form 'category=utility' \
--form 'language=en' \
--form 'body=Hello {{1}}, your order {{2}} has been confirmed.' \
--form 'auto_submit=0'

Text Header — submit immediately

curl --location 'https://hooks.chatworks.co.za/api/templates/whatsapp-templates' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json' \
--form 'name=promo_launch' \
--form 'display_name=Promo Launch' \
--form 'category=marketing' \
--form 'language=en_US' \
--form 'header_type=text' \
--form 'header_content=Big Sale This Weekend' \
--form 'body=Hi {{1}}, use code {{2}} for 20% off.' \
--form 'footer=Reply STOP to unsubscribe' \
--form 'auto_submit=1'

Use auto_submit=1 to submit to Meta immediately, or auto_submit=0 to save as draft and submit later.

Media Header — raw file upload

curl --location 'https://hooks.chatworks.co.za/api/templates/whatsapp-templates' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json' \
--form 'name=product_showcase' \
--form 'display_name=Product Showcase' \
--form 'category=marketing' \
--form 'language=en' \
--form 'header_type=image' \
--form 'header_file=@/path/to/banner.jpg' \
--form 'body=Check out our new product, {{1}}!' \
--form 'auto_submit=0'

Replace @/path/to/banner.jpg with the actual file path. In Postman, set header_file as type File in the form-data body. Alternatively pass a pre-uploaded handle as header_content instead of header_file.

Success Response 201 Created

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",   // UUID — use this for submit
    "name": "order_confirmed",
    "display_name": "Order Confirmed",
    "category": "utility",
    "language": "en",
    "status": "draft",          // "pending" when auto_submit=true and submission succeeded
    "header_type": null,
    "header_content": null,
    "body": "Hello {{1}}, your order {{2}} has been confirmed.",
    "footer": null,
    "buttons": null,
    "wa_template_id": null,     // populated when auto_submit=true
    "created_at": "2026-05-13T10:00:00.000000Z",
    "updated_at": "2026-05-13T10:00:00.000000Z"
  },
  "wa_template_id": null        // Meta's template ID when auto_submit=true
}

Submit Template for Approval

POST /api/templates/whatsapp-templates/{uuid}/submit

Submits a template to Meta for approval. Use this when a template was created without auto_submit=true, or to re-submit a rejected template after corrections. Templates in any status (draft, rejected, pending) can be submitted. On success the status is updated to pending.

URL Parameter

Parameter Type Notes
{uuid} UUID The id value returned by the Create Template endpoint.

cURL Sample

curl --location --request POST \
  'https://hooks.chatworks.co.za/api/templates/whatsapp-templates/550e8400-e29b-41d4-a716-446655440000/submit' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json'

Replace the UUID with the id returned when the template was created.

Success Response 200 OK

{
  "message": "Template submitted for approval.",
  "wa_template_id": "123456789"
}

Delete Template

DELETE /api/templates/whatsapp-templates/{uuid}

Deletes a template from Meta and soft-deletes the local record. The template must have a wa_template_id (i.e. it must have been submitted at least once). Drafts that were never submitted can be discarded without calling this endpoint.

This action is irreversible. Once deleted from Meta the template cannot be recovered.

URL Parameter

Parameter Type Notes
{uuid} UUID The id returned by the Create Template endpoint.

cURL Sample

curl --location --request DELETE \
  'https://hooks.chatworks.co.za/api/templates/whatsapp-templates/550e8400-e29b-41d4-a716-446655440000' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json'

Replace the UUID with the id returned when the template was created.

Success Response 200 OK

{ "message": "Template deleted." }

Error — not submitted to Meta yet 422

{ "error": "Template has not been submitted to Meta yet — nothing to delete remotely." }

Send Template Message

POST /api/templates/whatsapp-templates/send

Sends an approved WhatsApp template message to a recipient phone number. You can identify the template by its local database ID (recommended — name and language are resolved automatically) or by passing the template name and language directly.

Content-Type: application/json or multipart/form-data

Request Fields

Field Type Required Notes
to string yes Recipient phone number. Any format — non-digits are stripped and + is prepended automatically. E.g. 27821234567.
template_id integer one of Local database ID of an approved template. Name and language are resolved automatically. Required unless template_name is provided.
template_name string one of Exact snake_case template name. Required unless template_id is provided.
language string no BCP-47 code. Default: en. Ignored when template_id is supplied.
body_values string[] no Ordered values for body variables {{1}}, {{2}} … Index 0 maps to {{1}}.
header_values string[] no Ordered values for text-header variables. Only relevant when the template has a text header with variables.
header_type string no none (default) · text. Pass text together with header_values when the template has a text header with variables.

cURL Samples

By template_id (recommended)

curl --location 'https://hooks.chatworks.co.za/api/templates/whatsapp-templates/send' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
  "to": "27821234567",
  "template_id": 42,
  "body_values": ["John", "ORD-9981"]
}'

By template_name with text header variables

curl --location 'https://hooks.chatworks.co.za/api/templates/whatsapp-templates/send' \
--header 'X-API-KEY: your-api-secret' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
  "to": "27821234567",
  "template_name": "promo_launch",
  "language": "en_US",
  "header_type": "text",
  "header_values": ["Weekend Sale"],
  "body_values": ["John", "SAVE20"]
}'

Success Response 200 OK

{
  "message": "Template message sent."
}

Reference — All Fields

Button object (Create Template)

Field Required Notes
type yes Marketing/Utility: URL · PHONE_NUMBER · QUICK_REPLY · COPY_CODE
Authentication: COPY_CODE · ONE_TAP
text yes Button label. Max 25 chars.
url URL type Valid URL. Required when type=URL.
phone_number PHONE type Required when type=PHONE_NUMBER.

Authentication category restrictions

When category=authentication, the fields header_type, header_content, header_file, and footer are prohibited. buttons is limited to a single item of type COPY_CODE or ONE_TAP.

Error Responses

Status Cause Body
401 Missing or invalid X-API-KEY {"error": "Unauthorized"}
422 Validation failed or non-meta-direct company {"error": "...", "message": "..."}
404 Template not found or not approved (send endpoint) {"error": "Template not found or not approved."}
500 Meta API call failed {"error": "Failed to send template message.", "detail": "..."}