Nuntis documentação Referência da API

Enviar e receber

Mídia

Imagem, áudio, vídeo e documento passam pelo mesmo POST /v1/messages. O binário nunca trafega no recurso da mensagem: o que você recebe são metadados e uma URL assinada e temporária.

Enviar mídia

Troque type e use o bloco media no lugar de text.

json — documento por URL
{
  "numberId": "num_4711",
  "to": { "phone": "+5511999990000" },
  "type": "document",
  "media": {
    "url": "https://cdn.seuproduto.com.br/contratos/2026-08/exemplo.pdf",
    "filename": "contrato.pdf",
    "caption": "Segue o contrato para assinatura."
  }
}
json — áudio como nota de voz, em base64
{
  "numberId": "num_4711",
  "conversationId": "conv_991",
  "type": "audio",
  "media": {
    "base64": "SUQzBAAAAAAA...",
    "mimetype": "audio/ogg",
    "ptt": true
  }
}
CampoDescrição
url URL http(s) pública do arquivo. Mutuamente exclusiva com base64.
base64 O arquivo embutido. Exige mimetype. Mutuamente exclusiva com url.
mimetype No formato tipo/subtipo. Obrigatório quando você usa base64.
filename Nome apresentado ao destinatário. Até 255 caracteres.
caption Legenda exibida junto da mídia. Até 1024 caracteres.
ptt Envia o áudio como nota de voz. Só se aplica a type: audio, e só em canal que declare audioPtt: true.
Teto de 10 MB no corpo da requisição

Arquivo maior que isso precisa ir por url. Base64 ainda infla o tamanho em cerca de um terço — para qualquer coisa que não seja um áudio curto, url é o caminho melhor.

Confira a capacidade antes

Cada canal declara quais tipos de mídia aceita e se suporta nota de voz. Consulte GET /v1/channels e leia midia e audioPtt. Enviar algo que o canal não declara devolve 422 CHANNEL_CAPABILITY_UNSUPPORTED.

Receber mídia

Numa mensagem recebida, o bloco media traz os metadados e — se o arquivo já estiver disponível — uma URL assinada:

json — trecho de message.received
{
  "id": "msg_18291",
  "conversationId": "conv_991",
  "numberId": "num_4711",
  "direction": "inbound",
  "type": "image",
  "status": "received",
  "media": {
    "mimetype": "image/jpeg",
    "filename": "foto.jpg",
    "size": 184320,
    "caption": "É esse o comprovante?",
    "url": "https://…<assinada e temporária>",
    "urlExpiresAt": "2026-08-13T19:12:03.000Z",
    "pending": false
  }
}
Nunca persista a url

Ela é assinada e temporária, gerada sob demanda a cada leitura. Um link guardado no seu banco vira um 403 silencioso no dia seguinte — a imagem simplesmente para de carregar na sua interface, sem erro nenhum no seu log.

Baixe o arquivo para o seu próprio armazenamento assim que receber, ou peça a URL de novo com GET /v1/messages/{id} na hora de exibir. O campo urlExpiresAt diz quando ela deixa de valer.

Quando o arquivo ainda não chegou

Falha de mídia nunca derruba a mensagem. Se os metadados chegaram mas o binário não, a mensagem é persistida normalmente — texto, legenda e remetente completos — com media.pending: true e sem url.

json
"media": {
  "mimetype": "application/pdf",
  "filename": "comprovante.pdf",
  "pending": true
}

Isso é deliberado: descartar a mensagem inteira porque um anexo falhou faria você perder o que o cliente escreveu. O anexo é recuperável; a mensagem perdida não.

Rebaixar o arquivo

POST /v1/messages/{id}/media/redownload

bash
curl -X POST \
  -H "x-api-key: $NUNTIS_API_KEY" \
  https://api.nuntis.com.br/v1/messages/msg_18291/media/redownload

A resposta é o recurso completo da mensagem, com media.url preenchida quando a recuperação deu certo.

SituaçãoResposta
Mídia recuperada 200 com media.url e pending: false.
Mídia estava disponível 200 com o recurso como está. É idempotente — pedir de novo não é erro.
Mensagem sem mídia 400 VALIDATION_FAILED.
Canal ou armazenamento indisponível agora 503 CHANNEL_UNREACHABLE, com retryable: true. Tente de novo com backoff.
Não é um proxy de download

A rota devolve o recurso da mensagem, com uma URL nova — não os bytes do arquivo. Baixe pela URL devolvida.

Fluxo recomendado

  1. Chega message.received no seu webhook.
  2. Se media.pending for false, baixe pela url e guarde no seu armazenamento.
  3. Se for true, agende um redownload com backoff em vez de tentar em laço.
  4. Na sua interface, sirva sempre do seu armazenamento — nunca da URL do Nuntis.