Contatos
Liste, busque, crie, atualize e exclua os contatos da sua loja pela API.
Um contato é um cliente com número de WhatsApp. Cada número aparece uma vez só na organização, e cada contato tem uma única conversa com a loja.
O contato
{
"id": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f",
"organizationId": "0d1e2f3a-4b5c-4d6e-8f70-819203a4b5c6",
"storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
"waId": "5511987654321",
"name": "Mariana Costa",
"phone": "+5511987654321",
"email": "mariana@email.com",
"document": null,
"city": "São Paulo",
"properties": { "modelo_celular": "iPhone 13" },
"avatarUrl": null,
"status": "active",
"tags": ["vip"],
"lastMessageAt": "2026-10-30T14:05:40.000Z",
"lastInboundAt": "2026-10-30T14:02:11.000Z",
"marketingOptedOutAt": null,
"createdAt": "2026-09-12T10:00:00.000Z",
"spent": [{ "currency": "BRL", "total": 468890 }]
}| Campo | O que é |
|---|---|
phone | O número, como foi gravado. É para ele que as mensagens saem |
waId | O número no WhatsApp, só dígitos. É por ele que as mensagens do cliente chegam ao contato certo |
status | active (cliente), lead ou unresolved (não resolvido) |
properties | Os campos personalizados da sua organização, pela chave |
lastInboundAt | A última mensagem do cliente. Menos de 24 horas atrás: dá para enviar mensagem livre |
marketingOptedOutAt | Preenchido quando o cliente pediu para não receber marketing |
spent | Quanto o contato já gastou, somando os pedidos não cancelados, um item por moeda (em centavos) |
GET /contacts
Lista os contatos, do mais novo para o mais antigo. Acesso: chave secreta (leitura).
| Parâmetro | Descrição |
|---|---|
search | Parte do nome, sem diferenciar maiúsculas nem acentos (joao encontra "João") |
status | active, lead ou unresolved |
page, pageSize | Paginação: padrão 50, máximo 100 |
curl "https://vamo.ai/api/v1/contacts?search=mariana&status=active" \
-H "Authorization: Bearer sk_live_SUA_CHAVE"Resposta 200
{
"data": [
{ "id": "2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f", "name": "Mariana Costa", "phone": "+5511987654321", "status": "active", "spent": [{ "currency": "BRL", "total": 468890 }] }
],
"pagination": { "page": 1, "pageSize": 50, "total": 1 }
}A busca é só pelo nome. Para achar um contato pelo telefone, guarde no seu sistema o id que o Vamo devolveu ao criá-lo.
GET /contacts/:id
Um contato pelo ID. Acesso: chave secreta (leitura). Responde 404 not_found (Contact not found) se ele não existe, é de outra organização ou o ID não é um UUID.
curl https://vamo.ai/api/v1/contacts/2c9d8e7f-6a5b-4c3d-9e2f-1a0b9c8d7e6f \
-H "Authorization: Bearer sk_live_SUA_CHAVE"POST /contacts
Cria um contato. Acesso: chave secreta com Leitura e escrita.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome do cliente |
phone | string | Sim | Número no formato internacional, com +: +5511987654321 |
storeId | string (UUID) | Sim | A sua loja (veja GET /stores) |
waId | string | Não | Só dígitos. Padrão: o phone sem o + |
status | string | Não | active, lead ou unresolved. Padrão: lead |
tags | string[] | Não | Etiquetas: até 50, cada uma com até 50 caracteres |
avatarUrl | string | Não | Link http(s) de uma foto |
curl -X POST https://vamo.ai/api/v1/contacts \
-H "Authorization: Bearer sk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"name": "Rafael Souza",
"phone": "+5521998877665",
"storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
"tags": ["site"]
}'Resposta 201
{
"data": {
"id": "3d0e9f8a-7b6c-4d5e-8f1a-2b3c4d5e6f70",
"storeId": "7b1e2c3d-4a5f-4b6c-8d7e-9f0a1b2c3d4e",
"waId": "5521998877665",
"name": "Rafael Souza",
"phone": "+5521998877665",
"status": "lead",
"tags": ["site"],
"lastInboundAt": null,
"createdAt": "2026-10-31T13:40:00.000Z"
}
}Dispara o webhook contact.created.
Telefone sempre com + e código do país
O phone precisa estar no formato internacional (+, código do país e o número, de 7 a 15 dígitos, sem espaços nem traços): 21998877665 ou +55 21 99887-7665 respondem 400 validation_error. É nesse formato que POST /templates/send procura o contato. Cada número de WhatsApp (waId) existe uma vez só na organização: criar de novo um número que já existe responde 409 contact_exists, com o contactId do contato que já existe.
| Status | code | Quando |
|---|---|---|
400 | validation_error | Falta name, phone ou storeId, ou um deles tem formato inválido |
404 | not_found | Store not found: a loja não é da sua organização |
409 | contact_exists | Já existe um contato com esse número. contactId diz qual |
Aceita Idempotency-Key (veja Idempotência).
Um contato criado pela API ainda não tem janela de 24 horas aberta: a primeira mensagem para ele precisa ser um modelo.
PATCH /contacts/:id
Altera um contato. Mande só o que muda. Acesso: chave secreta com Leitura e escrita.
| Campo | Descrição |
|---|---|
name | Nome |
phone | Número para onde as mensagens saem, no formato internacional (+5521998877665). Não muda o waId |
status | active, lead ou unresolved |
tags | Substitui a lista inteira de etiquetas |
avatarUrl | Link http(s) da foto, ou null para tirar |
curl -X PATCH https://vamo.ai/api/v1/contacts/3d0e9f8a-7b6c-4d5e-8f1a-2b3c4d5e6f70 \
-H "Authorization: Bearer sk_live_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{ "status": "active", "tags": ["site", "comprou"] }'Responde 200 com o contato completo e dispara contact.updated. Sem nenhum desses campos no corpo: 400 validation_error (No valid fields to update). Outros campos (como storeId, email ou properties) são ignorados.
DELETE /contacts/:id
Exclui o contato e a conversa dele, com todo o histórico de mensagens. Acesso: chave secreta com Leitura e escrita.
curl -X DELETE https://vamo.ai/api/v1/contacts/3d0e9f8a-7b6c-4d5e-8f1a-2b3c4d5e6f70 \
-H "Authorization: Bearer sk_live_SUA_CHAVE"Resposta 200
{ "data": { "success": true } }Dispara contact.deleted com { "contactId": "…" }. Não tem volta.
| Status | Quando |
|---|---|
404 | not_found: Contact not found |
409 | contact_has_orders: o contato tem pedidos. Pedidos são registro financeiro e ficam guardados, então o contato não pode ser excluído |
Muitos contatos de uma vez
Para importar até 10.000 contatos numa requisição, use POST /bulk/contacts.