vamobotDocs

Introdução à API

O que dá para fazer com a API do Vamo, a URL base e a sua primeira requisição em menos de 2 minutos.

A API do Vamo liga o seu sistema ao WhatsApp da sua loja. Com ela você envia mensagens e modelos, mantém contatos em dia, acompanha conversas, registra pedidos que baixam o estoque e recebe avisos (webhooks) quando algo muda.

Você quer…Use
Responder um cliente que escreveu nas últimas 24 horasPOST /messages/send
Falar com quem não escreveu (confirmação de pedido, aviso de entrega)POST /templates/send
Sincronizar clientes com o seu CRMContatos e importação em massa
Lançar uma venda feita no balcão ou no site e baixar o estoquePOST /orders
Saber quando uma mensagem foi entregue ou um pedido mudouWebhooks

URL base

Todas as rotas ficam em:

https://vamo.ai/api/v1

A versão faz parte do caminho (/v1). Os exemplos desta seção mostram só o caminho depois da base, por exemplo GET /contacts é https://vamo.ai/api/v1/contacts.

Sua primeira requisição

Crie uma chave

No Vamo, abra Desenvolvedores → Chaves API e clique em Criar chave API. Dê um nome (por exemplo "Teste local"), escolha o tipo Secreta e o acesso Somente leitura. Copie a chave na hora: ela aparece uma única vez.

Só o proprietário, os administradores e os desenvolvedores da organização veem essa página.

Liste dois contatos

curl "https://vamo.ai/api/v1/contacts?pageSize=2" \
  -H "Authorization: Bearer sk_live_SUA_CHAVE"

Leia a resposta

{
  "data": [
    {
      "id": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f",
      "storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
      "name": "Mariana Costa",
      "phone": "+5511987654321",
      "waId": "5511987654321",
      "status": "active",
      "tags": ["vip"],
      "lastInboundAt": "2026-10-30T14:02:11.000Z",
      "createdAt": "2026-09-12T10:00:00.000Z",
      "spent": [{ "currency": "BRL", "total": 468890 }]
    }
  ],
  "pagination": { "page": 1, "pageSize": 2, "total": 148 }
}

Os dados vêm sempre em data. Listas trazem também pagination. Valores em dinheiro vêm em centavos: 468890 é R$ 4.688,90.

Recebeu 401? Confira se o cabeçalho é exatamente Authorization: Bearer <chave>. Os detalhes estão em Autenticação.

Convenções

O quêComo é
FormatoJSON na ida e na volta. Envie Content-Type: application/json nos POST e PATCH
IDsUUID (2c9d8e7f-6a5b-…)
DatasISO 8601 em UTC (2026-10-30T14:02:11.000Z)
DinheiroInteiro em centavos (×100), também para guaranis: Gs. 150.000 vai como 15000000
TelefonesFormato internacional com + e código do país: +5511987654321
Sucesso200 (leitura e alteração), 201 (criação ou envio), 202 (envio em massa aceito)
ErrosSempre { "error": { "code": "…", "message": "…" } } (veja Erros)

Campos desconhecidos no corpo são ignorados. Novos campos podem aparecer nas respostas: não quebre se encontrar um que você não conhece.

Paginação

As listas de contatos, conversas, mensagens de uma conversa, pedidos e modelos são paginadas pela query string:

ParâmetroPadrãoRegra
page1Começa em 1
pageSize50Máximo 100: um valor maior vira 100

page ou pageSize que não são números inteiros positivos respondem 400 validation_error.

A resposta traz pagination.total, o total de itens com os filtros aplicados. Para percorrer tudo, avance page até page * pageSize >= total. As listas vêm do mais recente para o mais antigo (mensagens de uma conversa são a exceção: veja Conversas), e itens criados no mesmo instante saem sempre na mesma ordem, então uma página nunca repete nem pula um item da anterior. Um item criado enquanto você percorre as páginas empurra os outros uma posição: para uma cópia completa, percorra de novo ou use os webhooks.

Lojas, webhooks e o histórico de entregas de um webhook não são paginados.

Limites de requisição

Cada chave pode fazer um número de requisições por minuto, numa janela deslizante (os últimos 60 segundos), conforme o plano da organização:

PlanoRequisições por minuto, por chave
Starter100
Professional1.000
Enterprise1.000 (ou o que estiver no contrato)

Toda rota conta, inclusive as que falham. Um envio em massa conta como uma requisição. Cada chave tem a sua conta: duas chaves da mesma organização não dividem o limite.

Toda resposta traz:

CabeçalhoO que é
X-RateLimit-LimitO limite por minuto da chave
X-RateLimit-RemainingQuantas requisições ainda cabem agora
X-RateLimit-ResetQuando a janela tem espaço de novo, em segundos Unix

Passou do limite: 429 com o código rate_limited, o cabeçalho Retry-After (em segundos) e retryAfterSec no corpo. Espere esse tempo e tente de novo.

{ "error": { "code": "rate_limited", "message": "Too many requests. Try again in 12 seconds.", "retryAfterSec": 12 } }

O WhatsApp também tem limites próprios nos envios: quando a Meta segura os envios do seu número, o envio responde 429 com o código whatsapp_rate_limited e Retry-After. Veja Erros.

Idempotência

Uma falha de rede no meio de um envio deixa a dúvida: a mensagem saiu? Para repetir sem medo, mande o cabeçalho Idempotency-Key com um valor único por operação (até 200 caracteres; um UUID serve) nestas rotas:

curl -X POST https://vamo.ai/api/v1/messages/send \
  -H "Authorization: Bearer sk_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1042-aviso-envio" \
  -d '{ "contactId": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f", "content": "Seu pedido saiu para entrega!" }'
SituaçãoO que acontece
Primeira requisição com a chaveRoda normalmente. Uma resposta de sucesso (2xx) fica guardada por 24 horas
Repetição com a mesma chave e o mesmo corpoNada é enviado nem criado de novo: volta a mesma resposta, com o cabeçalho Idempotent-Replayed: true
A mesma chave com outro corpo (ou outra rota)422 idempotency_key_reused
Repetição enquanto a primeira ainda roda409 idempotency_key_in_progress com Retry-After: 1
A primeira terminou em erro (4xx ou 5xx)A chave é liberada: a repetição roda de novo

A chave vale só dentro da sua organização e por 24 horas. POST /orders também aceita Idempotency-Key, com regras próprias.

Chamadas pelo navegador (CORS)

As rotas /v1 aceitam chamadas de qualquer origem (com a pré-verificação OPTIONS do navegador), então dá para chamá-las direto de uma página web. Os cabeçalhos X-RateLimit-* e Retry-After ficam visíveis para o seu JavaScript. As respostas vêm com Cache-Control: no-store: nenhum navegador ou cache guarda os dados. Faça isso só com uma chave publicável (pk_live_…), que lê apenas a loja e os modelos. Uma chave secreta no navegador fica visível para qualquer visitante.

Próximos passos

Nesta página