Experia Docs

WhatsApp Templates API

For schema reference, validation rules, supported languages, and component details, see whatsapp_templates.md.

This document describes how to call each WhatsApp template endpoint with curl examples, request/response formats, and per-endpoint errors.


First Template Walkthrough

A typical journey to deliver a template to your users:

  1. Upload media (only if your template has an IMAGE/VIDEO/DOCUMENT header) → Upload Media returns a handle
  2. Create templateCreate Template submits to Meta for review. Use the upload's handle inside creation[*].example.header_handle if you have a media header
  3. Wait for approval → Meta reviews asynchronously. Watch the template_status_update webhook for under_reviewapproved (or rejected)
  4. Send template message → use the template id as tempMsgID in Send Message once status is approved
  5. Update / Delete later via Update Template or Delete Template

Create Template

Create a new WhatsApp template and submit it for review.

Endpoint

POST /v2/whatsapp/templates

Authentication

HeaderRequiredDescription
X-API-KeyYesYour API key
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
namestringYesTemplate name (lowercase letters, digits, underscores only)
categorystringYesOne of AUTHENTICATION, MARKETING, UTILITY
languagestringYesLanguage code (e.g. en_US, ar). See whatsapp_templates.md
creationarrayYesComponents array. Must contain a BODY component

compose is auto-generated from creation by the gateway - do not send it.

For component structure (HEADER, BODY, FOOTER, BUTTONS, CAROUSEL), see whatsapp_templates.md.

Example - Text-only template

curl -X POST "https://api.experiaapp.com/v2/whatsapp/templates" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "welcome_simple",
    "category": "UTILITY",
    "language": "en_US",
    "creation": [
      { "type": "BODY", "text": "Welcome to our service!" }
    ]
  }'

Example - Template with media header

For an IMAGE / VIDEO / DOCUMENT header, first upload the media via Upload Media and pass the returned handle in example.header_handle:

curl -X POST "https://api.experiaapp.com/v2/whatsapp/templates" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "promo_with_image",
    "category": "MARKETING",
    "language": "en_US",
    "creation": [
      {
        "type": "HEADER",
        "format": "IMAGE",
        "example": {
          "header_handle": ["4::aW...=="]
        }
      },
      { "type": "BODY", "text": "Limited time offer just for you!" }
    ]
  }'

Response

{
  "id": "cac845bf-910d-48f5-b70e-77f3fe806134",
  "name": "welcome_simple",
  "title": "welcome_simple",
  "category": "UTILITY",
  "language": "en_US",
  "status": "submitted",
  "creation": "[{\"type\":\"BODY\",\"text\":\"Welcome to our service!\"}]",
  "compose": "{\"to\":\"<accountID>\",\"type\":\"template\",\"template\":{...}}",
  "whatsappID": "",
  "rejectReason": "",
  "qualityRating": "",
  "isMinExperia": false,
  "createdAt": "2026-01-15T10:30:00Z"
}

The template enters status submitted, then transitions to under_review once submitted to Meta, then approved or rejected. See Template Statuses.

Errors

StatusErrorCause
400Category must be one of AUTHENTICATION, MARKETING, or UTILITYInvalid category value
400At least one component is required in the creation fieldEmpty creation array
400A BODY component is required in the creation fieldMissing required BODY component
400Invalid request bodyMalformed JSON
401UnauthorizedMissing or invalid API key
502Bad gatewayService temporarily unavailable

List / Get Templates

Retrieve all templates for the consumer's channel, or a specific template by ID.

Endpoint

GET /v2/whatsapp/templates
GET /v2/whatsapp/templates?templateID={id}

Authentication

HeaderRequiredDescription
X-API-KeyYesYour API key

Query Parameters

ParameterTypeRequiredDescription
templateIDstringNoIf provided, returns the single matching template. Omit to list all

Example - List all

curl "https://api.experiaapp.com/v2/whatsapp/templates" \
  -H "X-API-Key: YOUR_API_KEY"

Example - Single template

curl "https://api.experiaapp.com/v2/whatsapp/templates?templateID=cac845bf-910d-48f5-b70e-77f3fe806134" \
  -H "X-API-Key: YOUR_API_KEY"

Response

Returns an array of template objects:

[
  {
    "id": "cac845bf-910d-48f5-b70e-77f3fe806134",
    "name": "welcome_simple",
    "title": "welcome_simple",
    "category": "UTILITY",
    "language": "en_US",
    "status": "approved",
    "creation": "[{\"type\":\"BODY\",\"text\":\"Welcome to our service!\"}]",
    "compose": "{\"to\":\"<accountID>\",\"type\":\"template\",\"template\":{...}}",
    "whatsappID": "1008681241488740",
    "rejectReason": "",
    "qualityRating": "",
    "isMinExperia": false,
    "createdAt": "2026-01-15T10:30:00Z",
    "updateAt": { "Valid": true, "Time": "2026-01-15T11:00:00Z" },
    "deleteAt": { "Valid": false, "Time": "0001-01-01T00:00:00Z" }
  }
]

Errors

StatusErrorCause
401UnauthorizedMissing or invalid API key
502Bad gatewayService temporarily unavailable

Update Template

Update content (and optionally name/category) of an existing template. Only templates with status APPROVED, REJECTED, or PAUSED can be edited.

Endpoint

POST /v2/whatsapp/templates/update

Authentication

HeaderRequiredDescription
X-API-KeyYesYour API key
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
idstringYesTemplate ID to update
creationstringNoNew components as JSON-encoded string. e.g. "[{\"type\":\"BODY\",\"text\":\"new text\"}]"
titlestringNoNew title. Cannot be changed for APPROVED templates. If omitted, existing title is kept
categorystringNoNew category. Ignored for APPROVED templates (Meta restriction)

compose is auto-generated from creation by the gateway - do not send it.

Editing Rules

  • APPROVED templates: only creation (content) can be changed; max 10 edits per 30-day window or 1 per 24 hours
  • REJECTED / PAUSED templates: all fields can be changed freely
  • Templates in any other status (submitted, under_review) cannot be edited

Example

curl -X POST "https://api.experiaapp.com/v2/whatsapp/templates/update" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "cac845bf-910d-48f5-b70e-77f3fe806134",
    "creation": "[{\"type\":\"BODY\",\"text\":\"Updated content\"}]"
  }'

Response

{
  "id": "cac845bf-910d-48f5-b70e-77f3fe806134",
  "name": "welcome_simple",
  "title": "welcome_simple",
  "category": "UTILITY",
  "language": "en_US",
  "status": "submitted",
  "creation": "[{\"type\":\"BODY\",\"text\":\"Updated content\"}]",
  "compose": "{\"to\":\"<accountID>\",\"type\":\"template\",\"template\":{...}}",
  "whatsappID": "1008681241488740",
  "rejectReason": "",
  "qualityRating": "",
  "isMinExperia": false,
  "updateAt": { "Valid": true, "Time": "2026-01-15T12:00:00Z" }
}

After Meta accepts the update, status transitions to under_review, then to approved or rejected once Meta finishes its review. Webhooks fire on each transition.

Errors

StatusErrorCause
400Only APPROVED, REJECTED, or PAUSED templates can be editedTemplate is not in an editable status
400Cannot change name of an approved templatetitle was provided and differs from existing title on an APPROVED template
400Approved template edit limit reached (max 10 edits in 30 days or 1 in 24h)Edit rate limit hit
400Invalid creation formatcreation field is not valid JSON
404Template not foundNo template with given id
401UnauthorizedMissing or invalid API key
500Internal server errorServer-side error
502Bad gatewayService temporarily unavailable

Delete Template

Delete an existing template. The deletion is propagated to Meta.

Endpoint

DELETE /v2/whatsapp/templates

Authentication

HeaderRequiredDescription
X-API-KeyYesYour API key
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
idstringYesTemplate ID to delete

Example

curl -X DELETE "https://api.experiaapp.com/v2/whatsapp/templates" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "id": "cac845bf-910d-48f5-b70e-77f3fe806134" }'

Response

Returns the deleted template object:

{
  "id": "cac845bf-910d-48f5-b70e-77f3fe806134",
  "name": "welcome_simple",
  "title": "welcome_simple",
  "category": "UTILITY",
  "language": "en_US",
  "status": "approved",
  "creation": "[{\"type\":\"BODY\",\"text\":\"Welcome to our service!\"}]",
  "compose": "{\"to\":\"<accountID>\",\"type\":\"template\",\"template\":{...}}",
  "whatsappID": "1008681241488740",
  "deleteAt": { "Valid": true, "Time": "2026-01-15T13:00:00Z" }
}

Errors

StatusCodeMessageCause
400-Invalid request bodyMissing or malformed id
4001033template not foundNo template with given id
401-UnauthorizedMissing or invalid API key
5001029Internal server errorServer-side error
502-Bad gatewayService temporarily unavailable

Upload Media

Upload media (image, video, document) and get a handle/URL to use in template HEADER components.

Endpoint

POST /v2/whatsapp/upload

Authentication

HeaderRequiredDescription
X-API-KeyYesYour API key
Content-TypeYesmultipart/form-data

Form Fields

FieldTypeRequiredDescription
filefileYesMedia file to upload

Size Limits

FormatMax Size
IMAGE5 MB
VIDEO16 MB
DOCUMENT100 MB

Example

curl -X POST "https://api.experiaapp.com/v2/whatsapp/upload" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "file=@/path/to/image.jpg"

Response

{
  "h": "4::aW...=="
}

Use the returned h value inside a HEADER component's example.header_handle array when creating templates - see the Create Template - media header example.

Errors

StatusCodeMessageCause
4001029Upload error: ...Missing file or read error
5001029Upload error: ...Internal upload failure
502-Bad gatewayService temporarily unavailable

Template Lifecycle

A template moves through these statuses:

submitted → under_review → approved
                        → rejected
                        → submit_failed (validation/transport error before Meta accepted)

For full status descriptions see Template Statuses.

Webhook Events

A TemplateStatus webhook is published on every status transition. Example payload:

{
  "Type": "TemplateStatus",
  "SourceID": "CHANNEL_ID",
  "Event": {
    "Type": "template_status_update",
    "templateID": "cac845bf-910d-48f5-b70e-77f3fe806134",
    "status": "approved",
    "rejectReason": "",
    "qualityRating": "",
    "updatedAt": "2026-01-15T12:59:05Z"
  }
}

For all webhook payload formats see webhook_response.md.


Rate Limiting

  • 200 requests per hour per API key
  • HTTP 429 returned when limit is exceeded
On this page