Snodr

Documentação da API

Um caminho simples para sair da API Key até o primeiro envio no WhatsApp.

Esta página foi pensada para quem não vive programação no dia a dia. A ideia é seguir uma ordem natural: preparar a conta, descobrir a instância certa e só então enviar a mensagem.

Qual é a ordem mais segura para fazer tudo funcionar

1

Crie sua conta e escolha um plano

A conta precisa estar ativa para liberar a área do usuário e permitir a criação da primeira instância. Abrir meu plano

2

Crie a instância no painel

A instância é o identificador operacional que representa o WhatsApp que fará os envios. Abrir instâncias

3

Conecte o WhatsApp pelo QR Code

Sem a instância conectada, o endpoint de envio não libera a mensagem e retorna conflito. Ir para o painel

4

Gere sua API Key

Na tela de API Key, crie a chave da conta e guarde o valor completo no mesmo momento em que ele aparecer. Abrir API Key

5

Teste primeiro o endpoint /me

Isso confirma se a chave está correta antes de você gastar tempo tentando enviar mensagens.

6

Liste /instances e pegue o id

O envio sempre precisa de uma instância específica, então este é o passo natural antes do `send-message`.

Um endpoint, três tipos de mensagem e duas formas de enviar mídia

Use sempre `POST /api/integration/instances/:instanceId/send-message`. O campo `type` define o contrato; apenas integrações antigas de texto podem omiti-lo.

textapplication/json
Obrigatórios
`to` e `text`
Campos aceitos
`type`, `to`, `text`

`text` aceita até 65.536 caracteres. O campo `type` pode ser omitido apenas por compatibilidade.

imageJSON por URL ou multipart
Obrigatórios
`to` e uma fonte de mídia
Campos aceitos
`type`, `to`, `caption`, `url`

`caption` aceita até 4.096 caracteres. No multipart, remova `url` e envie o arquivo em `file`.

documentJSON por URL ou multipart
Obrigatórios
`to` e uma fonte de mídia
Campos aceitos
`type`, `to`, `caption`, `fileName`, `mimeType`, `url`

`fileName` e `mimeType` são opcionais, mas quando informados são validados contra o conteúdo real.

Regras de conteúdo e limites

Destino

Envie `to` em formato internacional, com DDI e DDD. Para grupos, use o JID completo terminado em `@g.us` — descubra o JID com `GET /instances/:instanceId/groups`.

Upload multipart

Envie exatamente um campo `file` e um campo `message`. O limite padrão é 15 MiB e o JSON de `message` não deve conter `url`. Abrir Uso da API

Mídia por URL

A URL deve ser pública e válida. O serviço protege contra SSRF, limita redirects, tamanho e tempo de download e inspeciona o conteúdo real.

Não misture fontes

Use URL em JSON ou arquivo em multipart. Enviar as duas fontes na mesma requisição é inválido.

Resposta de sucesso

O objeto `result` vem do serviço do WhatsApp e contém o `messageId`. Para mídia, também inclui o resultado da inspeção do arquivo.

{
  "instanceId": "INSTANCE_ID",
  "message": {
    "type": "image",
    "to": "5511999999999",
    "caption": "Imagem do pedido",
    "source": "upload"
  },
  "ok": true,
  "result": {
    "instanceId": "INSTANCE_ID",
    "to": "5511999999999",
    "jid": "5511999999999@s.whatsapp.net",
    "messageId": "IDENTIFICADOR_WHATSAPP",
    "media": {
      "filename": "foto.jpg",
      "mimeType": "image/jpeg",
      "extension": "jpg",
      "contentTypeDetected": true
    }
  },
  "sentAt": "2026-06-19T12:00:00.000Z"
}
Compatibilidade de texto

O payload legado { "to": "...", "text": "..." } continua aceito. Para novas integrações, use { "type": "text", "to": "...", "text": "..." }. A rota pública permanece a mesma.

Como criar um fluxo de opções de forma confiável

Botões e listas nativas do WhatsApp ainda são tratados como experimentais. Para fluxos de produção, envie uma mensagem de texto com opções numeradas e interprete a resposta do cliente no seu sistema.

Mensagem enviada

Este formato usa apenas o contrato público type: "text", por isso é o caminho mais estável para atendimento, triagem e menus simples.

Olá! Como podemos ajudar?

Responda com uma das opções:
1 - Financeiro
2 - Suporte

Você também pode responder "Financeiro" ou "Suporte".

Como tratar a resposta

Normalize a entrada

Converta a resposta para minúsculas, remova acentos e aceite variações como 1, financeiro, 2 e suporte.

Use webhook para automação

O envio funciona sem webhook, mas a automação precisa receber a resposta do cliente. Para configurar, abra o card de instâncias, clique em Abrir detalhe da instância na instância que enviará as mensagens e ajuste o webhook nos detalhes dela. Ir para o card de instâncias

Depois de configurar

Quando o webhook estiver ativo na instância, trate os eventos de mensagem recebida no seu sistema. Use o instanceId do evento para saber de qual WhatsApp veio a resposta e aplique a regra do fluxo numerado.

Valide a assinatura

Todo webhook enviado pela plataforma inclui x-snodr-signature,x-snodr-timestamp, x-snodr-event,x-snodr-instance-id e x-snodr-delivery-id.Use o segredo da instância para confirmar que o evento é legítimo.

{
  "event": "message.received",
  "instanceId": "INSTANCE_ID",
  "from": "5511999999999@s.whatsapp.net",
  "text": "1",
  "messageId": "IDENTIFICADOR_DA_RESPOSTA"
}
const crypto = require("crypto");

function isValidSnodrSignature({ rawBody, timestamp, signature, secret }) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Exemplos prontos para copiar e testar com curl ou Postman

1. Validar a API Key com /me

Use este primeiro teste para confirmar que a API Key está correta e que a conta foi reconhecida.

curl -H "x-api-key: SUA_API_KEY" "https://snodr.com/api/integration/me"

2. Descobrir a instância com /instances

Depois de validar a chave, liste as instâncias disponíveis e copie o valor de id da instância conectada que vai enviar mensagens.

curl -H "x-api-key: SUA_API_KEY" "https://snodr.com/api/integration/instances"

3. Enviar a primeira mensagem

Com a instância conectada e o id em mãos, envie uma mensagem do tipo text. Integrações existentes sem o campo type continuam compatíveis.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"type\":\"text\",\"to\":\"5511999999999\",\"text\":\"Olá! Esta é uma mensagem de teste.\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

4. Enviar uma imagem por URL

Envie uma imagem disponível em URL pública. O serviço valida endereço, redirects, tamanho e conteúdo real antes do envio.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"type\":\"image\",\"to\":\"5511999999999\",\"caption\":\"Imagem do pedido\",\"url\":\"https://cdn.example.com/order.jpg\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

5. Enviar um documento por URL

Para documentos, você pode declarar o nome e o MIME. Eles serão comparados com o conteúdo baixado antes do envio.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"type\":\"document\",\"to\":\"5511999999999\",\"caption\":\"Contrato\",\"fileName\":\"contrato.pdf\",\"mimeType\":\"application/pdf\",\"url\":\"https://cdn.example.com/contract.pdf\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

6. Fazer upload de imagem

No upload, envie somente os campos file e message. O campo message contém o mesmo contrato JSON, mas sem url.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -F "file=@foto.jpg;type=image/jpeg" \
  -F "message={\"type\":\"image\",\"to\":\"5511999999999\",\"caption\":\"Imagem do pedido\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

7. Fazer upload de documento

O conteúdo real, o MIME e a extensão do documento são validados pelo serviço antes do envio.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -F "file=@contrato.pdf;type=application/pdf" \
  -F "message={\"type\":\"document\",\"to\":\"5511999999999\",\"caption\":\"Contrato\",\"fileName\":\"contrato.pdf\",\"mimeType\":\"application/pdf\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

8. Enviar opções por texto

Use texto com opções numeradas quando precisar de um fluxo confiável de escolha. O cliente responde com 1, 2 ou com o nome da opção.

curl -X POST \
  -H "x-api-key: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"type\":\"text\",\"to\":\"5511999999999\",\"text\":\"Olá! Como podemos ajudar?\\n\\nResponda com uma das opções:\\n1 - Financeiro\\n2 - Suporte\\n\\nVocê também pode responder Financeiro ou Suporte.\"}" \
  "https://snodr.com/api/integration/instances/INSTANCE_ID/send-message"

9. Listar os grupos da instância

Liste os grupos em que a instância participa e copie o jid (termina em @g.us) para usar no campo to de uma mensagem de grupo.

curl -H "x-api-key: SUA_API_KEY" "https://snodr.com/api/integration/instances/INSTANCE_ID/groups"

O que cada endpoint faz na prática

`GET /api/integration/me`

Confirma que a API Key é válida e mostra os dados básicos da conta reconhecida.

`GET /api/integration/instances`

Lista apenas as instâncias vinculadas à conta da API Key, para você descobrir qual id usar.

`POST /api/integration/instances/:instanceId/send-message`

Envia texto, imagem ou documento usando a instância informada. Mídias aceitam URL pública em JSON ou upload multipart; payloads antigos apenas com `to` e `text` continuam aceitos.

`GET /api/integration/instances/:instanceId/groups`

Lista os grupos do WhatsApp em que a instância participa, retornando o `jid`, o nome (`subject`) e a quantidade de participantes de cada grupo — use o `jid` no campo `to` para enviar mensagens a esse grupo.

Dica para Postman

Se preferir Postman, copie o comando `curl`, importe na ferramenta e ajuste a API Key, o `INSTANCE_ID`, o número `to` e os campos específicos do tipo escolhido.

Ponto mais importante

O envio depende de uma instância conectada. Se você ainda não conectou o WhatsApp pelo QR Code no painel, Abrir instâncias e conclua isso antes.

Observabilidade

A tela Uso da API registra status, tipo, origem da mídia, MIME, tamanho, código do erro e `messageId`, sem armazenar o conteúdo da mensagem ou a URL completa. Abrir Uso da API

Como tratar falhas comuns da integração

Formato da resposta de erro

As rotas `/api/integration/*` retornam erros com um código estável para facilitar tratamento automático.

{
  "error": {
    "code": "INSTANCE_NOT_CONNECTED",
    "message": "A mensagem só pode ser enviada quando a instância estiver conectada.",
    "details": {
      "instanceId": "INSTANCE_ID"
    }
  }
}

Códigos mais comuns

MISSING_API_KEYHTTP 401

A requisição chegou sem credencial.

Envie a chave em `x-api-key` ou `Authorization: Bearer <key>`.
O que fazer

Adicione a API Key no header da requisição.

curl -H "x-api-key: SUA_API_KEY" /api/integration/me
INVALID_API_KEYHTTP 401

A API Key não existe, está errada ou foi excluída.

Gere uma nova chave no painel ou confira se a chave usada não foi revogada.
O que fazer

Confira se copiou a chave completa ou gere uma nova API Key no painel.

Authorization: Bearer wapp_live_...
ACCOUNT_INACTIVEHTTP 403

A conta vinculada à API Key está inativa.

Regularize a conta antes de tentar novas chamadas.
O que fazer

Ative ou regularize a conta antes de chamar a API novamente.

Acesse Minha área > Meu plano para revisar o estado da conta.
MISSING_TOHTTP 400

O envio foi chamado sem telefone de destino.

Informe o telefone de destino em formato internacional no campo `to`.
O que fazer

Envie o campo `to` com DDI e DDD, apenas números.

{ "type": "text", "to": "5511999999999", "text": "Olá!" }
MISSING_TEXTHTTP 400

O envio foi chamado sem texto.

Informe o conteúdo da mensagem no campo `text`.
O que fazer

Envie o campo `text` com o conteúdo da mensagem.

{ "type": "text", "to": "5511999999999", "text": "Pedido confirmado." }
UNSUPPORTED_MESSAGE_TYPEHTTP 400

O campo `type` contém um valor não suportado.

O tipo informado ainda não faz parte do contrato público.
O que fazer

Use `text`, `image` ou `document` no campo `type`.

{ "type": "image", "to": "5511999999999", "url": "https://cdn.exemplo.com/foto.jpg" }
MULTIPART_REQUIREDHTTP 415

Uma mensagem de mídia foi enviada como JSON sem URL.

Imagem e documento enviados como JSON precisam do campo `url`.
O que fazer

Informe uma URL pública ou envie os campos `file` e `message` como multipart.

{ "type": "document", "to": "5511999999999", "url": "https://cdn.exemplo.com/arquivo.pdf" }
INVALID_MULTIPARTHTTP 400

O upload contém campos extras, partes demais ou estrutura inválida.

O formulário aceita somente um arquivo e um campo de metadados.
O que fazer

Envie exatamente um arquivo no campo `file` e o JSON no campo `message`.

-F "file=@foto.jpg" -F "message={\"type\":\"image\",\"to\":\"5511999999999\"}"
FILE_TOO_LARGEHTTP 413

O upload excede `INTEGRATION_MEDIA_MAX_FILE_SIZE_BYTES`.

O arquivo ultrapassou o limite de upload da integração.
O que fazer

Reduza o arquivo ou use mídia por URL dentro do limite configurado.

Limite padrão: 15 MiB
REMOTE_MEDIA_DISABLEDHTTP 403

O envio por URL remota está desabilitado no serviço.

O ambiente do WhatsApp não está autorizado a baixar mídia por URL.
O que fazer

Habilite mídia remota no serviço ou utilize upload quando ele estiver disponível.

MEDIA_REMOTE_URL_ENABLED=true
REMOTE_MEDIA_ADDRESS_NOT_ALLOWEDHTTP 400

A URL aponta ou redireciona para um endereço não permitido.

A proteção contra SSRF bloqueou o endereço resolvido pela URL.
O que fazer

Use uma URL pública HTTPS que não resolva para rede local ou privada.

Evite localhost, 127.0.0.1 e endereços de rede privada.
MEDIA_TYPE_MISMATCHHTTP 415

A inspeção do arquivo detecta divergência de MIME.

O tipo declarado não corresponde ao conteúdo real do arquivo.
O que fazer

Confira o MIME e a extensão declarados ou remova declarações incorretas.

Um PNG não deve ser declarado como application/pdf.
INVALID_FILE_NAMEHTTP 400

O campo `fileName` tenta incluir diretórios.

O nome do documento não pode conter caminho.
O que fazer

Use um nome simples, sem diretórios ou caminhos relativos.

Use contrato.pdf, não ../contrato.pdf.
BAILEYS_LEADER_REQUIREDHTTP 503

O roteamento não alcança a réplica líder do runtime.

A requisição atingiu uma réplica que não lidera a sessão do WhatsApp.
O que fazer

Tente novamente; se persistir, acione o suporte com horário e instância.

Consulte Uso da API e informe o messageId ou código do erro.
INSTANCE_NOT_FOUNDHTTP 404

A instância informada não pertence à conta autenticada.

Liste `/instances` novamente e use uma instância vinculada à conta da API Key.
O que fazer

Liste as instâncias novamente e use o `id` retornado por `/instances`.

GET /api/integration/instances
INSTANCE_NOT_CONNECTEDHTTP 409

A instância existe, mas não está conectada.

Conecte o WhatsApp pelo QR Code antes de enviar mensagens.
O que fazer

Volte ao painel, abra a instância e conecte o WhatsApp pelo QR Code.

Depois de conectar, repita o POST /send-message.
RATE_LIMITEDHTTP 429

A API Key excedeu o limite de chamadas por minuto.

Aguarde o tempo indicado em `Retry-After` antes de tentar novamente.
O que fazer

Aguarde o tempo indicado pelo header `Retry-After` e tente novamente.

Retry-After: 23
UPSTREAM_ERRORHTTP 5xx/4xx

O serviço interno de WhatsApp não conseguiu concluir a operação.

Tente novamente. Se persistir, use o log de uso da API para acionar suporte.
O que fazer

Tente novamente depois de alguns segundos e confira o log de uso da API.

Use Uso da API para copiar horário, instância e código do erro.