Enviar mensagem
Enfileira o envio de uma mensagem pelo número vinculado à API key. Use exatamente um de templateId (envio por template, com variables) ou text (texto livre); e exatamente um destino: destinationNumber (E.164), groupId (…@g.us) ou newsletterId (…@newsletter). Requer key escopada a número (403 para key de tenant). Efeito real: entrega de verdade e pode custar. NOT_SUPPORTED_FOR_META para groupId/newsletterId em números Meta.
Requer uma chave com escopo de número.
curl --request POST \
--url https://pilotstatus.com.br/v1/messages/send \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"templateId": "boas_vindas",
"text": "Olá! Sua entrega chegou.",
"destinationNumber": "5511988887777",
"groupId": "123456789-987654321@g.us",
"newsletterId": "120363000000000000@newsletter",
"variables": {
"nome": "Ana"
},
"media": "https://cdn.acme.com/img.png",
"mediaType": "image",
"mediaFilename": "Nota Fiscal 123.pdf",
"caption": "Segue seu comprovante",
"buttons": [
{
"type": "reply",
"displayText": "Confirmar",
"id": "confirmar"
},
{
"type": "url",
"displayText": "Ver detalhes",
"url": "https://exemplo.com/pedido/123"
}
],
"list": {
"buttonText": "Ver áreas",
"sections": [
{
"title": "Atendimento",
"rows": [
{
"id": "clientes",
"title": "Clientes",
"description": "Consultar e cadastrar clientes"
}
]
}
]
},
"carousel": {
"cardTemplate": {
"hasBody": true,
"buttons": [
{
"type": "QUICK_REPLY"
}
]
},
"cards": [
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/a.png"
},
"body": "Tênis — 30% off",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-1"
}
]
},
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/b.png"
},
"body": "Mochila — frete grátis",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-2"
}
]
}
]
},
"header": {
"type": "text",
"content": "Título do cabeçalho"
},
"footer": "Responda SAIR para não receber mais",
"deliverAt": "2026-06-21T09:00:00Z",
"deliverUntil": "2026-06-21T18:00:00Z",
"labels": [
"pedido",
"vip"
]
}
'import requests
url = "https://pilotstatus.com.br/v1/messages/send"
payload = {
"templateId": "boas_vindas",
"text": "Olá! Sua entrega chegou.",
"destinationNumber": "5511988887777",
"groupId": "123456789-987654321@g.us",
"newsletterId": "120363000000000000@newsletter",
"variables": { "nome": "Ana" },
"media": "https://cdn.acme.com/img.png",
"mediaType": "image",
"mediaFilename": "Nota Fiscal 123.pdf",
"caption": "Segue seu comprovante",
"buttons": [
{
"type": "reply",
"displayText": "Confirmar",
"id": "confirmar"
},
{
"type": "url",
"displayText": "Ver detalhes",
"url": "https://exemplo.com/pedido/123"
}
],
"list": {
"buttonText": "Ver áreas",
"sections": [
{
"title": "Atendimento",
"rows": [
{
"id": "clientes",
"title": "Clientes",
"description": "Consultar e cadastrar clientes"
}
]
}
]
},
"carousel": {
"cardTemplate": {
"hasBody": True,
"buttons": [{ "type": "QUICK_REPLY" }]
},
"cards": [
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/a.png"
},
"body": "Tênis — 30% off",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-1"
}
]
},
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/b.png"
},
"body": "Mochila — frete grátis",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-2"
}
]
}
]
},
"header": {
"type": "text",
"content": "Título do cabeçalho"
},
"footer": "Responda SAIR para não receber mais",
"deliverAt": "2026-06-21T09:00:00Z",
"deliverUntil": "2026-06-21T18:00:00Z",
"labels": ["pedido", "vip"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
templateId: 'boas_vindas',
text: 'Olá! Sua entrega chegou.',
destinationNumber: '5511988887777',
groupId: '123456789-987654321@g.us',
newsletterId: '120363000000000000@newsletter',
variables: {nome: 'Ana'},
media: 'https://cdn.acme.com/img.png',
mediaType: 'image',
mediaFilename: 'Nota Fiscal 123.pdf',
caption: 'Segue seu comprovante',
buttons: [
{type: 'reply', displayText: 'Confirmar', id: 'confirmar'},
{
type: 'url',
displayText: 'Ver detalhes',
url: 'https://exemplo.com/pedido/123'
}
],
list: {
buttonText: 'Ver áreas',
sections: [
{
title: 'Atendimento',
rows: [
{
id: 'clientes',
title: 'Clientes',
description: 'Consultar e cadastrar clientes'
}
]
}
]
},
carousel: {
cardTemplate: {hasBody: true, buttons: [{type: 'QUICK_REPLY'}]},
cards: [
{
media: {format: 'IMAGE', url: 'https://media.example.com/a.png'},
body: JSON.stringify('Tênis — 30% off'),
buttons: [{type: 'QUICK_REPLY', text: 'Quero', payload: 'SKU-1'}]
},
{
media: {format: 'IMAGE', url: 'https://media.example.com/b.png'},
body: JSON.stringify('Mochila — frete grátis'),
buttons: [{type: 'QUICK_REPLY', text: 'Quero', payload: 'SKU-2'}]
}
]
},
header: {type: 'text', content: 'Título do cabeçalho'},
footer: 'Responda SAIR para não receber mais',
deliverAt: '2026-06-21T09:00:00Z',
deliverUntil: '2026-06-21T18:00:00Z',
labels: ['pedido', 'vip']
})
};
fetch('https://pilotstatus.com.br/v1/messages/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://pilotstatus.com.br/v1/messages/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 => json_encode([
'templateId' => 'boas_vindas',
'text' => 'Olá! Sua entrega chegou.',
'destinationNumber' => '5511988887777',
'groupId' => '123456789-987654321@g.us',
'newsletterId' => '120363000000000000@newsletter',
'variables' => [
'nome' => 'Ana'
],
'media' => 'https://cdn.acme.com/img.png',
'mediaType' => 'image',
'mediaFilename' => 'Nota Fiscal 123.pdf',
'caption' => 'Segue seu comprovante',
'buttons' => [
[
'type' => 'reply',
'displayText' => 'Confirmar',
'id' => 'confirmar'
],
[
'type' => 'url',
'displayText' => 'Ver detalhes',
'url' => 'https://exemplo.com/pedido/123'
]
],
'list' => [
'buttonText' => 'Ver áreas',
'sections' => [
[
'title' => 'Atendimento',
'rows' => [
[
'id' => 'clientes',
'title' => 'Clientes',
'description' => 'Consultar e cadastrar clientes'
]
]
]
]
],
'carousel' => [
'cardTemplate' => [
'hasBody' => true,
'buttons' => [
[
'type' => 'QUICK_REPLY'
]
]
],
'cards' => [
[
'media' => [
'format' => 'IMAGE',
'url' => 'https://media.example.com/a.png'
],
'body' => 'Tênis — 30% off',
'buttons' => [
[
'type' => 'QUICK_REPLY',
'text' => 'Quero',
'payload' => 'SKU-1'
]
]
],
[
'media' => [
'format' => 'IMAGE',
'url' => 'https://media.example.com/b.png'
],
'body' => 'Mochila — frete grátis',
'buttons' => [
[
'type' => 'QUICK_REPLY',
'text' => 'Quero',
'payload' => 'SKU-2'
]
]
]
]
],
'header' => [
'type' => 'text',
'content' => 'Título do cabeçalho'
],
'footer' => 'Responda SAIR para não receber mais',
'deliverAt' => '2026-06-21T09:00:00Z',
'deliverUntil' => '2026-06-21T18:00:00Z',
'labels' => [
'pedido',
'vip'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://pilotstatus.com.br/v1/messages/send"
payload := strings.NewReader("{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pilotstatus.com.br/v1/messages/send")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/messages/send")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "msg_01HZX...",
"correlationId": "corr_01HZX...",
"status": "QUEUED",
"createdAt": "2026-06-20T10:00:00.000Z",
"origin": "Suporte",
"sourceNumber": "5511999999999"
}{
"error": "Validation error"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Template not found"
}{
"error": "Billing suspended",
"code": "BILLING_SUSPENDED"
}{
"error": "Too many requests"
}Autorizações
Sua chave de API ps_
Corpo
Id ou nome do template (exclusivo com text).
"boas_vindas"
Texto livre (exclusivo com templateId).
"Olá! Sua entrega chegou."
Destino (exatamente um destino). Aceita telefone E.164 OU um BSUID — o userId durável do contato (ex.: BR.13491208655302741918), retornado por GET /api/v1/conversations. Use o BSUID para responder a contatos que usam username do WhatsApp (sem telefone). Templates de autenticação one-tap/zero-tap/copy-code exigem telefone.
"5511988887777"
JID de grupo. NOT_SUPPORTED_FOR_META.
"123456789-987654321@g.us"
JID de canal/newsletter. NOT_SUPPORTED_FOR_META.
"120363000000000000@newsletter"
Variáveis do template (padrão {}). Para um template criado no painel da Meta cujo botão de URL dinâmica tem um placeholder numerado (ex.: https://ctlnk.io/{{1}}, que não é o {{1}} do body), passe o sufixo da URL desse botão como button_<N>, em que N é a posição do botão entre todos os botões do template, começando em 1. Num número oficial (Meta), a mesma chave também leva o código de um botão de copiar código cujo valor não tem {{variável}} (o código definido na criação é só a amostra da Meta), ex.: button_2 para os botões [QUICK_REPLY, COPY_CODE]; um envio sem ela é recusado com 400 MISSING_TEMPLATE_VARIABLES.
Show child attributes
Show child attributes
{ "nome": "Ana" }
URL pública http(s) OU data URI base64 (ex.: data:audio/ogg;base64,AAAA…). Base64 é aceito em números Meta Cloud API e em números não oficiais (Pilot Status web); em números não oficiais a Pilot Status sobe o arquivo decodificado para o próprio armazenamento e envia uma URL ao provedor, e se esse upload falhar a mensagem falha com MEDIA_REHOST_FAILED. Para figurinhas em números não oficiais, use uma URL http(s) pública. Usado no modo template ou no modo mídia direta (media + mediaType, sem templateId e sem text). O base64 tem teto pelo tamanho decodificado: 50 MiB (52428800 bytes) quando mediaType é document, 16 MiB (16777216 bytes) nos demais tipos e quando mediaType é omitido; acima disso a requisição falha com 400 Validation error (details.fieldErrors.media). Envie arquivos maiores como URL http(s) pública. Uma URL (ou um redirecionamento que ela responda) que aponte para um endereço interno ou de rede privada nunca é baixada: a mensagem falha depois do 202 com MEDIA_DOWNLOAD_FAILED, em qualquer tipo de número.
"https://cdn.acme.com/img.png"
Tipo da mídia. No modo mídia direta (sem templateId/text) envie media + mediaType: caption opcional para image/video/document (não para audio/voice); botões/header/footer/variáveis não permitidos. "voice" entrega uma nota de voz (PTT) do WhatsApp em qualquer número. "audio" entrega um arquivo de áudio (não uma nota de voz) em números oficiais (Meta Cloud API) e uma nota de voz em números não oficiais (Evolution v2 e GO) — envie "voice" para uma nota de voz. Antes do envio, o áudio é convertido para AAC em MP4 (audio/mp4) em números oficiais e para Ogg/Opus em números não oficiais. Na Evolution v2 e GO um indicador "gravando áudio" é mostrado antes de um envio audio ou voice; na Meta Cloud API aparece um indicador "digitando" no lugar, quando a conversa tem uma mensagem recente do contato. "sticker" envia uma figurinha do WhatsApp: só no modo mídia direta (nunca com templateId), sem caption, e o arquivo precisa ser image/webp com exatamente 512x512 pixels — estática até 100 KB, animada até 500 KB. Qualquer outra dimensão é recusada pelo WhatsApp (erro 131053 da Meta, META_MEDIA_UPLOAD_ERROR) depois que esta API já respondeu 202. Na Meta Cloud API a figurinha é enviada como type "sticker"; na Evolution v2 e GO ela sai pela rota de sticker dedicada de cada servidor.
image, video, document, audio, voice, sticker "image"
Nome com que o documento chega no WhatsApp. Apenas envios diretos de documento (exige mediaType: document). Sem ele, o nome vem do final da URL. Separadores de caminho são removidos. Retorna 400 se enviado sem media, em um envio de template, ou com mediaType diferente de document.
"Nota Fiscal 123.pdf"
Legenda que acompanha um envio direto de mídia. Vale para image, video e document; recusada com 400 para audio e sticker. Também não é suportada em voice: não é recusada, mas é descartada em números não oficiais e sua exibição em números oficiais não é garantida — não envie legenda. Máximo de 1024 caracteres. Não é usada no modo template — lá o texto vem do corpo do template.
"Segue seu comprovante"
Até 3 botões interativos. Cada item tem type + displayText mais um campo específico do tipo.
reply— botão de resposta rápida; funciona em texto livre e em template. Definaid(valor seu; não volta no toque — case as respostas por rótulo +quotedMessageId).url— abre um link; definaurl(https). Em texto livre, no máximo um botão URL por mensagem, e ele pode ser combinado com botõesreply.call— liga para um número; definaphoneNumber(E.164, ex.:+5511999999999). Somente em templates — em texto livre retorna 400 (BUTTON_PHONE_NUMBER_TEMPLATE_ONLY).copy— copia um código; definacopyCode. Somente em templates — em texto livre retorna 400 (BUTTON_COPY_CODE_TEMPLATE_ONLY).
Em um template, os botões substituem os botões do próprio template — exceto em números Meta (oficiais), em que os botões do template aprovado são fixos: buttons não os substitui e não preenche variável de botão. Preencha um botão de URL dinâmica por variables (a chave nomeada, ou button_<N> para placeholder numerado em template criado no painel da Meta); o código de um botão de copiar código também vai em variables como button_<N>, não em copyCode.
Show child attributes
Show child attributes
[ { "type": "reply", "displayText": "Confirmar", "id": "confirmar" }, { "type": "url", "displayText": "Ver detalhes", "url": "https://exemplo.com/pedido/123" } ]
Lista interativa de seleção única — um botão que abre um menu de até 10 linhas. Requer text (o corpo da mensagem acima do botão); exclusiva com templateId, buttons e mídia direta. Funciona em ambos os tipos de número com a mesma requisição: números Meta Cloud API enviam a lista interativa oficial, números não oficiais (Pilot Status web) enviam a lista nativa. A seleção do destinatário chega como mensagem/webhook de entrada normal.
Show child attributes
Show child attributes
{ "buttonText": "Ver áreas", "sections": [ { "title": "Atendimento", "rows": [ { "id": "clientes", "title": "Clientes", "description": "Consultar e cadastrar clientes" } ] } ] }
Carrossel de sessão — uma tira horizontal e arrastável de 2–10 cards anexada a um envio livre. Requer text (o corpo da mensagem acima dos cards); exclusivo com templateId, list, buttons e mídia direta, e não aceita header (a mídia fica em cada card). Funciona nos dois tipos de número: números Meta Cloud API só enviam dentro da janela de atendimento de 24h (fora dela, use um template de carrossel aprovado); números não oficiais (Pilot Status web) enviam no avulso. Botões do carrossel de sessão são só QUICK_REPLY na Meta (um botão URL ali exige um template de carrossel aprovado); em números não oficiais um botão URL também funciona no avulso. O toque num botão de resposta rápida chega como um webhook de entrada normal.
Show child attributes
Show child attributes
{ "cardTemplate": { "hasBody": true, "buttons": [{ "type": "QUICK_REPLY" }] }, "cards": [ { "media": { "format": "IMAGE", "url": "https://media.example.com/a.png" }, "body": "Tênis — 30% off", "buttons": [ { "type": "QUICK_REPLY", "text": "Quero", "payload": "SKU-1" } ] }, { "media": { "format": "IMAGE", "url": "https://media.example.com/b.png" }, "body": "Mochila — frete grátis", "buttons": [ { "type": "QUICK_REPLY", "text": "Quero", "payload": "SKU-2" } ] } ] }
Flow dinâmico — um botão que abre um WhatsApp Flow escolhido NO MOMENTO DO ENVIO, em vez de ficar preso a um template aprovado. Apenas números Meta Cloud API (os provedores não oficiais não têm Flows), exige text e exige a janela de 24h aberta: fora dela a Meta responde 200 com um wamid e descarta a mensagem em silêncio, por isso o Pilot Status recusa com FLOW_WINDOW_CLOSED em vez de deixá-la sumir. Mutuamente exclusivo com templateId, list, carousel, buttons, header e envio direto de mídia. O flow_token é gerado por mensagem pelo Pilot Status e não pode ser informado.
Show child attributes
Show child attributes
Cabeçalho de uma mensagem interativa de texto livre. Requer buttons. type é text (até 60 chars em content) ou image / video / document (URL pública em content).
Show child attributes
Show child attributes
{ "type": "text", "content": "Título do cabeçalho" }
Rodapé da mensagem (máx. 60 caracteres). Requer buttons.
"Responda SAIR para não receber mais"
Agendar a entrega para um instante futuro.
"2026-06-21T09:00:00Z"
Janela máxima de entrega.
"2026-06-21T18:00:00Z"
Labels a aplicar à conversa de destino.
["pedido", "vip"]
Resposta
Enviar template
Esta página foi útil?
curl --request POST \
--url https://pilotstatus.com.br/v1/messages/send \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"templateId": "boas_vindas",
"text": "Olá! Sua entrega chegou.",
"destinationNumber": "5511988887777",
"groupId": "123456789-987654321@g.us",
"newsletterId": "120363000000000000@newsletter",
"variables": {
"nome": "Ana"
},
"media": "https://cdn.acme.com/img.png",
"mediaType": "image",
"mediaFilename": "Nota Fiscal 123.pdf",
"caption": "Segue seu comprovante",
"buttons": [
{
"type": "reply",
"displayText": "Confirmar",
"id": "confirmar"
},
{
"type": "url",
"displayText": "Ver detalhes",
"url": "https://exemplo.com/pedido/123"
}
],
"list": {
"buttonText": "Ver áreas",
"sections": [
{
"title": "Atendimento",
"rows": [
{
"id": "clientes",
"title": "Clientes",
"description": "Consultar e cadastrar clientes"
}
]
}
]
},
"carousel": {
"cardTemplate": {
"hasBody": true,
"buttons": [
{
"type": "QUICK_REPLY"
}
]
},
"cards": [
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/a.png"
},
"body": "Tênis — 30% off",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-1"
}
]
},
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/b.png"
},
"body": "Mochila — frete grátis",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-2"
}
]
}
]
},
"header": {
"type": "text",
"content": "Título do cabeçalho"
},
"footer": "Responda SAIR para não receber mais",
"deliverAt": "2026-06-21T09:00:00Z",
"deliverUntil": "2026-06-21T18:00:00Z",
"labels": [
"pedido",
"vip"
]
}
'import requests
url = "https://pilotstatus.com.br/v1/messages/send"
payload = {
"templateId": "boas_vindas",
"text": "Olá! Sua entrega chegou.",
"destinationNumber": "5511988887777",
"groupId": "123456789-987654321@g.us",
"newsletterId": "120363000000000000@newsletter",
"variables": { "nome": "Ana" },
"media": "https://cdn.acme.com/img.png",
"mediaType": "image",
"mediaFilename": "Nota Fiscal 123.pdf",
"caption": "Segue seu comprovante",
"buttons": [
{
"type": "reply",
"displayText": "Confirmar",
"id": "confirmar"
},
{
"type": "url",
"displayText": "Ver detalhes",
"url": "https://exemplo.com/pedido/123"
}
],
"list": {
"buttonText": "Ver áreas",
"sections": [
{
"title": "Atendimento",
"rows": [
{
"id": "clientes",
"title": "Clientes",
"description": "Consultar e cadastrar clientes"
}
]
}
]
},
"carousel": {
"cardTemplate": {
"hasBody": True,
"buttons": [{ "type": "QUICK_REPLY" }]
},
"cards": [
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/a.png"
},
"body": "Tênis — 30% off",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-1"
}
]
},
{
"media": {
"format": "IMAGE",
"url": "https://media.example.com/b.png"
},
"body": "Mochila — frete grátis",
"buttons": [
{
"type": "QUICK_REPLY",
"text": "Quero",
"payload": "SKU-2"
}
]
}
]
},
"header": {
"type": "text",
"content": "Título do cabeçalho"
},
"footer": "Responda SAIR para não receber mais",
"deliverAt": "2026-06-21T09:00:00Z",
"deliverUntil": "2026-06-21T18:00:00Z",
"labels": ["pedido", "vip"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
templateId: 'boas_vindas',
text: 'Olá! Sua entrega chegou.',
destinationNumber: '5511988887777',
groupId: '123456789-987654321@g.us',
newsletterId: '120363000000000000@newsletter',
variables: {nome: 'Ana'},
media: 'https://cdn.acme.com/img.png',
mediaType: 'image',
mediaFilename: 'Nota Fiscal 123.pdf',
caption: 'Segue seu comprovante',
buttons: [
{type: 'reply', displayText: 'Confirmar', id: 'confirmar'},
{
type: 'url',
displayText: 'Ver detalhes',
url: 'https://exemplo.com/pedido/123'
}
],
list: {
buttonText: 'Ver áreas',
sections: [
{
title: 'Atendimento',
rows: [
{
id: 'clientes',
title: 'Clientes',
description: 'Consultar e cadastrar clientes'
}
]
}
]
},
carousel: {
cardTemplate: {hasBody: true, buttons: [{type: 'QUICK_REPLY'}]},
cards: [
{
media: {format: 'IMAGE', url: 'https://media.example.com/a.png'},
body: JSON.stringify('Tênis — 30% off'),
buttons: [{type: 'QUICK_REPLY', text: 'Quero', payload: 'SKU-1'}]
},
{
media: {format: 'IMAGE', url: 'https://media.example.com/b.png'},
body: JSON.stringify('Mochila — frete grátis'),
buttons: [{type: 'QUICK_REPLY', text: 'Quero', payload: 'SKU-2'}]
}
]
},
header: {type: 'text', content: 'Título do cabeçalho'},
footer: 'Responda SAIR para não receber mais',
deliverAt: '2026-06-21T09:00:00Z',
deliverUntil: '2026-06-21T18:00:00Z',
labels: ['pedido', 'vip']
})
};
fetch('https://pilotstatus.com.br/v1/messages/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://pilotstatus.com.br/v1/messages/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 => json_encode([
'templateId' => 'boas_vindas',
'text' => 'Olá! Sua entrega chegou.',
'destinationNumber' => '5511988887777',
'groupId' => '123456789-987654321@g.us',
'newsletterId' => '120363000000000000@newsletter',
'variables' => [
'nome' => 'Ana'
],
'media' => 'https://cdn.acme.com/img.png',
'mediaType' => 'image',
'mediaFilename' => 'Nota Fiscal 123.pdf',
'caption' => 'Segue seu comprovante',
'buttons' => [
[
'type' => 'reply',
'displayText' => 'Confirmar',
'id' => 'confirmar'
],
[
'type' => 'url',
'displayText' => 'Ver detalhes',
'url' => 'https://exemplo.com/pedido/123'
]
],
'list' => [
'buttonText' => 'Ver áreas',
'sections' => [
[
'title' => 'Atendimento',
'rows' => [
[
'id' => 'clientes',
'title' => 'Clientes',
'description' => 'Consultar e cadastrar clientes'
]
]
]
]
],
'carousel' => [
'cardTemplate' => [
'hasBody' => true,
'buttons' => [
[
'type' => 'QUICK_REPLY'
]
]
],
'cards' => [
[
'media' => [
'format' => 'IMAGE',
'url' => 'https://media.example.com/a.png'
],
'body' => 'Tênis — 30% off',
'buttons' => [
[
'type' => 'QUICK_REPLY',
'text' => 'Quero',
'payload' => 'SKU-1'
]
]
],
[
'media' => [
'format' => 'IMAGE',
'url' => 'https://media.example.com/b.png'
],
'body' => 'Mochila — frete grátis',
'buttons' => [
[
'type' => 'QUICK_REPLY',
'text' => 'Quero',
'payload' => 'SKU-2'
]
]
]
]
],
'header' => [
'type' => 'text',
'content' => 'Título do cabeçalho'
],
'footer' => 'Responda SAIR para não receber mais',
'deliverAt' => '2026-06-21T09:00:00Z',
'deliverUntil' => '2026-06-21T18:00:00Z',
'labels' => [
'pedido',
'vip'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://pilotstatus.com.br/v1/messages/send"
payload := strings.NewReader("{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pilotstatus.com.br/v1/messages/send")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pilotstatus.com.br/v1/messages/send")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"templateId\": \"boas_vindas\",\n \"text\": \"Olá! Sua entrega chegou.\",\n \"destinationNumber\": \"5511988887777\",\n \"groupId\": \"123456789-987654321@g.us\",\n \"newsletterId\": \"120363000000000000@newsletter\",\n \"variables\": {\n \"nome\": \"Ana\"\n },\n \"media\": \"https://cdn.acme.com/img.png\",\n \"mediaType\": \"image\",\n \"mediaFilename\": \"Nota Fiscal 123.pdf\",\n \"caption\": \"Segue seu comprovante\",\n \"buttons\": [\n {\n \"type\": \"reply\",\n \"displayText\": \"Confirmar\",\n \"id\": \"confirmar\"\n },\n {\n \"type\": \"url\",\n \"displayText\": \"Ver detalhes\",\n \"url\": \"https://exemplo.com/pedido/123\"\n }\n ],\n \"list\": {\n \"buttonText\": \"Ver áreas\",\n \"sections\": [\n {\n \"title\": \"Atendimento\",\n \"rows\": [\n {\n \"id\": \"clientes\",\n \"title\": \"Clientes\",\n \"description\": \"Consultar e cadastrar clientes\"\n }\n ]\n }\n ]\n },\n \"carousel\": {\n \"cardTemplate\": {\n \"hasBody\": true,\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\"\n }\n ]\n },\n \"cards\": [\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/a.png\"\n },\n \"body\": \"Tênis — 30% off\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-1\"\n }\n ]\n },\n {\n \"media\": {\n \"format\": \"IMAGE\",\n \"url\": \"https://media.example.com/b.png\"\n },\n \"body\": \"Mochila — frete grátis\",\n \"buttons\": [\n {\n \"type\": \"QUICK_REPLY\",\n \"text\": \"Quero\",\n \"payload\": \"SKU-2\"\n }\n ]\n }\n ]\n },\n \"header\": {\n \"type\": \"text\",\n \"content\": \"Título do cabeçalho\"\n },\n \"footer\": \"Responda SAIR para não receber mais\",\n \"deliverAt\": \"2026-06-21T09:00:00Z\",\n \"deliverUntil\": \"2026-06-21T18:00:00Z\",\n \"labels\": [\n \"pedido\",\n \"vip\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "msg_01HZX...",
"correlationId": "corr_01HZX...",
"status": "QUEUED",
"createdAt": "2026-06-20T10:00:00.000Z",
"origin": "Suporte",
"sourceNumber": "5511999999999"
}{
"error": "Validation error"
}{
"error": "Unauthorized"
}{
"error": "Tenant-scoped keys cannot call number endpoints",
"code": "TENANT_SCOPE_NOT_ALLOWED"
}{
"error": "Template not found"
}{
"error": "Billing suspended",
"code": "BILLING_SUSPENDED"
}{
"error": "Too many requests"
}