Contatos e leads
Sincronize os contatos com o seu sistema, troque as etiquetas, mande as datas das réguas, informe a idade conferida por você, leia os leads e atenda o pedido do titular para apagar os dados.
contactsPacoteIntegrações (R$ 49 por mês, por conta). Sem ele, a API responde 403 plan_not_allowed.| Rota | O que faz |
|---|---|
GET /v1/contacts | Os contatos, na ordem da última alteração (para sincronizar). |
PUT /v1/contacts/{contact}/tags | Troca as etiquetas do contato. |
PATCH /v1/contacts/{contact} | Grava o aniversário, a última visita e o próximo horário (as datas das réguas). |
PUT /v1/contacts/{contact}/age | A empresa informa a idade que conferiu. |
GET /v1/leads | Um lead por contato, com o histórico de pedidos. |
DELETE /v1/contacts/{contact}?bot_id= | Pedido do titular: apaga os dados do contato. |
{contact} é o endereço do contato (ctc_…, phone:…, wa:…, ig:… ou ext:…).
GET/v1/contacts
Na ordem da última alteração: guarde o updated_at do último e use em since na próxima vez. consent.marketing é o aceite de novidades no WhatsApp (none, granted, declined ou revoked); consent.opted_out, o que a pessoa pediu para não receber (marketing, utility ou all); age_confirmed, o 18+ (null: ninguém perguntou); birthday, last_visit_at e appointment_at, as datas das réguas.
curl "https://boavoz.com/api/v1/contacts?limit=20" \
-H "Authorization: Bearer $BOAVOZ_API_KEY"{
"data": [
{
"id": "ctc_9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"channel": "whatsapp",
"name": "Ruan",
"email": null,
"phone": "5511999990000",
"whatsapp_user_id": null,
"instagram_id": null,
"external_id": null,
"tags": [
"vip"
],
"consent": {
"marketing": "granted",
"opted_out": []
},
"age_confirmed": null,
"birthday": "10-21",
"last_visit_at": "2026-10-05T15:00:00.000Z",
"appointment_at": null,
"dates": {
"renovacao_do_plano": "2027-03-10"
},
"first_inbound_at": "2026-10-02T13:10:44.000Z",
"last_inbound_at": "2026-10-19T14:58:02.117Z",
"created_at": "2026-10-02T13:10:44.000Z",
"updated_at": "2026-10-19T14:58:02.117Z"
}
],
"next_cursor": null
}| Parâmetro | Regra | Erro |
|---|---|---|
limit, cursor | Paginação: limit de 1 a 100 (padrão 50) e o next_cursor anterior. | 400 limit, cursor |
bot_id | Só os contatos deste chatbot. | 403 forbidden_scope |
channel | widget, whatsapp ou instagram. | 400 channel |
tag | Só os com esta etiqueta (até 30 caracteres). | 400 tag |
since | Só os alterados desde a data (ISO 8601). | 400 since |
PUT/v1/contacts/{contact}/tags
Troca todas as etiquetas (lista vazia apaga). Com ext:, vale para todos os contatos do chatbot com aquele id externo.
curl -X PUT "https://boavoz.com/api/v1/contacts/ctc_9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d/tags" \
-H "Authorization: Bearer $BOAVOZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"tags": [
"vip",
"postman"
]
}'{
"data": [
{
"id": "ctc_9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
"tags": [
"vip",
"postman"
]
}
]
}| Campo | Regra | Erro |
|---|---|---|
bot_id | Obrigatório: o chatbot do contato. | 403 forbidden_scope |
tags | Lista de textos, até 20 (vírgula e ponto e vírgula viram espaço). Contato que não existe: 404. | 400 tags |
PATCH/v1/contacts/{contact}
As datas que as réguas do WhatsApp usam: o aniversário, a última visita ou compra (“faz tempo que você não vem” e o pós-atendimento) e o próximo horário marcado (o lembrete antes do horário). O campo que não vem não muda; null apaga. Pelo telefone (phone:…), cria o contato do WhatsApp que ainda não existe: o horário costuma chegar antes da primeira mensagem. Com ext:, vale para todos os contatos do chatbot com aquele id externo. A resposta traz os contatos alterados.
curl -X PATCH "https://boavoz.com/api/v1/contacts/phone:5511999990000" \
-H "Authorization: Bearer $BOAVOZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"birthday": "10-21",
"last_visit_at": "2026-10-05",
"appointment_at": "2026-12-20T14:30:00-03:00"
}'{
"data": [
{
"id": "ctc_9a1b2c3d-4e5f-4a6b-8c7d-0e1f2a3b4c5d",
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"channel": "whatsapp",
"name": "Ruan",
"email": null,
"phone": "5511999990000",
"whatsapp_user_id": null,
"instagram_id": null,
"external_id": null,
"tags": [
"vip",
"postman"
],
"consent": {
"marketing": "granted",
"opted_out": []
},
"age_confirmed": null,
"birthday": "10-21",
"last_visit_at": "2026-10-05T15:00:00.000Z",
"appointment_at": "2026-12-20T17:30:00.000Z",
"dates": {
"renovacao_do_plano": "2027-03-10"
},
"first_inbound_at": "2026-10-02T13:10:44.000Z",
"last_inbound_at": "2026-10-19T14:58:02.117Z",
"created_at": "2026-10-02T13:10:44.000Z",
"updated_at": "2026-10-20T15:00:00.000Z"
}
]
}| Campo | Regra | Erro |
|---|---|---|
bot_id | Obrigatório: o chatbot do contato. | 403 forbidden_scope |
birthday | Mês e dia, MM-DD (ex.: 10-21). A data inteira (AAAA-MM-DD) também vale, mas o ano não é guardado. | 400 birthday |
last_visit_at | A última visita ou compra: data (AAAA-MM-DD) ou data e hora ISO 8601 com fuso. Não pode ser no futuro. | 400 last_visit_at |
appointment_at | O próximo horário marcado: data e hora ISO 8601 com fuso (ex.: 2026-12-20T14:30:00-03:00), até um ano à frente. | 400 appointment_at |
dates | As datas novas das suas réguas (régua personalizada), pela chave de cada uma: { "renovacao_do_plano": "2027-03-10" }. A data é AAAA-MM-DD; null apaga. A chave nasce com a régua que tem a data nova, no painel; as outras chaves do contato ficam. | 400 dates.<chave> |
| Nenhum dos quatro | Mande pelo menos um. | 400 birthday |
| Contato que não existe | Com ctc_, wa:, ig: ou ext:: o contato precisa existir. | 404 not_found |
PUT/v1/contacts/{contact}/age
Para quem vende bebida alcoólica ou remédio: o BoaVoz só mostra esses itens para quem tem 18 anos confirmados. Um “Não” dado pela pessoa no chat sempre vence o que a empresa informar (age_confirmed_source chat). A data de nascimento daqui nunca é guardada; para a régua do aniversário, mande o dia e o mês em birthday.
curl -X PUT "https://boavoz.com/api/v1/contacts/phone:5511999990000/age" \
-H "Authorization: Bearer $BOAVOZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"age_verified": true,
"origin": "Teste pelo Postman"
}'{
"age_confirmed": true,
"age_confirmed_source": "company"
}| Campo | Regra | Erro |
|---|---|---|
bot_id | Obrigatório. | 403 forbidden_scope |
age_verified ou birth_date | age_verified true ou false, ou birth_date (AAAA-MM-DD, no passado). Com os dois, eles precisam bater. | 400 age_verified, birth_date |
origin | Obrigatório: como a idade foi conferida (3 a 300 caracteres). | 400 origin |
GET/v1/leads
Um lead por contato em cada chatbot, do mais antigo para o mais novo: nome, telefone, e-mail, o pedido mais recente (notes) e o histórico (requests). Filtros: bot_id, channel, since (criados desde a data) e updated_since (os que mudaram desde a data: pedido novo ou contato); o webhook lead.updated avisa na hora.
curl "https://boavoz.com/api/v1/leads?limit=20" \
-H "Authorization: Bearer $BOAVOZ_API_KEY"{
"data": [
{
"id": "lead_7f3e2d1c-0b9a-4c8d-9e7f-6a5b4c3d2e1f",
"bot_id": "bot_7c9e6679-7425-40de-944b-e07fc1f90ae7",
"conversation_id": "conv_0e8f5a3c-2b1d-4c6e-9f7a-1d2c3b4a5e6f",
"channel": "whatsapp",
"name": "Ana Souza",
"phone": "5511988887777",
"email": "ana@exemplo.com.br",
"instagram": null,
"notes": "Quer orçamento para 30 pizzas no sábado.",
"requests": [
{
"created_at": "2026-10-19T15:10:00.000Z",
"channel": "whatsapp",
"conversation_id": "conv_0e8f5a3c-2b1d-4c6e-9f7a-1d2c3b4a5e6f",
"text": "Quer orçamento para 30 pizzas no sábado."
}
],
"created_at": "2026-10-19T15:10:00.000Z",
"last_request_at": "2026-10-19T15:10:00.000Z",
"updated_at": "2026-10-19T15:10:00.000Z"
}
],
"next_cursor": null
}DELETE/v1/contacts/{contact}?bot_id=
Para o pedido do titular (LGPD) que você já confirmou: apaga as conversas, os arquivos, os leads e a ficha do contato, põe o número na lista de supressão e emite o webhook contact.deleted. Responde 202 com o request_id na hora; a exclusão roda logo depois e aparece em Segurança, no painel.
curl -X DELETE "https://boavoz.com/api/v1/contacts/phone:5511999990000?bot_id=bot_7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer $BOAVOZ_API_KEY"{
"request_id": "dsr_1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
}contact_suppressed, e nada do contato pode ser recuperado.