External APItemplatesCreate Template

Create Template

Overview

This API creates a WhatsApp message template through WappCloud’s platform by submitting it directly to Meta for review.

Templates with media headers (Image, Document, Video) require uploading the file first via the Upload Media endpoint to obtain the h handle and s3Url.


Endpoint

POST https://client-api.wappcloud.com/api/v1/external/templates

Headers

HeaderDescription
x-api-key(Required) Your API Key for authentication
Authorization(Required) Bearer Token
Content-Typeapplication/json

Common Fields

FieldTypeRequiredDescription
namestringYesLowercase letters, numbers, and underscores only. Max 512 chars
categorystringYesMARKETING, UTILITY, or AUTHENTICATION
languagestringYesLanguage code e.g. en_US, hi, ta, ar
componentsarrayYesArray of component objects (HEADER, BODY, FOOTER, BUTTONS)
s3UrlstringNoRequired only for media header templates (from Upload Media)
allow_category_changebooleanNoIf true, Meta may reassign the category automatically

Setting Up in Postman

  1. Select the Body tab
  2. Choose raw
  3. From the dropdown select JSON
  4. Paste the request body

Request Payloads


1. Static — Text Body Only

The simplest template. No header, no footer, no buttons.

{
  "name": "static_text_only",
  "category": "UTILITY",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Your order has been confirmed. Thank you for shopping with us."
    }
  ]
}

{
  "name": "static_text_header_footer",
  "category": "MARKETING",
  "language": "en_US",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Welcome to WappCloud!"
    },
    {
      "type": "BODY",
      "text": "We are excited to have you on board. Explore all the features available to you."
    },
    {
      "type": "FOOTER",
      "text": "Reply STOP to unsubscribe"
    }
  ]
}

Step 1: Upload image via Upload Media → get h and s3Url. Step 2: Use those values below.

{
  "name": "static_image_header",
  "category": "MARKETING",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "IMAGE",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Check out our latest collection. Limited time offer!"
    },
    {
      "type": "FOOTER",
      "text": "Terms and conditions apply"
    }
  ]
}

4. Static — Document Header + Body

Upload a PDF first via Upload Media.

{
  "name": "static_document_header",
  "category": "UTILITY",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "DOCUMENT",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Please find your invoice attached. Contact us for any queries."
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Billing"
    }
  ]
}

5. Static — Video Header + Body

Upload an MP4 first via Upload Media.

{
  "name": "static_video_header",
  "category": "MARKETING",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "VIDEO",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Watch our product demo. We think you will love it!"
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Team"
    }
  ]
}

6. Dynamic — Body Variables Only

Use {{1}}, {{2}}, {{3}} as placeholders in the body. Provide example values in body_text (one array per placeholder, in order).

{
  "name": "dynamic_body_variables",
  "category": "UTILITY",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Hi {{1}}, your order #{{2}} has been shipped. Expected delivery: {{3}}.",
      "example": {
        "body_text": [["John", "ORD-9821", "Dec 25, 2024"]]
      }
    }
  ]
}

7. Dynamic — Text Header Variable + Body Variables

The header text can also contain a variable {{1}}.

{
  "name": "dynamic_text_header_body",
  "category": "MARKETING",
  "language": "en_US",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Hello {{1}}!",
      "example": {
        "header_text": ["Sarah"]
      }
    },
    {
      "type": "BODY",
      "text": "Your exclusive {{1}}% discount is valid until {{2}}. Use code {{3}} at checkout.",
      "example": {
        "body_text": [["20", "Dec 31, 2024", "SAVE20"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Rewards"
    }
  ]
}

8. Dynamic — Image Header + Body Variables

{
  "name": "dynamic_image_header_body",
  "category": "MARKETING",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "IMAGE",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Hi {{1}}, your appointment is confirmed for {{2}} at {{3}}.",
      "example": {
        "body_text": [["Rahul", "Monday, Dec 23", "10:00 AM"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "Reply NO to cancel"
    }
  ]
}

9. Dynamic — Document Header + Body Variables

{
  "name": "dynamic_document_header_body",
  "category": "UTILITY",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "DOCUMENT",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Hi {{1}}, your invoice #{{2}} for ₹{{3}} is ready for download.",
      "example": {
        "body_text": [["Priya", "INV-4521", "2,500"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Billing"
    }
  ]
}

10. Dynamic — Video Header + Body Variables

{
  "name": "dynamic_video_header_body",
  "category": "MARKETING",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "VIDEO",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Hi {{1}}, here is your personalised product demo for {{2}}.",
      "example": {
        "body_text": [["Arun", "WappCloud Pro"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Team"
    }
  ]
}

11. Static — Quick Reply Buttons

Up to 3 quick reply buttons. No variables needed.

{
  "name": "quick_reply_static",
  "category": "MARKETING",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Are you interested in our new product launch this weekend?"
    },
    {
      "type": "FOOTER",
      "text": "WappCloud"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        { "type": "QUICK_REPLY", "text": "Yes, tell me more!" },
        { "type": "QUICK_REPLY", "text": "No, thanks" },
        { "type": "QUICK_REPLY", "text": "Remind me later" }
      ]
    }
  ]
}

12. Static — Call to Action Buttons (URL + Phone)

{
  "name": "cta_url_and_phone",
  "category": "UTILITY",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Your payment is due. Pay now online or call our support team for assistance."
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Billing"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "URL",
          "text": "Pay Now",
          "url": "https://billing.wappcloud.com/pay",
          "example": ["https://billing.wappcloud.com/pay"]
        },
        {
          "type": "PHONE_NUMBER",
          "text": "Call Support",
          "phone_number": "+919876543210"
        }
      ]
    }
  ]
}

13. Dynamic — URL Button with Variable

The URL can contain a variable {{1}} that is replaced at send time (e.g., a unique tracking ID per recipient).

{
  "name": "dynamic_url_button",
  "category": "UTILITY",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Hi {{1}}, your shipment is on its way. Track it in real time.",
      "example": {
        "body_text": [["Priya"]]
      }
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "URL",
          "text": "Track Order",
          "url": "https://track.wappcloud.com/{{1}}",
          "example": ["https://track.wappcloud.com/ORD-9821"]
        }
      ]
    }
  ]
}

14. Dynamic — Quick Reply + Body Variables

{
  "name": "dynamic_body_quick_reply",
  "category": "MARKETING",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "Hi {{1}}, your exclusive offer of {{2}}% off expires on {{3}}. Would you like to claim it?",
      "example": {
        "body_text": [["Arun", "30", "Dec 31, 2024"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "WappCloud Deals"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        { "type": "QUICK_REPLY", "text": "Claim Offer" },
        { "type": "QUICK_REPLY", "text": "Not Interested" }
      ]
    }
  ]
}

15. Full Template — All Sections Dynamic

Image header + body variables + footer + mixed buttons (URL with variable + phone + quick reply).

{
  "name": "full_dynamic_all_sections",
  "category": "MARKETING",
  "language": "en_US",
  "s3Url": "<s3Url from upload response>",
  "components": [
    {
      "type": "HEADER",
      "format": "IMAGE",
      "example": {
        "header_handle": ["<h from upload response>"]
      }
    },
    {
      "type": "BODY",
      "text": "Hi {{1}}, your {{2}} is ready for pickup at {{3}}. Show this message at the counter.",
      "example": {
        "body_text": [["Arun", "order", "MG Road Store"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "WappCloud | Valid today only"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "URL",
          "text": "View Order",
          "url": "https://wappcloud.com/orders/{{1}}",
          "example": ["https://wappcloud.com/orders/ORD-9821"]
        },
        {
          "type": "PHONE_NUMBER",
          "text": "Call Store",
          "phone_number": "+919876543210"
        },
        {
          "type": "QUICK_REPLY",
          "text": "Confirm Pickup"
        }
      ]
    }
  ]
}

16. Authentication — OTP Template

Used for sending one-time passwords. Category must be AUTHENTICATION.

{
  "name": "otp_verification_code",
  "category": "AUTHENTICATION",
  "language": "en_US",
  "components": [
    {
      "type": "BODY",
      "text": "{{1}} is your verification code. For your security, do not share this code.",
      "add_security_recommendation": true,
      "example": {
        "body_text": [["123456"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "This code expires in 10 minutes.",
      "code_expiration_minutes": 10
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "OTP",
          "otp_type": "COPY_CODE",
          "text": "Copy Code"
        }
      ]
    }
  ]
}

Response (Success)

{
  "success": true,
  "code": 200,
  "message": "Template created successfully",
  "data": {
    "id": "1234567890123456",
    "status": "PENDING",
    "category": "MARKETING"
  }
}
FieldDescription
idMeta’s template ID
statusInitial status — always PENDING until Meta reviews and approves it
categoryThe category assigned (Meta may change this if allow_category_change is true)

Error Responses

400 Bad Request

Returned when the payload is invalid (e.g. missing required field, invalid category, invalid language code).

{
  "success": false,
  "code": 400,
  "message": "Invalid request body"
}

401 Unauthorized

{
  "error": "Missing authToken or x-api-key"
}

Notes

  • Template name rules: lowercase letters, numbers, and underscores only (a-z, 0-9, _). No spaces or uppercase.
  • Variable order: must be sequential starting at {{1}} — e.g. {{1}}, {{2}}, {{3}}. Skipping numbers is not allowed.
  • Media templates: always call Upload Media first to get h and s3Url.
  • example values: required by Meta for all components that contain variables or media. They are sample values shown during template review — they are not sent to the end user.
  • Status after creation: templates are always PENDING initially. Use List Templates to check when a template moves to APPROVED or REJECTED.
  • Language codes: use valid WhatsApp language codes — e.g. en_US (English), hi (Hindi), ta (Tamil), ar (Arabic). See Meta’s documentation for the full list.