Envio de mensagens
Envie mensagens pelo Turbo Notify e siga as políticas do WhatsApp (abre em nova aba) .
O corpo de POST /v1/numbers/{ref}/messages (ou o atalho
POST /v1/messages para o número principal) leva o conteúdo da mensagem
no objeto content. O tipo vem do campo
âncora presente em content (text, image_url, latitude,
start_at, …). Não envie um campo content_type na requisição: ele
nunca é aceito (incluí-lo retorna 422).
Suporta texto, localização, contato, calendário, mensagem com botão de
link (interactive_type) e mídia (image, video, audio, document, sticker, veja
Envio de mídia).
Para citar (responder) uma mensagem existente (qualquer variante de conteúdo), use o endpoint dedicado POST /v1/messages/{message_id}/reply, onde {message_id} é o id público da mensagem citada (msg_{hex32}). O corpo dessa requisição contém apenas content. O webhook resultante é message.replied (em vez de message.sent); veja Webhooks.
Use a citação para trazer ao contexto uma mensagem anterior, quando a conversa já andou e a sua resposta depende dela (do contato, sua ou, em grupo, de qualquer participante). Para responder à mensagem que acabou de chegar, envie uma mensagem normal, como se faz numa conversa: o chat já mostra o que veio antes, e uma citação em toda resposta só polui.
Dá para responder a qualquer mensagem dos últimos 12 meses, inclusive uma cujo conteúdo já expirou (Retenção das mensagens): a conversa continua encadeada pela mensagem citada, só que o balão de citação vai sem o texto original.
Antes de enviar (ou de responder), o Turbo Notify abre a conversa como uma pessoa faria: o número aparece online, o histórico de mensagens não lidas do chat de destino é marcado como lido e só então a mensagem é enviada. Para marcar um chat como lido sem enviar nenhuma mensagem, veja Marcar como lida.
Envio básico
O envio básico leva só o número do destinatário e o texto. O remetente é o número principal da sua conta.
curl -X POST \ https://api.turbonotify.com/v1/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "to": {"number": "+5511988887777"}, "content": { "text": "Olá, esta é uma mensagem enviada pelo Turbo Notify!" } }'const response = await fetch('https://api.turbonotify.com/v1/messages', { method: 'POST', headers: { 'Authorization': 'Bearer SUA_CHAVE', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: { number: '+5511988887777' }, content: { text: 'Olá, esta é uma mensagem enviada pelo Turbo Notify!' } })});
const result = await response.json();console.log(result);import requests
url = "https://api.turbonotify.com/v1/messages"headers = { "Authorization": "Bearer SUA_CHAVE", "Content-Type": "application/json"}data = { "to": {"number": "+5511988887777"}, "content": { "text": "Olá, esta é uma mensagem enviada pelo Turbo Notify!" }}
response = requests.post(url, json=data, headers=headers)result = response.json()print(result)package main
import ( "fmt" "io" "net/http" "strings")
func main() { payload := strings.NewReader(`{"to": {"number": "+5511988887777"}, "content": {"text": "Olá, esta é uma mensagem enviada pelo Turbo Notify!"}}`) req, _ := http.NewRequest("POST", "https://api.turbonotify.com/v1/messages", payload) req.Header.Set("Authorization", "Bearer SUA_CHAVE") req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Println(string(body))}<?php$url = 'https://api.turbonotify.com/v1/messages';$data = [ 'to' => ['number' => '+5511988887777'], 'content' => [ 'text' => 'Olá, esta é uma mensagem enviada pelo Turbo Notify!' ]];
$options = [ 'http' => [ 'header' => [ 'Authorization: Bearer SUA_CHAVE', 'Content-Type: application/json' ], 'method' => 'POST', 'content' => json_encode($data) ]];
$context = stream_context_create($options);$result = file_get_contents($url, false, $context);$response = json_decode($result, true);var_dump($response);?>using System.Text;using System.Text.Json;
var client = new HttpClient();client.DefaultRequestHeaders.Add("Authorization", "Bearer SUA_CHAVE");
var data = new { to = new { number = "+5511988887777" }, content = new { text = "Olá, esta é uma mensagem enviada pelo Turbo Notify!" }};
var json = JsonSerializer.Serialize(data);var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync( "https://api.turbonotify.com/v1/messages", content);var result = await response.Content.ReadAsStringAsync();Console.WriteLine(result);import java.net.http.*;import java.net.URI;
public class TurboNotify { public static void main(String[] args) throws Exception { var client = HttpClient.newHttpClient();
var json = """ { "to": {"number": "+5511988887777"}, "content": { "text": "Olá, esta é uma mensagem enviada pelo Turbo Notify!" } } """;
var request = HttpRequest.newBuilder() .uri(URI.create("https://api.turbonotify.com/v1/messages")) .header("Authorization", "Bearer SUA_CHAVE") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(json)) .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); }}Depois do envio, o texto pode ser corrigido com Editar mensagem.
Menções (@mentions)
Para mencionar alguém, escreva o token @<numero> no text (ou no
caption de mídia, veja Envio de mídia): @ seguido
do telefone do contato em dígitos E.164, sem +. É uma menção real do
WhatsApp, com nome tocável e notificação no aparelho de quem foi mencionado.
{ "to": { "number": "+5511988887777" }, "content": { "text": "Olá @5511977776666, seu pedido chegou!" }}Em grupos, mencione um participante pelo número:
{ "to": { "group_id": "grp_e442553a56b14e2695f6acfd7d651b1a" }, "content": { "text": "Bom dia @5511977776666, pode validar o pedido de hoje?" }}A requisição não tem campo mentions: o Turbo Notify detecta as menções no
próprio texto. Todo token válido vira uma menção real no dispositivo do
destinatário.
Regras do token
| Regra | Comportamento |
|---|---|
| Sintaxe | @ + 7 a 15 dígitos, delimitado por fronteira de palavra: nome@dominio.com, @@123, sequências com mais de 15 dígitos e @+55… não viram menção |
| Normalização | Números BR de 12 dígitos são normalizados para a forma de 13 dígitos: o conteúdo guardado e devolvido traz o token normalizado (ex.: @551177776666 → @5511977776666) |
| Token inválido | Dígitos inválidos ou não normalizáveis ficam como texto comum: o envio nunca falha por causa de uma menção |
| Onde funciona | Em 1:1 e em grupos, em text e em caption de image/video/document (audio/sticker não têm legenda) |
| Reuso do token recebido | O token @<numero> que você recebe em message.received pode ser colado de volta no envio: a menção funciona sem nenhuma conversão |
| Cota | Mencionar alguém nunca consome cota de mensagens nem de contatos |
Depois do envio, a mensagem passa a carregar a estrutura mentions
(lista de {contact_id?, name?, number}: contact_id e name são omitidos
quando a menção não corresponde a um contato conhecido) em
GET /v1/messages/{message_id} e no data.mentions dos
eventos message.sent/message.replied/message.edited.
Um @<digitos> literal no texto só é menção se constar dessa estrutura.
As mesmas regras de detecção valem para POST .../messages/{message_id}/reply
(o text/caption da resposta) e para POST .../messages/{message_id}/edit (o
novo text ou caption da edição substitui todo o conjunto de menções da mensagem,
veja Editar e apagar mensagens).
Envio com número extra
Para enviar a partir de um número extra cadastrado e ativo na sua conta, use o alias do número diretamente no caminho da URL.
curl -X POST \ https://api.turbonotify.com/v1/numbers/vendas-sp/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "to": {"number": "+5511988887777"}, "content": { "text": "Mensagem enviada a partir de um número extra." } }'const response = await fetch('https://api.turbonotify.com/v1/numbers/vendas-sp/messages', { method: 'POST', headers: { 'Authorization': 'Bearer SUA_CHAVE', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: { number: '+5511988887777' }, content: { text: 'Mensagem enviada a partir de um número extra.' } })});
const result = await response.json();console.log(result);import requests
url = "https://api.turbonotify.com/v1/numbers/vendas-sp/messages"headers = { "Authorization": "Bearer SUA_CHAVE", "Content-Type": "application/json"}data = { "to": {"number": "+5511988887777"}, "content": { "text": "Mensagem enviada a partir de um número extra." }}
response = requests.post(url, json=data, headers=headers)result = response.json()print(result)package main
import ( "fmt" "io" "net/http" "strings")
func main() { payload := strings.NewReader(`{"to": {"number": "+5511988887777"}, "content": {"text": "Mensagem enviada a partir de um número extra."}}`) req, _ := http.NewRequest("POST", "https://api.turbonotify.com/v1/numbers/vendas-sp/messages", payload) req.Header.Set("Authorization", "Bearer SUA_CHAVE") req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Println(string(body))}<?php$url = 'https://api.turbonotify.com/v1/numbers/vendas-sp/messages';$data = [ 'to' => ['number' => '+5511988887777'], 'content' => [ 'text' => 'Mensagem enviada a partir de um número extra.' ]];
$options = [ 'http' => [ 'header' => [ 'Authorization: Bearer SUA_CHAVE', 'Content-Type: application/json' ], 'method' => 'POST', 'content' => json_encode($data) ]];
$context = stream_context_create($options);$result = file_get_contents($url, false, $context);$response = json_decode($result, true);var_dump($response);?>using System.Text;using System.Text.Json;
var client = new HttpClient();client.DefaultRequestHeaders.Add("Authorization", "Bearer SUA_CHAVE");
var data = new { to = new { number = "+5511988887777" }, content = new { text = "Mensagem enviada a partir de um número extra." }};
var json = JsonSerializer.Serialize(data);var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync( "https://api.turbonotify.com/v1/numbers/vendas-sp/messages", content);var result = await response.Content.ReadAsStringAsync();Console.WriteLine(result);import java.net.http.*;import java.net.URI;
public class TurboNotify { public static void main(String[] args) throws Exception { var client = HttpClient.newHttpClient();
var json = """ { "to": {"number": "+5511988887777"}, "content": { "text": "Mensagem enviada a partir de um número extra." } } """;
var request = HttpRequest.newBuilder() .uri(URI.create("https://api.turbonotify.com/v1/numbers/vendas-sp/messages")) .header("Authorization", "Bearer SUA_CHAVE") .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(json)) .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); }}Se o alias da URL não for de um número extra cadastrado e ativo, o envio é rejeitado.
Saiba mais em Inclusão de números extras.
Envio sem duplicar
O envio (POST .../messages) e a resposta (POST .../messages/{message_id}/reply) aceitam o cabeçalho opcional Idempotency-Key: um texto de até 255 caracteres escolhido por você. Se a requisição falhar por tempo esgotado ou erro de rede e você repetir com a mesma chave, no mesmo número, a mensagem não é enviada de novo: a resposta traz o message_id da mensagem original. Sem a chave, repetir pode entregar a mensagem em dobro.
Use uma chave nova para cada mensagem nova, derivada de algo estável do seu lado (por exemplo o id do pedido que gerou a notificação). Uma chave vazia ou com mais de 255 caracteres é recusada com 400 invalid_idempotency_key.
curl -X POST https://api.turbonotify.com/v1/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: pedido-4711-confirmacao" \ -d '{"to": {"number": "+5511988887777"}, "content": {"text": "Seu pedido foi confirmado."}}'Erros possíveis
| Status | Código de erro | Descrição |
|---|---|---|
400 | contact_not_found | O contact_id informado não pertence à organização. |
400 | contacts_not_enabled | Envio por contact_id não configurado. |
400 | invalid_phone_number | O to.number informado não é um telefone válido em formato E.164 (ex.: +5511988887777). |
400 | invalid_recipient | Não foi possível resolver o destinatário informado em to para um endereço de envio. Informar nenhum ou mais de um entre number, group_id e contact_id retorna 422 validation_error. |
400 | not_group_member | Seu número não é mais participante do group_id informado, veja Envio para grupo. |
402 | feature_not_available | Envio para grupo (to.group_id) requer plano Empresarial ou superior, veja Envio para grupo. |
402 | subscription_inactive | Assinatura com pagamento pendente, encerrada ou com período de teste expirado (details.status). Bloqueia todo envio até a assinatura voltar a ficar ativa. |
402 | contact_quota_exceeded | Cota de contatos distintos do ciclo atual esgotada, veja Cota e uso. |
401 | not_authenticated | A chave de API está inválida ou ausente. |
403 | insufficient_scope | A chave de API não possui o escopo messages:send (resposta inclui required_scope). |
404 | number_not_found | O alias ou o id informado na URL não corresponde a nenhum número cadastrado na conta. |
400 | invalid_number_id | O valor na URL começa com num_, mas não é um id de número válido. |
404 | group_not_found | O group_id informado em to não foi encontrado na conta. |
409 | number_not_connected | O número que envia não está conectado ao WhatsApp. Reconecte o número e tente de novo. |
422 | validation_error | O corpo da requisição está malformado ou não passou na validação. A resposta traz details.errors com os campos rejeitados. |
422 | group_not_owned_by_number | O group_id informado pertence a outro número da conta, não ao alias do caminho da URL. |
422 | message_not_replyable | (apenas POST .../messages/{message_id}/reply) A mensagem citada ainda não foi enviada ao WhatsApp ou já foi apagada. |
429 | messages_quota_exceeded | Cota de mensagens do ciclo atual esgotada, veja Cota e uso. |
429 | send_rate_spacing | Envio antes do intervalo mínimo entre mensagens do seu plano, veja Limites de velocidade. |
429 | rate_limit_exceeded | Limite de requisições por segundo da API ultrapassado. Os demais limites de proteção do envio (messages_per_minute_limit_exceeded, recipients_per_day_limit_exceeded, warmup_limit_exceeded, duplicate_burst_blocked, reply_ratio_too_low) têm códigos próprios, veja Limites de velocidade. |
500 | internal_error | Erro interno inesperado no servidor. |
Status da mensagem
O status mostra em que etapa a mensagem está. Cada valor é explicado em Status.
{
"message_id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f70",
"status": {
"state": "pending",
"at": "2025-07-16T10:00:00Z",
"error": null
}
} O retorno final do processamento chega via webhook com os eventos message.sent, message.delivered, message.read ou message.send.failed.
Segurança e privacidade
Toda comunicação entre o seu sistema e a API do Turbo Notify usa HTTPS, então os dados trafegam criptografados.
O tempo que o conteúdo das mensagens fica guardado (as mensagens em si ficam disponíveis por 12 meses) está em Retenção das mensagens.
Conteúdo rico: localização, contato, calendário e botão com link
POST /v1/messages aceita quatro variantes de
conteúdo rico além de text. Cada variante tem um campo âncora próprio
dentro do objeto content e chega ao WhatsApp como o tipo nativo
correspondente (locationMessage, contactMessage, eventMessage).
Enviar localização
curl -X POST \ https://api.turbonotify.com/v1/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "to": {"number": "+5511988887777"}, "content": { "latitude": -23.5505, "longitude": -46.6333, "name": "Avenida Paulista", "address": "São Paulo, SP", "url": "https://maps.google.com/?q=-23.5505,-46.6333" } }'await fetch('https://api.turbonotify.com/v1/messages', { method: 'POST', headers: { 'Authorization': 'Bearer SUA_CHAVE', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: { number: '+5511988887777' }, content: { latitude: -23.5505, longitude: -46.6333, name: 'Avenida Paulista', address: 'São Paulo, SP', url: 'https://maps.google.com/?q=-23.5505,-46.6333' } })});import requests
requests.post( "https://api.turbonotify.com/v1/messages", headers={ "Authorization": "Bearer SUA_CHAVE", "Content-Type": "application/json", }, json={ "to": {"number": "+5511988887777"}, "content": { "latitude": -23.5505, "longitude": -46.6333, "name": "Avenida Paulista", "address": "São Paulo, SP", "url": "https://maps.google.com/?q=-23.5505,-46.6333", }, },)| Campo | Tipo | Obrigatório | Validação |
|---|---|---|---|
content.latitude | number | sim | -90 ≤ x ≤ 90 |
content.longitude | number | sim | -180 ≤ x ≤ 180 |
content.name | string | não | até 200 caracteres |
content.address | string | não | até 500 caracteres |
content.url | string | não | apenas http:///https:// |
Uma localização enviada não pode ser editada: apagar é a única alteração. Veja o que pode ser alterado depois do envio.
Enviar contato
curl -X POST \ https://api.turbonotify.com/v1/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "to": {"number": "+5511988887777"}, "content": { "display_name": "João Silva", "phones": [ { "label": "Mobile", "number": "+5511977776666" }, { "label": "Work", "number": "+551133334444" } ], "emails": [ { "label": "Work", "address": "joao@acme.com" } ], "organization": "Acme Corp", "title": "CTO", "address": "Av. Paulista 1578, São Paulo - SP" } }'await fetch('https://api.turbonotify.com/v1/messages', { method: 'POST', headers: { 'Authorization': 'Bearer SUA_CHAVE', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: { number: '+5511988887777' }, content: { display_name: 'João Silva', phones: [ { label: 'Mobile', number: '+5511977776666' }, { label: 'Work', number: '+551133334444' } ], emails: [ { label: 'Work', address: 'joao@acme.com' } ], organization: 'Acme Corp', title: 'CTO', address: 'Av. Paulista 1578, São Paulo - SP' } })});import requests
requests.post( "https://api.turbonotify.com/v1/messages", headers={ "Authorization": "Bearer SUA_CHAVE", "Content-Type": "application/json", }, json={ "to": {"number": "+5511988887777"}, "content": { "display_name": "João Silva", "phones": [ {"label": "Mobile", "number": "+5511977776666"}, {"label": "Work", "number": "+551133334444"}, ], "emails": [ {"label": "Work", "address": "joao@acme.com"}, ], "organization": "Acme Corp", "title": "CTO", "address": "Av. Paulista 1578, São Paulo - SP", }, },)| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
content.display_name | string | sim | 1 a 200 caracteres |
content.phones[] | array | sim | 1 a 10 itens; number em E.164 |
content.phones[].label | string | não | padrão "Mobile" (Mobile/Home/Work/…) |
content.emails[] | array | não | 0 a 10 itens; address validado como e-mail |
content.emails[].label | string | não | padrão "Email" |
content.organization | string | não | até 200 caracteres |
content.title | string | não | até 100 caracteres |
content.address | string | não | até 500 caracteres |
O Turbo Notify monta o cartão de contato (vCard) a partir desses campos. Um cartão enviado não pode ser editado: apagar é a única alteração. Veja o que pode ser alterado depois do envio.
Enviar evento de calendário
curl -X POST \ https://api.turbonotify.com/v1/messages \ -H "Authorization: Bearer SUA_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "to": {"number": "+5511988887777"}, "content": { "name": "Sprint Planning", "description": "Planejamento da sprint 24.", "start_at": "2026-05-01T14:00:00Z", "end_at": "2026-05-01T15:00:00Z", "join_link": "https://meet.example.com/abc", "has_reminder": true, "reminder_offset_sec": 600, "location": { "latitude": -23.5505, "longitude": -46.6333, "name": "HQ - Sala Mestre" } } }'await fetch('https://api.turbonotify.com/v1/messages', { method: 'POST', headers: { 'Authorization': 'Bearer SUA_CHAVE', 'Content-Type': 'application/json' }, body: JSON.stringify({ to: { number: '+5511988887777' }, content: { name: 'Sprint Planning', description: 'Planejamento da sprint 24.', start_at: '2026-05-01T14:00:00Z', end_at: '2026-05-01T15:00:00Z', join_link: 'https://meet.example.com/abc', has_reminder: true, reminder_offset_sec: 600, location: { latitude: -23.5505, longitude: -46.6333, name: 'HQ - Sala Mestre' } } })});import requests
requests.post( "https://api.turbonotify.com/v1/messages", headers={ "Authorization": "Bearer SUA_CHAVE", "Content-Type": "application/json", }, json={ "to": {"number": "+5511988887777"}, "content": { "name": "Sprint Planning", "description": "Planejamento da sprint 24.", "start_at": "2026-05-01T14:00:00Z", "end_at": "2026-05-01T15:00:00Z", "join_link": "https://meet.example.com/abc", "has_reminder": True, "reminder_offset_sec": 600, "location": { "latitude": -23.5505, "longitude": -46.6333, "name": "HQ - Sala Mestre", }, }, },)| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
content.name | string | sim | título do evento; até 200 caracteres |
content.description | string | não | até 2000 caracteres |
content.start_at | datetime | sim | ISO-8601 com timezone (campo âncora da variante calendar) |
content.end_at | datetime | não | ISO-8601 com timezone; deve ser > start_at |
content.join_link | string | não | apenas http:///https:// |
content.location | object | não | mesmo formato do objeto location |
content.has_reminder | bool | não | padrão false |
content.reminder_offset_sec | int | não | segundos antes do evento; só tem efeito com has_reminder=true e é ignorado, sem erro, quando has_reminder é false ou ausente |
content.extra_guests_allowed | bool | não | padrão false |
Enviar botão com link
Uma mensagem com um botão que abre um link. O campo âncora é
interactive_type, sempre "cta_url".
{ "to": { "number": "+5511988887777" }, "content": { "interactive_type": "cta_url", "body": "Seu pedido foi enviado.", "footer": "Loja Exemplo", "url_button": { "display_text": "Rastrear", "url": "https://exemplo.com/rastreio/123" } }}| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
content.interactive_type | string | sim | sempre "cta_url" |
content.body | string | sim | 1 a 1024 caracteres |
content.header | object | não | { "type": "text", "text": "..." }, text com 1 a 60 caracteres |
content.footer | string | não | até 60 caracteres |
content.url_button.display_text | string | sim | 1 a 20 caracteres |
content.url_button.url | string | sim | URL http:// ou https:// |
Uma mensagem com botão de link não pode ser editada depois de enviada: apagar é a única alteração. Veja o que pode ser alterado depois do envio.
Como aparece no destinatário
Cada tipo aparece no WhatsApp do destinatário com a interface nativa: localização com mapa e botão “Ver no mapa”, contato com cartão que pode ser salvo, calendário com botão “Adicionar ao calendário”, botão com link com o botão logo abaixo do texto.
A entrada que o convidado cria na agenda com o botão “Adicionar ao calendário” não acompanha uma edição ou um cancelamento do evento: veja O que acontece com os convidados.
Para visualizar exatamente como o evento message.sent correspondente
chega no seu webhook, abra o Webhook Inspector.
O painel “Enriched” renderiza esses tipos com cards dedicados.
Envio para grupo
Para enviar a um grupo, o campo to
recebe o objeto { "group_id": "grp_..." } em vez de
{ "number": "+5511988887777" }, que é a forma usada em 1:1. Veja
Visão geral de grupos para detalhes do modelo.
{ "to": { "group_id": "grp_e442553a56b14e2695f6acfd7d651b1a" }, "content": { "text": "Bom dia, equipe" }}O campo to é polimórfico. Aceita exatamente uma das três formas (sem kind nem type):
Forma de to | Destino |
|---|---|
{ "number": "+5511988887777" } | Mensagem 1:1 (pessoa) |
{ "group_id": "grp_..." } | Mensagem para grupo |
{ "contact_id": "ct_..." } | Mensagem 1:1 via ID de contato Turbo Notify |
- As três formas são mutuamente exclusivas. Envie exatamente uma.
group_idé o identificador públicogrp_{hex32}recebido em webhooks/polling demessage.received(to.group_id) ou nos eventos de ciclo de vida de grupo.- O objeto
contentusa o mesmo formato dos envios 1:1 (texto, imagem, vídeo, áudio, documento, figurinha, localização, contato, calendário, botão com link), sem diferenças. - Para citar uma mensagem dentro do grupo, use o endpoint dedicado
POST /v1/numbers/{ref}/messages/{message_id}/reply.
A resposta tem o formato padrão (message_id, status). O webhook
message.sent correspondente usa to.group_id (o mesmo valor que você
enviou na requisição); o number_alias do envelope identifica o número
que enviou, o que ajuda a relacionar mensagens recebidas e enviadas no
mesmo grupo.
Envio por contact_id
Use to.contact_id para enviar a um contato que o Turbo Notify já conhece, sem informar o telefone.
O Turbo Notify usa o número registrado nesse contato.
{ "to": { "contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" }, "content": { "text": "Olá, tudo bem?" }}