Pular para o conteúdo

Consultar mensagem

Recupere o conteúdo completo, o status de entrega e a referência de mídia de qualquer mensagem enviada ou recebida na sua conta, usando o id como identificador.

Use GET /v1/messages/{id} para o número principal. Para números extras, use GET /v1/numbers/{ref}/messages/{id}, onde {ref} é o alias atual do número ou o id dele (num_…, o number_id da mensagem). Prefira o id: o alias lido numa mensagem antiga pode ter sido renomeado depois.

Escopo obrigatório: messages:read

Consultar mensagem

get-mensagem.sh
curl -X GET \
https://api.turbonotify.com/v1/messages/msg_01993c5a1b24d3e9f01a2b3c4d5e6f70 \
-H "Authorization: Bearer SUA_CHAVE"

Resposta: mensagem de texto (outbound)

Status HTTP: 200
{
  "id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f70",
  "organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "number_alias": "main",
  "number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
  "from": {
    "name": "Turbo Notify",
    "number": "5511973117056",
    "alias": "main"
  },
  "to": {
    "name": "João",
    "number": "5511988887777"
  },
  "preview": "Olá, seu pedido foi confirmado!",
  "content_expired": false,
  "text": "Olá, seu pedido foi confirmado!",
  "content_type": "text",
  "direction": "outbound",
  "channel": "whatsapp",
  "origin": "tn",
  "at": "2026-06-01T13:00:05Z",
  "status": {
    "state": "delivered",
    "at": "2026-06-01T13:01:00Z"
  }
}

Resposta: mensagem de imagem (inbound)

Status HTTP: 200
{
  "id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f71",
  "organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "number_alias": "main",
  "number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
  "from": {
    "name": "João",
    "number": "5511988887777"
  },
  "to": {
    "name": "Turbo Notify",
    "number": "5511973117056",
    "alias": "main"
  },
  "preview": "Foto do produto",
  "content_expired": false,
  "image": {
    "caption": "Foto do produto",
    "kind": "available",
    "url": "https://your-bucket.r2.cloudflarestorage.com/organizations/.../image.jpeg?X-Amz-...",
    "expires_at": "2026-06-01T14:00:00Z",
    "mime_type": "image/jpeg",
    "size_bytes": 123456
  },
  "content_type": "image",
  "direction": "inbound",
  "channel": "whatsapp",
  "origin": "native",
  "at": "2026-06-01T13:00:00Z",
  "status": {
    "state": "read",
    "at": "2026-06-01T13:05:00Z"
  }
}

Campos da resposta

from e to são objetos cujo formato depende da direção da mensagem, o mesmo usado nos webhooks. O seu número na conversa é identificado pelo number_id (e pelo number_alias, o alias que ele tinha na hora); os dados dele estão em GET /v1/numbers/{ref}, com o number_id.

CampoTipoDescrição
idstringIdentificador público da mensagem (msg_ + 32 hex)
organization_idstringIdentificador público da sua organização (org_{hex32}). Sempre presente.
number_aliasstringO alias que o número Turbo Notify tinha na hora da mensagem: "main" ou o alias de um número extra, o mesmo valor do evento. Se o número for renomeado depois, as mensagens antigas mantêm o alias antigo. Para ler os dados do número, use GET /v1/numbers/{ref} com o number_id.
number_idstringIdentificador do número (num_…), logo depois do number_alias. Nunca muda, mesmo que o alias seja renomeado.
fromobjectRemetente: o formato depende da direção
toobjectDestinatário: o formato depende da direção
previewstringTrecho inicial do conteúdo. Expira junto com o conteúdo, no prazo de retenção do plano (vira ""), veja Sobre preview
content_expiredbooleantrue quando o conteúdo já passou do prazo de retenção do seu plano e foi apagado. A mensagem continua consultável por 12 meses, veja Conteúdo expirado
campo específicoobject|stringConteúdo completo nomeado pelo content_type (text, image, …). Veja a tabela abaixo.
content_typestringtext, image, audio, video, document, sticker, location, calendar, contact, interactive. Enquetes e tipos não reconhecidos são armazenados como text. O preview preserva o texto disponível.
directionstringoutbound (enviada) ou inbound (recebida)
channelstringSempre "whatsapp"
originstring"tn" (envio via Turbo Notify API) ou "native" (digitada no celular). Sempre presente.
atstringISO 8601 em UTC com sufixo Z e precisão de segundos (ex.: 2026-06-01T13:00:05Z): momento estável de ocorrência da mensagem no WhatsApp (outbound: o momento real de envio; inbound: o momento de recebimento). Não muda conforme a mensagem avança sent → delivered → read. Para o momento da entrega/leitura atual, use status.at.
statusobject{state, at}: estado atual de entrega e o status.at correspondente. Diferente do at raiz, o status.at avança a cada transição (move para delivered, depois read).
mentionsarrayOpcional: presente apenas quando a mensagem menciona alguém (inbound ou outbound). Lista de contatos mencionados, itens {contact_id?, name?, number} (mesmo formato do from inbound), na ordem dos tokens no texto, sem duplicatas. Um @<digitos> no texto só é menção se o número constar aqui. Segue a mesma janela de retenção do restante do conteúdo. Veja Menções (@mentions).

Campos por content_type

Além dos campos comuns acima, cada content_type expõe um campo específico com o conteúdo completo:

content_typeCampo específicoDescrição
texttextTexto completo da mensagem
imageimageObjeto com caption? e campos de mídia (kind, url?, expires_at?, …) diretamente
videovideoObjeto com caption? e campos de mídia
audioaudioObjeto com campos de mídia e transcription? (BYO Speech-to-Text, se configurado)
documentdocumentObjeto com filename?, caption? e campos de mídia
stickerstickerObjeto com campos de mídia
locationlocationObjeto com latitude, longitude, name?, address?, url?, is_live?, accuracy_m?, comment?, thumbnail_b64?. is_live aparece apenas quando true (localização em tempo real). Nunca vem como false; trate a ausência da chave como “não é ao vivo”. accuracy_m (precisão do GPS, em metros) e comment (nota de texto anexada pelo remetente) só aparecem em localizações inbound quando o WhatsApp os envia. Não podem ser enviados pela API.
calendarcalendarObjeto com name, description?, start_at?, end_at?, join_link?, location?, has_reminder?, reminder_offset_sec?, extra_guests_allowed?. Um calendário inbound também pode trazer is_canceled?/is_scheduled_call? (o organizador cancelou o evento / é uma chamada agendada: sinalizados pelo próprio WhatsApp; is_scheduled_call nunca é enviável pela API). Em um calendário inbound, has_reminder/extra_guests_allowed/is_canceled/is_scheduled_call aparecem apenas quando true: trate a ausência da chave como “não”. Em um calendário outbound enviado pela API, o conteúdo é devolvido exatamente como foi enviado: "has_reminder": false, "extra_guests_allowed": false e chaves explicitamente null (description, end_at, join_link, location, reminder_offset_sec) podem aparecer (is_scheduled_call nunca aparece em calendários outbound; is_canceled aparece como true depois que você cancela o evento pela API). Trate false/null/chave ausente como equivalentes.
contactcontactCartão vCard estruturado: mesmos campos aceitos no envio (Enviar contato): display_name, phones[], emails?, organization?, title?, address?
interactiveinteractiveObjeto com interactive_type (sempre "cta_url"), body, header? ({type: "text", text}), footer?, url_button: {display_text, url}

Para mensagens replied (citações):

CampoTipoDescrição
repliedobject{message_id: string, preview: string}: id e trecho da mensagem citada

Para mensagens reacted:

CampoTipoDescrição
textstringO emoji da reação (ex.: "👍") ou "" para remoção

Exemplo: mensagem de texto

GET /v1/numbers/{ref}/messages/{id}: text
{
"id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f70",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "Turbo Notify", "alias": "main", "number": "5511973117056" },
"to": { "name": "João", "number": "5511988887777" },
"preview": "Olá, seu pedido foi confirmado!",
"content_expired": false,
"text": "Olá, seu pedido foi confirmado!",
"content_type": "text",
"direction": "outbound",
"channel": "whatsapp",
"origin": "tn",
"at": "2026-06-01T13:00:05Z",
"status": { "state": "delivered", "at": "2026-06-01T13:01:00Z" }
}

Exemplo: mensagem de imagem (inbound, BYO Storage ativo)

GET /v1/numbers/{ref}/messages/{id}: image (available)
{
"id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f71",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "Foto do produto",
"content_expired": false,
"image": {
"caption": "Foto do produto",
"kind": "available",
"url": "https://<bucket>.s3.amazonaws.com/...?X-Amz-Signature=...",
"expires_at": "2026-06-01T14:00:00Z",
"mime_type": "image/jpeg",
"size_bytes": 184320
},
"content_type": "image",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "read", "at": "2026-06-01T13:05:00Z" }
}

Exemplo: mensagem de imagem (sem BYO Storage)

GET /v1/numbers/{ref}/messages/{id}: image (unavailable)
{
"id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f72",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "[Image]",
"content_expired": false,
"image": {
"kind": "unavailable",
"reason": "no_storage",
"mime_type": "image/jpeg",
"size_bytes": 184320,
"setup_hint": {
"setup_url": "https://dashboard.turbonotify.com/storage",
"docs_url": "https://docs.turbonotify.com/general/byo-storage-setup/",
"message": "Configure BYO Object Storage to receive media."
}
},
"content_type": "image",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "delivered", "at": "2026-06-01T13:00:00Z" }
}

Exemplo: mensagem de localização

GET /v1/numbers/{ref}/messages/{id}: location
{
"id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f73",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "Av. Paulista, Avenida Paulista, 1578, Bela Vista,",
"content_expired": false,
"location": {
"latitude": -23.561414,
"longitude": -46.655881,
"name": "Av. Paulista",
"address": "Avenida Paulista, 1578, Bela Vista, São Paulo - SP",
"url": "https://maps.google.com/?q=-23.561414,-46.655881",
"thumbnail_b64": "..."
},
"content_type": "location",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "delivered", "at": "2026-06-01T13:00:00Z" }
}

Exemplo: mensagem de calendário

GET /v1/numbers/{ref}/messages/{id}: calendar
{
"id": "msg_01993c5a1b24d3e9f01a2b3c4d5e6f74",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "Sprint Planning — Mon, 1 Jun 2026 17:00",
"content_expired": false,
"calendar": {
"name": "Sprint Planning",
"description": "Planejamento da sprint 24.",
"start_at": "2026-06-01T14:00:00-03:00",
"end_at": "2026-06-01T15:00:00-03:00",
"join_link": "https://meet.example.com/sprint-planning",
"has_reminder": true,
"reminder_offset_sec": 600
},
"content_type": "calendar",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "delivered", "at": "2026-06-01T13:00:00Z" }
}

Exemplo: mensagem interativa (cta_url)

GET /v1/numbers/{ref}/messages/{id}: interactive
{
"id": "msg_d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "Turbo Notify", "alias": "main", "number": "5511973117056" },
"to": { "name": "João", "number": "5511988887777" },
"preview": "Clique para saber mais",
"content_expired": false,
"interactive": {
"interactive_type": "cta_url",
"body": "Clique para saber mais",
"footer": "Turbo Notify",
"url_button": {
"display_text": "Acessar",
"url": "https://turbonotify.com"
}
},
"content_type": "interactive",
"direction": "outbound",
"channel": "whatsapp",
"origin": "tn",
"at": "2026-06-01T13:00:05Z",
"status": { "state": "delivered", "at": "2026-06-01T13:01:00Z" }
}

O botão url_button abre o link diretamente no destinatário; header é opcional ({type: "text", text}; por enquanto, só texto).

Exemplo: mensagem com menções

O texto carrega os tokens @<numero> normalizados; a estrutura mentions traz os contatos correspondentes, já resolvidos:

GET /v1/numbers/{ref}/messages/{id}: text com mentions
{
"id": "msg_c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "Turbo Notify", "alias": "main", "number": "5511973117056" },
"to": { "group_id": "grp_e442553a56b14e2695f6acfd7d651b1a", "name": "Equipe Vendas" },
"preview": "Bom dia @5511977776666, pode validar o pedido de hoje?",
"content_expired": false,
"text": "Bom dia @5511977776666, pode validar o pedido de hoje?",
"mentions": [
{
"contact_id": "ct_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"name": "Maria Santos",
"number": "5511977776666"
}
],
"content_type": "text",
"direction": "outbound",
"channel": "whatsapp",
"origin": "tn",
"at": "2026-07-03T13:00:05Z",
"status": { "state": "delivered", "at": "2026-07-03T13:01:00Z" }
}

O campo aparece em mensagens inbound e outbound e continua presente depois que o conteúdo expira: ele não traz texto, só os contatos mencionados (veja Retenção das mensagens).

Exemplo: reply (mensagem citada)

GET /v1/numbers/{ref}/messages/{id}: replied
{
"id": "msg_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "Sim, é esse pedido mesmo!",
"content_expired": false,
"text": "Sim, é esse pedido mesmo!",
"replied": {
"message_id": "msg_99887766554433221100ffeeddccbbaa",
"preview": "Pedido #1234 foi aprovado."
},
"content_type": "text",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "delivered", "at": "2026-06-01T13:00:00Z" }
}

Exemplo: reação

GET /v1/numbers/{ref}/messages/{id}: reacted
{
"id": "msg_b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5",
"organization_id": "org_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"number_alias": "main",
"number_id": "num_0f8e2c4a6b1d4e7f9a3c5d7e9b1a3c5e",
"from": { "name": "João", "number": "5511988887777" },
"to": { "alias": "main", "number": "5511973117056" },
"preview": "👍",
"content_expired": false,
"text": "👍",
"content_type": "text",
"direction": "inbound",
"channel": "whatsapp",
"origin": "native",
"at": "2026-06-01T13:00:00Z",
"status": { "state": "delivered", "at": "2026-06-01T13:00:00Z" }
}

Campos de mídia

Os campos de mídia aparecem diretamente no objeto específico (image, video, audio, document, sticker), sem sub-objeto media. O campo kind indica qual dos formatos abaixo a mídia tem:

kind: "available"

Mídia disponível para download. Requer Object Storage configurado (abre em nova aba) .

CampoTipoDescrição
kindstring"available"
urlstringURL pré-assinada de download
expires_atstring | nullTimestamp de expiração do acesso à mídia. Consulte a mensagem novamente para obter uma nova URL após a expiração, dentro do prazo de retenção de conteúdo do plano.
mime_typestring | nullTipo MIME do arquivo (ex: image/jpeg, application/pdf)
size_bytesinteger | nullTamanho do arquivo em bytes

kind: "pending"

A mídia ainda está sendo copiada para o seu bucket. Aguarde alguns segundos e consulte novamente.

CampoTipoDescrição
kindstring"pending"
mime_typestring | nullTipo MIME detectado
size_bytesinteger | nullTamanho do arquivo em bytes

kind: "unavailable"

Mídia não está disponível. O campo reason indica a causa.

CampoTipoDescrição
kindstring"unavailable"
reasonstringno_storage: nenhum Object Storage configurado; storage_circuit_open: o seu Object Storage vinha falhando repetidamente no momento do recebimento, e o envio de mídia para ele estava suspenso temporariamente; upload_failed: storage saudável, mas este item não pôde ser persistido; deleted: a mensagem foi apagada/revogada depois que a mídia já havia sido armazenada; expired: o conteúdo passou do prazo de retenção do seu plano e foi apagado (veja Conteúdo expirado). O motivo é registrado no momento do recebimento, da exclusão ou da expiração e não muda depois.
mime_typestring | nullTipo MIME detectado
size_bytesinteger | nullTamanho do arquivo em bytes
setup_hintobject | nullPresente quando reason é no_storage ou storage_circuit_open. Contém setup_url, docs_url e message.

audio.transcription

Quando BYO Speech-to-Text está ligado na sua organização, mensagens de áudio inbound ganham o campo transcription dentro do objeto audio, também identificado por kind (omitido quando a transcrição não foi tentada, por exemplo em áudio outbound ou sem transcrição configurada). Mesmo formato do data.transcription dos webhooks/polling de message.received:

CampoTipoDescrição
kindstring"available": transcrição concluída, ou "unavailable": não disponível.
textstring(apenas available) Texto transcrito.
languagestring | null(apenas available) Código BCP-47 do idioma detectado/configurado, quando disponível.
reasonstring(apenas unavailable) Um destes 6 valores: not_configured, provider_error, file_too_large (áudio acima de 24 MB), timeout, provider_not_supported (o provedor de transcrição configurado não é suportado no momento) ou internal_error.
hintstring | null(apenas unavailable) Orientação opcional, escrita para quem lê o evento (com o link da tela Transcrição do dashboard quando há algo a ajustar lá).

O fluxo da mensagem nunca é bloqueado por falha de transcrição. Para ligar a transcrição, veja Transcrição de áudio.

Status da mensagem

O campo status contém o estado atual de entrega:

CampoTipoDescrição
statestringEstado atual: pending (aceito no 202, ainda não enviado ao WhatsApp), sent, delivered, read, failed (outbound); delivered, read (inbound)
atstringISO 8601: timestamp do estado atual de entrega; avança a cada transição (sent → delivered → read). Não confundir com o at no nível raiz, que é o momento estável de ocorrência da mensagem.
errorobjectErro estruturado da falha: presente apenas quando state: "failed"; ausente (chave omitida) nos demais estados. Mesmo formato do data.error dos webhooks *.failed.
error.codestringCódigo estável: decida o tratamento da falha por este valor.
error.messagestringDescrição legível da falha, para logs e depuração. Pode trazer um diagnóstico do WhatsApp em inglês; identificadores pessoais (números, JIDs) nunca aparecem nela. O contrato estável é o code, não este texto.
error.hintstringOrientação acionável, derivada do code. Ausente (chave omitida, nunca null) quando não há orientação para o code.

Sobre preview

O campo preview segue exatamente o mesmo prazo de retenção de conteúdo do plano da sua organização, veja Retenção das mensagens. Ele não é guardado por mais tempo que o restante do conteúdo. Enquanto o conteúdo está dentro do prazo, preview traz um trecho do conteúdo, sem partir emoji ou acento ao meio:

  • Para text: primeiros ~50 caracteres do texto.
  • Para location: texto humanizado sem colchetes (ex: Av. Paulista, Sao Paulo, SP).
  • Para calendar: resumo sem colchetes, com dia da semana e mês abreviados em inglês e o horário convertido para UTC (ex: Sprint Planning — Mon, 1 Jun 2026 17:00).
  • Para mídia: a legenda (quando disponível) ou o rótulo do tipo em inglês ([Image], [Video], [Audio], [Document], [Sticker]). Documento: legenda → nome do arquivo → [Document]. Áudio com transcrição é a exceção: quando há transcrição disponível, o preview traz o texto transcrito (truncado em 50 caracteres). [Audio] só aparece quando não há transcrição nem legenda.
  • Para interactive: o texto do body da mensagem, ou [Interactive] quando o corpo está vazio.
  • Para reações: o emoji ou "" para remoção.
  • Menções: cada token @<numero> presente em mentions conta como exatamente 1 caractere no limite de ~50, e o recorte nunca corta um token no meio; um @<digitos> literal fora de mentions conta caractere a caractere. O valor é idêntico ao data.preview dos webhooks/polling.

Depois que o conteúdo passa do prazo de retenção do seu plano, preview vira "" e content_expired passa a true: não há um caminho que devolva o recorte depois desse ponto. O mesmo prazo apaga data.preview (junto com o resto do conteúdo) da cópia guardada de uma entrega de webhook já concluída e dos eventos de GET /v1/events: consulta por id, webhook e polling seguem um único prazo. A exceção é uma entrega de webhook ainda não concluída, que guarda o conteúdo até ser entregue ou até acabarem as novas tentativas (no máximo 72 horas).

Conteúdo expirado

Só o conteúdo expira. Uma mensagem que passou do prazo de retenção de conteúdo do seu plano (1 hora por padrão, até 72 horas conforme o plano) continua consultável por 12 meses, e status, recibos, reações, resposta, reação, edição e exclusão continuam funcionando. Na resposta:

  • content_expired é true.
  • preview e text são "".
  • Os blocos de mídia e de conteúdo estruturado (image, video, audio, document, sticker, location, calendar, contact, interactive) trazem {"kind": "unavailable", "reason": "expired"}, a mesma forma de uma mensagem apagada, com outro reason.
  • replied.preview é "" quando a mensagem citada expirou; replied.message_id continua lá.
  • mentions continua presente.

Uma mensagem apagada mantém a forma de mensagem apagada (reason: "deleted") e content_expired: false.

Sobre kind

Para receber mídia inbound com kind: "available", configure a integração de Object Storage (abre em nova aba) no dashboard. Sem essa configuração, o Turbo Notify não tem onde armazenar a mídia e retorna kind: "unavailable" com reason: "no_storage".

Quando o Object Storage está configurado, o Turbo Notify copia cada mídia recebida para o seu bucket e retorna uma URL pré-assinada com validade configurável. O acesso à mídia expira conforme o expires_at. Você pode obter uma nova URL consultando a mensagem novamente enquanto o conteúdo está dentro do prazo de retenção do seu plano. Depois dele, o bloco de mídia vem como {"kind": "unavailable", "reason": "expired"} e o arquivo continua no seu bucket (Conteúdo expirado).

Erros possíveis

StatusCódigo de erroDescrição
400invalid_message_idO identificador não corresponde ao formato msg_ + 32 hex.
401not_authenticatedA chave de API está inválida ou ausente.
403insufficient_scopeA chave de API não possui o escopo messages:read (resposta inclui required_scope).
404not_foundMensagem não 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): mesma resposta de uma mensagem que nunca existiu.
404number_not_found(apenas na rota com {ref}) O alias ou o id informado na URL não corresponde a nenhum número cadastrado.
400invalid_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.
429rate_limit_exceededLimite de requisições ultrapassado.
500internal_errorErro interno inesperado no servidor.