curl --request POST \
--url https://crm.wachat.net/api/v1/templates/{id}/send \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'to=<string>' \
--form 'device_id=<string>' \
--form 'header_text=<string>' \
--form 'header_media_url=<string>' \
--form 'header_media=<string>' \
--form 'header_filename=<string>' \
--form 'body=<string>' \
--form 'buttons={
"index": 1,
"sub_type": "<string>",
"value": "<string>"
}' \
--form header_media.0='@example-file' \
--form header_media.1='@example-file'import requests
url = "https://crm.wachat.net/api/v1/templates/{id}/send"
files = {
"header_media.0": ("example-file", open("example-file", "rb")),
"header_media.1": ("example-file", open("example-file", "rb"))
}
payload = {
"to": "<string>",
"device_id": "<string>",
"header_text": "<string>",
"header_media_url": "<string>",
"header_media": "<string>",
"header_filename": "<string>",
"body": "<string>",
"buttons": "{
\"index\": 1,
\"sub_type\": \"<string>\",
\"value\": \"<string>\"
}"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('to', '<string>');
form.append('device_id', '<string>');
form.append('header_text', '<string>');
form.append('header_media_url', '<string>');
form.append('header_media', '<string>');
form.append('header_filename', '<string>');
form.append('body', '<string>');
form.append('buttons', '{
"index": 1,
"sub_type": "<string>",
"value": "<string>"
}');
form.append('header_media.0', '{
"fileName": "example-file"
}');
form.append('header_media.1', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://crm.wachat.net/api/v1/templates/{id}/send', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://crm.wachat.net/api/v1/templates/{id}/send",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://crm.wachat.net/api/v1/templates/{id}/send"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://crm.wachat.net/api/v1/templates/{id}/send")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://crm.wachat.net/api/v1/templates/{id}/send")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"wamid": "<string>",
"status": "sent",
"template_id": 123,
"template_name": "<string>",
"to": [
"<unknown>"
]
},
"meta": "<string>"
}{
"error": {
"code": "template_not_found",
"message": "Template not found in this workspace.",
"details": "<string>"
}
}{
"message": "<string>",
"errors": {}
}Send template
Sends one approved WhatsApp template to a single recipient with the variable values supplied by your application. Use this endpoint for transactional or campaign messages that must follow a Meta-approved template, including optional header media and button values.
curl --request POST \
--url https://crm.wachat.net/api/v1/templates/{id}/send \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'to=<string>' \
--form 'device_id=<string>' \
--form 'header_text=<string>' \
--form 'header_media_url=<string>' \
--form 'header_media=<string>' \
--form 'header_filename=<string>' \
--form 'body=<string>' \
--form 'buttons={
"index": 1,
"sub_type": "<string>",
"value": "<string>"
}' \
--form header_media.0='@example-file' \
--form header_media.1='@example-file'import requests
url = "https://crm.wachat.net/api/v1/templates/{id}/send"
files = {
"header_media.0": ("example-file", open("example-file", "rb")),
"header_media.1": ("example-file", open("example-file", "rb"))
}
payload = {
"to": "<string>",
"device_id": "<string>",
"header_text": "<string>",
"header_media_url": "<string>",
"header_media": "<string>",
"header_filename": "<string>",
"body": "<string>",
"buttons": "{
\"index\": 1,
\"sub_type\": \"<string>\",
\"value\": \"<string>\"
}"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('to', '<string>');
form.append('device_id', '<string>');
form.append('header_text', '<string>');
form.append('header_media_url', '<string>');
form.append('header_media', '<string>');
form.append('header_filename', '<string>');
form.append('body', '<string>');
form.append('buttons', '{
"index": 1,
"sub_type": "<string>",
"value": "<string>"
}');
form.append('header_media.0', '{
"fileName": "example-file"
}');
form.append('header_media.1', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://crm.wachat.net/api/v1/templates/{id}/send', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://crm.wachat.net/api/v1/templates/{id}/send",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://crm.wachat.net/api/v1/templates/{id}/send"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://crm.wachat.net/api/v1/templates/{id}/send")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://crm.wachat.net/api/v1/templates/{id}/send")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"to\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"device_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_text\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media_url\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_filename\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"body\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"buttons\"\r\n\r\n{\r\n \"index\": 1,\r\n \"sub_type\": \"<string>\",\r\n \"value\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.0\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"header_media.1\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"wamid": "<string>",
"status": "sent",
"template_id": 123,
"template_name": "<string>",
"to": [
"<unknown>"
]
},
"meta": "<string>"
}{
"error": {
"code": "template_not_found",
"message": "Template not found in this workspace.",
"details": "<string>"
}
}{
"message": "<string>",
"errors": {}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
Recipient phone in international format — digits or +E.164 (e.g. 919812345678). Required.
32Optional sender selector: baileys:<device_id>, waba:<config_id>, or twilio:<config_id>. Blank uses the workspace default.
64Value for a {{1}} in a TEXT header. Only for text-header templates.
1024Public https URL for an IMAGE / VIDEO / DOCUMENT header. Only for media-header templates.
2048OR attach the header file (PDF / image / video) directly in ONE multipart/form-data
request — field name header_media, up to 16 MB. We host it and use it as the header,
so you don't need a separate upload call. Takes precedence over header_media_url.
16384Display filename the recipient sees for a DOCUMENT header (e.g. "Invoice-2045.pdf"). Optional — when you attach header_media we default it to the uploaded file's own name.
255BODY variables, positional -> {{1}}, {{2}}, ... Send a list ["John","12345"] or a 1-indexed map {"1":"John","2":"12345"}. Omit if the body has no variables.
1024Dynamic button parameters, one object per variable button, e.g. [{"index":0,"sub_type":"url","value":"ORDER123"}].
Show child attributes
Show child attributes
