curl --request POST \
--url https://api.nuvia.ai/v1/messages/send-bulk-template \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'inboxId=<string>' \
--form 'templateName=<string>' \
--form languageCode=pt_BR \
--form 'components={
"index": "<string>",
"parameters": [
{
"image": {
"link": "<string>",
"id": "<string>"
},
"document": {
"link": "<string>",
"filename": "<string>"
},
"video": {
"link": "<string>"
},
"text": "<string>",
"value": "<string>",
"link": "<string>",
"imageUrl": "<string>",
"imageId": "<string>",
"documentUrl": "<string>",
"documentFilename": "<string>",
"videoUrl": "<string>",
"currencyCode": "<string>",
"currencyAmount": 123,
"dateTime": "<string>",
"payload": "<string>",
"parameter_name": "<string>",
"variable_ref": "<string>"
}
]
}' \
--form 'contacts={
"name": "<string>",
"phone": "<string>"
}' \
--form send_to_active_conversations=true \
--form 'agentToActivate=<string>' \
--form keep_existing_assignment=false \
--form 'owner_user_id=<string>' \
--form 'attendant_user_id=<string>'import requests
url = "https://api.nuvia.ai/v1/messages/send-bulk-template"
payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "multipart/form-data"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const form = new FormData();
form.append('inboxId', '<string>');
form.append('templateName', '<string>');
form.append('languageCode', 'pt_BR');
form.append('components', '{
"index": "<string>",
"parameters": [
{
"image": {
"link": "<string>",
"id": "<string>"
},
"document": {
"link": "<string>",
"filename": "<string>"
},
"video": {
"link": "<string>"
},
"text": "<string>",
"value": "<string>",
"link": "<string>",
"imageUrl": "<string>",
"imageId": "<string>",
"documentUrl": "<string>",
"documentFilename": "<string>",
"videoUrl": "<string>",
"currencyCode": "<string>",
"currencyAmount": 123,
"dateTime": "<string>",
"payload": "<string>",
"parameter_name": "<string>",
"variable_ref": "<string>"
}
]
}');
form.append('contacts', '{
"name": "<string>",
"phone": "<string>"
}');
form.append('send_to_active_conversations', 'true');
form.append('agentToActivate', '<string>');
form.append('keep_existing_assignment', 'false');
form.append('owner_user_id', '<string>');
form.append('attendant_user_id', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.nuvia.ai/v1/messages/send-bulk-template', 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://api.nuvia.ai/v1/messages/send-bulk-template",
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=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\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://api.nuvia.ai/v1/messages/send-bulk-template"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\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://api.nuvia.ai/v1/messages/send-bulk-template")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nuvia.ai/v1/messages/send-bulk-template")
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=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"totalProcessed": 123,
"sentCount": 123,
"errorCount": 123,
"errors": [
{
"row": 123,
"contact": "<string>",
"error": "<string>"
}
],
"sentContacts": [
{
"conversationId": "<string>",
"phoneNumber": "<string>"
}
]
}Enviar plantilla en masa
Envía una plantilla aprobada de WhatsApp a varios contactos en una única
solicitud (multipart/form-data).
Los contactos se envían mediante el campo contacts (JSON) o mediante un archivo CSV/XLSX en el
campo file, con las columnas name y phone — uno de los dos es obligatorio.
Los parámetros de la plantilla van en components y deben coincidir en número y tipo
con la plantilla aprobada.
El procesamiento es síncrono y parcial: la respuesta incluye totalProcessed,
sentCount, errorCount, los contactos enviados y la lista de errors por
fila. Un contacto con error no interrumpe a los demás.
Por ser plantillas, los envíos son válidos fuera de la ventana de 24 horas, pero siguen sujetos al límite diario del tier de la cuenta en WhatsApp.
curl --request POST \
--url https://api.nuvia.ai/v1/messages/send-bulk-template \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form 'inboxId=<string>' \
--form 'templateName=<string>' \
--form languageCode=pt_BR \
--form 'components={
"index": "<string>",
"parameters": [
{
"image": {
"link": "<string>",
"id": "<string>"
},
"document": {
"link": "<string>",
"filename": "<string>"
},
"video": {
"link": "<string>"
},
"text": "<string>",
"value": "<string>",
"link": "<string>",
"imageUrl": "<string>",
"imageId": "<string>",
"documentUrl": "<string>",
"documentFilename": "<string>",
"videoUrl": "<string>",
"currencyCode": "<string>",
"currencyAmount": 123,
"dateTime": "<string>",
"payload": "<string>",
"parameter_name": "<string>",
"variable_ref": "<string>"
}
]
}' \
--form 'contacts={
"name": "<string>",
"phone": "<string>"
}' \
--form send_to_active_conversations=true \
--form 'agentToActivate=<string>' \
--form keep_existing_assignment=false \
--form 'owner_user_id=<string>' \
--form 'attendant_user_id=<string>'import requests
url = "https://api.nuvia.ai/v1/messages/send-bulk-template"
payload = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "multipart/form-data"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const form = new FormData();
form.append('inboxId', '<string>');
form.append('templateName', '<string>');
form.append('languageCode', 'pt_BR');
form.append('components', '{
"index": "<string>",
"parameters": [
{
"image": {
"link": "<string>",
"id": "<string>"
},
"document": {
"link": "<string>",
"filename": "<string>"
},
"video": {
"link": "<string>"
},
"text": "<string>",
"value": "<string>",
"link": "<string>",
"imageUrl": "<string>",
"imageId": "<string>",
"documentUrl": "<string>",
"documentFilename": "<string>",
"videoUrl": "<string>",
"currencyCode": "<string>",
"currencyAmount": 123,
"dateTime": "<string>",
"payload": "<string>",
"parameter_name": "<string>",
"variable_ref": "<string>"
}
]
}');
form.append('contacts', '{
"name": "<string>",
"phone": "<string>"
}');
form.append('send_to_active_conversations', 'true');
form.append('agentToActivate', '<string>');
form.append('keep_existing_assignment', 'false');
form.append('owner_user_id', '<string>');
form.append('attendant_user_id', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.nuvia.ai/v1/messages/send-bulk-template', 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://api.nuvia.ai/v1/messages/send-bulk-template",
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=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\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://api.nuvia.ai/v1/messages/send-bulk-template"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\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://api.nuvia.ai/v1/messages/send-bulk-template")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nuvia.ai/v1/messages/send-bulk-template")
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=\"inboxId\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"templateName\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"languageCode\"\r\n\r\npt_BR\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"components\"\r\n\r\n{\r\n \"index\": \"<string>\",\r\n \"parameters\": [\r\n {\r\n \"image\": {\r\n \"link\": \"<string>\",\r\n \"id\": \"<string>\"\r\n },\r\n \"document\": {\r\n \"link\": \"<string>\",\r\n \"filename\": \"<string>\"\r\n },\r\n \"video\": {\r\n \"link\": \"<string>\"\r\n },\r\n \"text\": \"<string>\",\r\n \"value\": \"<string>\",\r\n \"link\": \"<string>\",\r\n \"imageUrl\": \"<string>\",\r\n \"imageId\": \"<string>\",\r\n \"documentUrl\": \"<string>\",\r\n \"documentFilename\": \"<string>\",\r\n \"videoUrl\": \"<string>\",\r\n \"currencyCode\": \"<string>\",\r\n \"currencyAmount\": 123,\r\n \"dateTime\": \"<string>\",\r\n \"payload\": \"<string>\",\r\n \"parameter_name\": \"<string>\",\r\n \"variable_ref\": \"<string>\"\r\n }\r\n ]\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"contacts\"\r\n\r\n{\r\n \"name\": \"<string>\",\r\n \"phone\": \"<string>\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"send_to_active_conversations\"\r\n\r\ntrue\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agentToActivate\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"keep_existing_assignment\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"owner_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"attendant_user_id\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"totalProcessed": 123,
"sentCount": 123,
"errorCount": 123,
"errors": [
{
"row": 123,
"contact": "<string>",
"error": "<string>"
}
],
"sentContacts": [
{
"conversationId": "<string>",
"phoneNumber": "<string>"
}
]
}Autorizaciones
Token JWT de autenticación
Encabezados
Identificador de la empresa objetivo. Obligatorio solo para API keys globales (type=global). Se ignora para API keys de empresa y usuarios humanos.
Cuerpo
ID del inbox/conexión de WhatsApp que se usará para enviar
1Nombre de la plantilla registrada en WhatsApp Business
1Código de idioma de la plantilla (formato: pt_BR, en_US, en, etc.)
Lista de componentes de la plantilla con sus parámetros/variables. Úsela para personalizar header, body y buttons con datos dinámicos.
Show child attributes
Show child attributes
Lista de contactos que recibirán la plantilla. Opcional si envía un archivo CSV/Excel con los contactos.
Show child attributes
Show child attributes
Define quién responde después del envío de la plantilla. Valores: AGENT (agente de IA), HUMAN (atendente humano). Ausente preserva a quien ya está atendiendo la conversación.
AGENT, HUMAN, UNASSIGNED Permite enviar la plantilla incluso cuando el contacto está en conversación activa. Por defecto el envío se omite y se registra como ACTIVE_CONVERSATION_BLOCKED.
ID del agente de IA que se activará para responder. Se usa junto con who_will_answer=AGENT
Si es true, preserva la asignación actual de la conversación: no se escribe nada en propietario/agente y el who_will_answer NO se aplica (la IA no asume). Default false para no alterar el comportamiento de integraciones existentes por API key — el front de atención envía true.
ID del usuario propietario de la conversación. null es la elección explícita de "No asignado" (autoriza a borrar el propietario actual); su ausencia significa que el caller no opinó sobre la asignación.
ID del usuario agente humano. Aplica cuando who_will_answer=HUMAN. null es "No asignado" explícito; su ausencia significa que el caller no opinó. El propietario tiene precedencia: conversation.user = owner ?? attendant.
Respuesta
Envío en masa ejecutado correctamente (devuelve estadísticas detalladas)
Total de contactos procesados
Cantidad de mensajes enviados correctamente
Cantidad de errores durante el envío
Lista detallada de errores ocurridos
Show child attributes
Show child attributes
Lista de contactos que recibieron el mensaje correctamente
Show child attributes
Show child attributes