Send WhatsApp Business API with Different Types of Template

  • Updated

WhatsApp Business API is designed with powerful messaging experiences to meet your business needs. Beyond the inbound message from multiple WhatsApp channels that you can handle with Qiscus Omnichannel, don’t have to worry about losing any chances to have more interactions with your customers by sending outbound messages. Have your own flow? Just send it through API! In this article, we give you some API samples with various templates.

 

We assume you have decided on your use cases (OTP, account update, ticket information, etc.) and have already submitted the outbound message template through the Qiscus Omnichannel dashboard.

 

Before we start, here are what you need:

  • Read the documentation here
  • Qiscus App ID and Qiscus Secret Key
    blobid1.png
  • Channel ID, Template Name, Language, & Namespace from your approved template
    blobid2.png
  • Ensure the components that you have submitted in the template. The template can handle these components:
    • Header (optional):
      • Text with 1 variable
      • Media (Image/Video/Document) variable
    • Body:
      • Text with up to 15 variable
    • Footer (optional):
      • Text
    • Buttons (optional):
      • Call To Action
        • Call Phone Number
        • Visit Website
          • Static
          • Dynamic with 1 variable
      • Quick Reply
        • Up to 3 text buttons
    • Code Delivery (only for Authentication category)
      • Copy Code
      • Auto-Fill
  • Phone number
    Must include country code without + (e.g. 62xxxxx) and valid as a WhatsApp account.
  • Additional notes
    • The maximum template content including variables:
      • Header 60 characters
      • Body 1024 characters
    • Make sure there is no unknown character like this to prevent errors
      �, â, €, ¬, â, œ, “, etc.

 

1. Body only, no variable

This example is using a simple template that only has content in the body section, without headers, buttons, or variables. Below is the API request.

Example template:

mceclip1.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
       "name": "noparam",
       "language": {
           "policy": "deterministic",
           "code": "en"
       }
   }
}'

Note: The language code will be different for each language. Please refer here to see the codes.
Because this template only contains a body without variables, the text will be the same as you have submitted in the template.

Result:

WhatsApp_Image_2022-02-15_at_11.24.14_AM.jpeg

 

2. Body with multiple text variables

The body is possible to handle up to 15 text variables. When you send with API, it will look like this.

Example template:

mceclip2.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
       "name": "90daysfreetrial3",
       "language": {
           "policy": "deterministic",
           "code": "id"
       },
       "components": [
           {
               "type" : "body",
               "parameters": [
                   {
                       "type": "text",
                       "text": "{{body_var1}}"
                   },
                   {
                       "type": "text",
                       "text": "{{body_var2}}"
                   }
               ]
          }
       ]
   }
}'

Result:

WhatsApp_Image_2022-02-15_at_11.24.13_AM__2_.jpeg

 

3. Header with a text variable

Unlike the body section, the header only can contain 1 text variable. 

Example template:

mceclip3.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
      "name": "header_text_with_var",
       "language": {
           "policy": "deterministic",
           "code": "id"
       },
       "components": [
           {
               "type" : "header",
               "parameters": [
                   {
                  "type": "text",
                  "text": "{{header_var1}}"
                   }
               ]
          },
           {
               "type" : "body",
               "parameters": [
                   {
                       "type": "text",
                      "text": "{{body_var1}}"
                  },
                   {
                       "type": "text",
                      "text": "{{body_var2}}"
                   }
               ]
          }
       ]
   }
}'

Note: If your header doesn't have a variable, just remove the header component.

Result:

WhatsApp_Image_2022-02-15_at_11.24.13_AM__1_.jpeg

 

4. Header with an image variable

Example template:

mceclip4.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
     "name": "image_demo",
       "language": {
           "policy": "deterministic",
           "code": "id"
       },
       "components": [
           {
               "type" : "header",
               "parameters": [
                  {
                   "type": "image",
                   "image": {
                    "link": "{{image_url}}"
                    }
                   }
               ]
          },
           {
               "type" : "body",
               "parameters": [
                   {
                       "type": "text",
                     "text": "{{body_var1}}"
                 }
               ]
          }
       ]
   }
}'

Note: The image URL must be direct, not shortened URL.
(e.g. https://d1edrlpyc25xu0.cloudfront.net/ramo-29lun8b1ulepsaio/image/upload/w_320,h_320,c_limit/zx64Ye2CA3/eae2beadacb892edac858b045b2c0d1c.png)

Result:

WhatsApp_Image_2022-02-15_at_11.24.12_AM__2_.jpeg

 

5. Header with a video variable

Example template:

mceclip5.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
     "name": "penjelasanmultichannel",
       "language": {
           "policy": "deterministic",
           "code": "id"
       },
       "components": [
           {
               "type" : "header",
               "parameters": [
                  {
                  "type": "video",
                  "video": {
                   "link": "{{video_url}}"
                   }
                 }
               ]
          },
           {
               "type" : "body",
               "parameters": [
                   {
                    "type": "text",
                     "text": "{{body_var1}}"
                 }
               ]
          }
       ]
   }
}'

Note: The video URL must be direct, not shortened URL.

(e.g. https://d1edrlpyc25xu0.cloudfront.net/hat-ppxmocchbbcbhopzk/video/upload/LdBf7CGc_1/final_620a46a7ae155601096e4f7f_749103.mp4

Result:

WhatsApp_Image_2022-02-15_at_11.24.13_AM.jpeg

 

6. Header with a document variable

Example template:

mceclip8.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
     "name": "information_update",
       "language": {
           "policy": "deterministic",
          "code": "ms"
       },
       "components": [
           {
               "type" : "header",
               "parameters": [
                  {
                  "type": "document",
                  "document": {
                  "link": "{{document_url}}",
"filename": "{{file_name}}"
                  }
                 }
               ]
         },
           {
               "type" : "body",
               "parameters": [
                   {
                    "type": "text",
                    "text": "{{body_var1}}"
                }
               ]
          }
       ]
   }
}'

Note: The document URL must be direct, not shortened URL. If you want to change the document name, just put it on "filename".

(e.g. https://d1edrlpyc25xu0.cloudfront.net/hat-ppxmocchbbcbhopzk/docs/upload/e7h9vQdk3_/qiscus.pdf)

Result:

WhatsApp_Image_2022-02-15_at_11.24.12_AM__1_.jpeg

 

7. Button - Call To Action with dynamic URL

If you're using Call To Action button, there are 3 options of action type when creating the template:

  • Call phone number
  • Visit website (static URL)
  • Visit website (dynamic URL): only add a custom suffix of the URL

You can only have 2 Call To Action Buttons (Call phone number & Visit website static/dynamic).
In the API, call phone number and visit website (static URL) no need to be included. It will use the default from the template that you have already submitted. Below is an example of dynamic URL usage.

Example template:

mceclip7.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
     "name": "ticket_resolved_123",
       "language": {
           "policy": "deterministic",
           "code": "id"
       },
      "components": [
           {
               "type" : "header",
              "parameters": [
                   {
                 "type": "text",
                "text": "{{header_var1}}"
                   }
               ]
          },
           {
               "type" : "body",
               "parameters": [
                   {
                    "type": "text",
                     "text": "{{body_var1}}"
                 }
               ]
          },
{
               "type":"button",
               "sub_type": "url",
               "index": 1,
              "parameters": [
                   {
                       "type": "text",
                      "text": "{{url_var1}}"
                   }
               ]
          }
       ]
   }
}'

Note: The value of "index" depends on the order of the Call To Action buttons you have in the template (0 - 1). In this example, the index is 1.
mceclip0.png

Result:

WhatsApp_Image_2022-02-15_at_11.24.41_AM.jpeg

 

8. Button - Quick Reply

The template can contain max 3 Quick Reply buttons.

Example template:

mceclip9.png

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
    "name": "ticket_resolved_123",
       "language": {
           "policy": "deterministic",
          "code": "en"
       },
      "components": [
           {
               "type" : "header",
              "parameters": [
                   {
                 "type": "text",
                "text": "{{header_var1}}"
                   }
               ]
         },
           {
               "type" : "body",
               "parameters": [
                   {
                    "type": "text",
                     "text": "{{body_var1}}"
                 }
               ]
         },
{
               "type":"button",
              "sub_type": "quick_reply",
              "index": 0,
              "parameters":[
                   {
                     "type": "payload",
                     "payload": "{{payload_var1}}"
                   }
               ]
          },
{
             "type":"button",
              "sub_type": "quick_reply",
             "index": 1,
              "parameters":[
                   {
                     "type": "payload",
                    "payload": "{{payload_var2}}"
                   }
               ]
          }
]
   }
}'

Note: Parameters in button quick reply are optional. The payload will be sent back when customers click the quick reply button on their WhatsApp. To see it, you have to listen through a webhook. You can remove it if not needed. 

          {
             "type":"button",
              "sub_type": "quick_reply",
             "index": 0,
             "parameters":[]
         }

Result:

WhatsApp_Image_2022-02-15_at_11.24.12_AM.jpeg

9. Code Delivery - Copy Code (OTP)

Please read this for the full guideline. 

Example template:

Screenshot_20230529_170611_Chrome.jpg

Request:

curl --location -g --request POST 'https://omnichannel.qiscus.com/whatsapp/v1/{{app_id}}/{{channel_id}}/messages' \
--header 'Qiscus-App-Id: {{app_id}}' \
--header 'Qiscus-Secret-Key: {{secret_key}}' \
--header 'Content-Type: application/json' \
--data-raw '{
   "to": "{{phone_number}}",
   "type": "template",
   "template": {
       "namespace": "{{namespace}}",
    "name": "new_otp",
       "language": {
           "policy": "deterministic",
          "code": "en"
       },
     "components": [
           {
               "type" : "body",
               "parameters": [
                   {
                    "type": "text",
                    "text": "{{otp_number}}"
                 }
               ]
         },
{
               "type":"button",
               "sub_type": "url",
              "index": 0,
              "parameters": [
                   {
                       "type": "text",
                     "text": "{{otp_number}}"
                   }
               ]
          }
       ]
   }
}'

 

10. Footer

No need to include the footer in your API payload (will automatically use the submitted footer text template).

 

If you find any errors, please see the following article Failed WhatsApp Broadcast Message with CSV or API 

 

 

Was this article helpful?

Comments

0 comments

Article is closed for comments.