Status da mensagem
Após enviar uma mensagem, você pode consultar o status dela a qualquer momento pela API. O status reflete o andamento do processamento e entrega no WhatsApp.
Tabela de status
| Status | Descrição |
|---|---|
pending | A mensagem foi recebida pelo Turbo Notify e aguarda processamento. |
sent | A mensagem foi enviada ao WhatsApp com sucesso. |
delivered | A mensagem foi entregue ao dispositivo do destinatário. |
read | A mensagem foi lida pelo destinatário. |
failed | O envio falhou. Consulte o objeto error ({code, message, hint}) para detalhes. |
Consultar status
Para consultar o status de uma mensagem, faça uma requisição GET informando o message_id retornado no envio.
curl -X GET \ https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status \ -H "Authorization: Bearer SUA_CHAVE"const response = await fetch( 'https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status', { method: 'GET', headers: { 'Authorization': 'Bearer SUA_CHAVE' } });
const result = await response.json();console.log(result);import requests
url = "https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status"headers = { "Authorization": "Bearer SUA_CHAVE"}
response = requests.get(url, headers=headers)result = response.json()print(result)package main
import ( "fmt" "io" "net/http")
func main() { req, _ := http.NewRequest("GET", "https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status", nil) req.Header.Set("Authorization", "Bearer SUA_CHAVE") 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/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status';
$options = [ 'http' => [ 'header' => [ 'Authorization: Bearer SUA_CHAVE' ], 'method' => 'GET' ]];
$context = stream_context_create($options);$result = file_get_contents($url, false, $context);$response = json_decode($result, true);var_dump($response);?>var client = new HttpClient();client.DefaultRequestHeaders.Add("Authorization", "Bearer SUA_CHAVE");
var response = await client.GetAsync( "https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status");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 request = HttpRequest.newBuilder() .uri(URI.create("https://api.turbonotify.com/v1/messages/msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7/status")) .header("Authorization", "Bearer SUA_CHAVE") .GET() .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); }}Exemplos de resposta
Pendente
{
"message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
"status": {
"state": "pending",
"at": "2025-07-16T10:00:00Z",
"error": null
}
} Enviada
{
"message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
"status": {
"state": "sent",
"at": "2025-07-16T10:00:02Z",
"error": null
}
} Entregue
{
"message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
"status": {
"state": "delivered",
"at": "2025-07-16T10:00:05Z",
"error": null
}
} Lida
{
"message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
"status": {
"state": "read",
"at": "2025-07-16T10:01:12Z",
"error": null
}
} Falha
{
"message_id": "msg_0198d3c5a1b24d3e9f01a2b3c4d5e6f7",
"status": {
"state": "failed",
"at": "2025-07-16T10:00:03Z",
"error": {
"code": "number_not_connected",
"message": "The number is not connected to WhatsApp.",
"hint": "The number was not connected to WhatsApp. Reconnect it, then send the message again."
}
}
} Detalhes da falha
Quando o status é failed, o objeto error traz os detalhes. Ele tem a mesma
estrutura do data.error dos webhooks *.failed, então o evento e a consulta descrevem a falha
do mesmo jeito (veja Webhooks e Consultar mensagem):
| Campo | Descrição |
|---|---|
error.code | Código estável, feito para o seu código: decida o tratamento por este valor (ex.: number_not_connected, whatsapp_send_failed, media_fetch_failed). |
error.message | Descrição legível da falha, para os seus logs e para depuração. Pode trazer um diagnóstico do WhatsApp em inglês; identificadores pessoais (números, JIDs) nunca aparecem nela. Não decida o tratamento por este texto: ele pode mudar, o code é o que permanece estável. |
error.hint | string: orientação acionável para corrigir, derivada do code. Ausente (chave omitida, nunca null) quando não há orientação para o code. |
Neste endpoint o campo error está sempre presente: vem preenchido quando state é failed e null nos demais estados (pending/sent/delivered/read). Já em GET /v1/numbers/{ref}/messages/{id}, o campo é omitido quando não há falha.
Erros possíveis
| Status | Código de erro | Descrição |
|---|---|---|
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:read (resposta inclui required_scope). |
404 | not_found | A mensagem não foi encontrada, pertence a outra organização ou pertence a um número diferente do da URL (na rota atalho sem {ref}, o número principal): todos esses casos devolvem a mesma resposta, sem distinção. |
404 | number_not_found | (apenas na rota com {ref}) O alias ou o id informado na URL não corresponde a nenhum número cadastrado. |
400 | invalid_number_id | (apenas na rota com {ref}) O valor na URL começa com num_, mas não é um id de número válido. |
500 | internal_error | Erro interno inesperado no servidor. |
Retenção
O status continua consultável por 12 meses, mesmo depois que o conteúdo da mensagem expira no prazo de retenção do seu plano: só o conteúdo expira. Os prazos por plano estão em Retenção.
Momento da mudança de status
O momento da mudança de estado mais recente vem no campo status.at, que avança a cada mudança (sent → delivered → read):
- Em
GET /v1/numbers/{ref}/messages/{id}/statuso objetostatuscarrega{state, at}: ostatus.até o instante em que o estado atual foi atingido. - Em
GET /v1/numbers/{ref}/messages/{id}o mesmostatus.ataparece dentro do objetostatus. Não confunda com oatno nível raiz da mensagem: este é o momento em que a mensagem aconteceu (mensagem enviada: o envio real no WhatsApp; mensagem recebida: o recebimento) e não muda conforme a mensagem avança paradelivered/read. - Nos eventos
message.sent,message.deliveredemessage.read(webhook e polling viaGET /v1/events) o instante da ação vem emdata.at: o mesmo nome de campo em todos os eventosmessage.*.
Atualizações em tempo real
Para receber cada mudança de status sem consultar a API repetidamente, configure um webhook. Veja como em Eventos via webhook.