WHATSAPP

Send transactional messages on WhatsApp at scale

Send OTPs, order confirmations, and delivery alerts on the channel your customers already engage with. Zoho CPaaS (formerly ZeptoMail) gives you the full stack to run it with WABA configuration, Meta-approved templates, Agent-based number routing, and four-level delivery analytics.


const url = "https://cpaas.zoho.com/v1.1/whatsapp";
const token = "<Authorization-token>";

const requestBody = {
  from: "<FROM_PHONE_NUMBER>",
  to: "<TO_PHONE_NUMBER>",
  template_key: "<TEMPLATE_KEY>",
  merge_info: { "<merge_key>": "<merge_value>" }
};

fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: token
  },
  body: JSON.stringify(requestBody)
})
  .then((response) => response.json())
  .then((resp) => console.log("success"))
  .catch((error) => console.log(error, "error"));
                                            

curl --location 'https://cpaas.zoho.com/v1.1/whatsapp' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: <Authorization-token>' \
  --data '{
    "from": "<FROM_PHONE_NUMBER>",
    "to": "<TO_PHONE_NUMBER>",
    "template_key": "<TEMPLATE_KEY>",
    "merge_info": {"<merge_key>": "<merge_value>"}
  }'
                                            

using System;
using System.Net;
using System.Text;
using System.IO;
using Newtonsoft.Json.Linq;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
            var baseAddress = "https://cpaas.zoho.com/v1.1/whatsapp";

            var http = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
            http.Accept = "application/json";
            http.ContentType = "application/json";
            http.Method = "POST";
            http.PreAuthenticate = true;
            http.Headers.Add("Authorization", "<Authorization-token>");

            JObject parsedContent = JObject.Parse("{'from': '<FROM_PHONE_NUMBER>','to': '<TO_PHONE_NUMBER>','template_key': '<TEMPLATE_KEY>','merge_info': {'<merge_key>': '<merge_value>'}}");

            ASCIIEncoding encoding = new ASCIIEncoding();
            Byte[] bytes = encoding.GetBytes(parsedContent.ToString());
            Stream newStream = http.GetRequestStream();
            newStream.Write(bytes, 0, bytes.Length);
            newStream.Close();

            var response = http.GetResponse();
            var stream = response.GetResponseStream();
            var sr = new StreamReader(stream);
            var content = sr.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}
                                            

import requests
import json

url = "https://cpaas.zoho.com/v1.1/whatsapp"

payload = json.dumps({
    "from": "<FROM_PHONE_NUMBER>",
    "to": "<TO_PHONE_NUMBER>",
    "template_key": "<TEMPLATE_KEY>",
    "merge_info": {"<merge_key>": "<merge_value>"}
})

headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "authorization": "<Authorization-token>"
}

response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
                                            

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => "https://cpaas.zoho.com/v1.1/whatsapp",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => json_encode(array(
        "from" => "<FROM_PHONE_NUMBER>",
        "to" => "<TO_PHONE_NUMBER>",
        "template_key" => "<TEMPLATE_KEY>",
        "merge_info" => array(
            "<merge_key>" => "<merge_value>"
        )
    )),
    CURLOPT_HTTPHEADER => array(
        "accept: application/json",
        "authorization: <Authorization-token>",
        "cache-control: no-cache",
        "content-type: application/json"
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #:" . $err;
} else {
    echo $response;
}
?>
                                            

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;

public class WabaTemplateSendApi {
    public static void main(String[] args) throws Exception {
        String postUrl = "https://cpaas.zoho.com/v1.1/whatsapp";
        BufferedReader br = null;
        HttpURLConnection conn = null;
        String output = null;
        StringBuffer sb = new StringBuffer();
        try {
            URL url = new URL(postUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Authorization", "<Authorization-token>");

            JSONObject mergeInfo = new JSONObject();
            mergeInfo.put("<merge_key>", "<merge_value>");

            JSONObject body = new JSONObject();
            body.put("from", "<FROM_PHONE_NUMBER>");
            body.put("to", "<TO_PHONE_NUMBER>");
            body.put("template_key", "<TEMPLATE_KEY>");
            body.put("merge_info", mergeInfo);

            OutputStream os = conn.getOutputStream();
            os.write(body.toString().getBytes());
            os.flush();

            br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
            while ((output = br.readLine()) != null) {
                sb.append(output);
            }
            System.out.println(sb.toString());
        } catch (Exception e) {
            br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
            while ((output = br.readLine()) != null) {
                sb.append(output);
            }
            System.out.println(sb.toString());
        } finally {
            if (br != null) br.close();
            if (conn != null) conn.disconnect();
        }
    }
}        
                                            

HOW IT WORKS

How transactional WhatsApp works in Zoho CPaaS

One POST request. Simply pass your sender key, recipient number, template key and variables—delivery and tracking are handled automatically. Works across all of your templates and WABAs. No extra SDKs or channel-specific setup.

templatevariablesroutedelivered

PRICING

Credit-based pricing with no monthly lock-in

Credit-based model
No monthly payments
No lock-ins

Only pay for what you send with our flexible credit-based pricing. Our WhatsApp channel runs on a credit-based model. Buy credits and spend them as you send. No monthly payments or lock-ins.

View Pricing

What businesses send on WhatsApp

Transactional WhatsApp messages cover any system-triggered notification that a user expects after taking an action—from authentication to fulfillment updates.

Authentication and OTPs

One-time passwords and 2FA prompts on a channel with higher open rates than SMS.

Order and delivery updates

Status notifications from order placement to delivery, with tracking links and contact buttons built in.

Payment confirmations

Receipts, invoice alerts, and transaction acknowledgements are triggered immediately after a payment event.

Account and security alerts

Password resets, login alerts, and policy updates are sent the moment an account event occurs.

Appointment reminders

Booking confirmations and pre-appointment reminders with the date, time, and a call or reschedule button.

System and service alerts

Downtime alerts, maintenance windows, and threshold notifications delivered without delay.

One place to manage all your WABAs

Connect your Meta-approved WhatsApp Business Accounts to Zoho CPaaS and manage phone numbers, Agent routing, and account status without leaving the platform.

WABA configuration

WABA

WABA configuration

Each WhatsApp Business Account is listed with its display name, active status, and unique WABA ID. Add multiple WABAs under a single Zoho CPaaS account to keep brands or business units cleanly separated—each with its own phone numbers, templates, and delivery data.

ROUTING

Phone number and Agent routing

Register multiple phone numbers under each WABA and map each number to a specific Agent. The Agent controls which API credentials handle outbound traffic for that number so you can segment sending by product line, region, or deployment environment.

Phone number and Agent routing

Build, submit, and manage templates

Every transactional WhatsApp message is powered by a Meta-approved template. Zoho CPaaS gives you a full template editor with a live preview, multi-language support, and approval status tracking.

Template editor

TEMPLATES

Template editor

Compose templates with a header, body, and footer. Add dynamic content using {{variable}} placeholders that get filled at send time. Attach buttons and see exactly how the message renders in a live phone preview before submitting.

APPROVALS

Approval and multi-language support

Submit templates for Meta approval and track their status without switching tabs. Create language-specific versions of the same template, each submitted and approved independently. Blocked templates can be revised and resubmitted directly from the platform.

Approval and multi-language support

ANALYTICS

Delivery data at every level

Track sent, failed, delivered, and seen data across four scopes so you can drill down and isolate issues at exactly the right granularity.

 

By WABA

Aggregate delivery overview for all messages sent under a WhatsApp Business Account.

 

By phone number

See delivery performance per registered number. This is useful when multiple numbers operate under the same WABA.

 

By Agent

Per-Agent delivery breakdown with a Logs tab. View timestamped records of every message with status, recipient, and template.

 

By template

Time-series chart of Sent, Failed, Delivered, and Seen per template, filterable by custom date range.

Frequently asked questions

It’s a system-triggered notification sent via the WhatsApp Business API using a pre-approved template like OTPs, order updates, payment receipts, account alerts.

A WABA (WhatsApp Business Account) is the Meta-level account required to send template messages programmatically. You need one before connecting to Zoho CPaaS. If you don’t have a WABA yet, apply through Meta first, then add it to the platform.

Yes, each template is language-specific. Create a separate version for each language you need, submit each for approval independently, and reference the appropriate one at send time via the language code in the API call.

Read means the recipient opened the message in their WhatsApp client. WhatsApp supports read receipts at the API level, making “Read” a fourth delivery state beyond Sent, Failed, and Delivered.

Start sending transactional WhatsApp messages today