Use a base https://botozap.com.br/api/v1 com Authorization: Bearer $BOTOZAP_KEY ou X-API-Key. A Conta é derivada da chave; não envie account_id. Os exemplos mostram o caminho depois desse prefixo.
Um contato pode ter várias oportunidades e demandas independentes do Funil de contatos, que continua funcionando como antes. Encerrar uma conversa não encerra registros de CRM. Retornos e notas das conversas estão em Atendimento pela API; compromissos, em Agenda e Google Calendar.
Permissões, plano e ambiente
| Escopo | Permite |
|---|---|
crm:read | Listar e consultar oportunidades, demandas, histórico, conversas vinculadas, Radar e critérios. |
crm:write | Criar e editar oportunidades e demandas, vincular conversas e configurar critérios do Radar. |
As rotas seguem a disponibilidade do Funil no plano da Conta: sem ele, retornam 403 feature_unavailable. Chaves live e sandbox são aceitas, e cada uma só enxerga contatos e conversas de Contas de canal do próprio ambiente. Um registro de contato do outro ambiente responde 404 not_found. A única exceção é a gravação de critérios do Radar, que exige chave live.
Rotas
| Método | Caminho | Resultado |
|---|---|---|
| GET | /opportunities, /demands | Lista paginada; customer_id obrigatório. |
| POST | /opportunities, /demands | 201 com o registro em data. |
| GET | /{recurso}/{id} | Registro em data. |
| PATCH | /{recurso}/{id} | Registro atualizado; exige expected_version. |
| GET | /{recurso}/{id}/activities | Histórico, 20 itens por página. |
| GET / POST / DELETE | /{recurso}/{id}/conversations | Consultar, criar ou remover vínculos com conversas. |
| GET | /radar | Itens priorizados do Cliente. |
| GET | /radar/stage-rules | Critérios configurados por etapa. |
| PUT | /radar/stage-rules/{stage_id} | Cria ou altera o critério de uma etapa. |
{recurso} é opportunities ou demands. IDs são UUID; um valor malformado retorna 422 invalid_id.
Oportunidades
| Campo | Tipo | Regras |
|---|---|---|
customer_id | UUID | Obrigatório na criação. Cliente do contato; imutável. |
contact_id | UUID | Obrigatório na criação. Contato do mesmo Cliente e do ambiente da chave; imutável. |
title | texto | Obrigatório na criação, 1 a 200 caracteres após remover espaços nas pontas. |
status | enum | open, won, lost. Padrão open. lost exige outcome_reason. |
stage_id | UUID ou null | Etapa do Funil do mesmo Cliente. Mudar a etapa reinicia stage_entered_at. |
owner_user_id | UUID ou null | Membro da Conta (consulte GET /users). |
value_cents | inteiro | Valor em centavos, de 0 a 9007199254740991. Padrão 0. |
currency | texto | Código ISO de 3 letras maiúsculas, como BRL ou USD. Padrão BRL. |
next_step | texto ou null | 1 a 1000 caracteres. |
next_step_at | ISO 8601 ou null | Data com fuso horário. Só é aceita quando há next_step. |
notes | texto ou null | Até 10000 caracteres. |
outcome_reason | texto ou null | 1 a 2000 caracteres. Motivo do ganho ou da perda. |
metadata | objeto | Campos personalizados. Veja as regras abaixo. |
Demandas
| Campo | Tipo | Regras |
|---|---|---|
customer_id, contact_id | UUID | Obrigatórios na criação e imutáveis, como nas oportunidades. |
title | texto | Obrigatório na criação, 1 a 200 caracteres. |
status | enum | open, in_progress, waiting_customer, resolved, closed. Padrão open. |
outcome | enum ou null | resolved, converted, not_applicable, customer_cancelled, lost, no_response. |
due_at | ISO 8601 ou null | Prazo da demanda, com fuso horário. |
opportunity_id | UUID ou null | Oportunidade do mesmo contato e Cliente. |
owner_user_id, next_step, next_step_at, notes, metadata | — | Mesmas regras das oportunidades. |
O desfecho acompanha o estado. Em resolved ou closed, outcome é obrigatório, e resolved só aceita outcome: "resolved". Nos demais estados, outcome precisa ser null: para reabrir uma demanda, envie o novo estado e outcome: null no mesmo PATCH. Combinações inválidas retornam 422 invalid_request.
closed_at é preenchido automaticamente quando a oportunidade sai de open ou a demanda chega a resolved ou closed, e volta a null ao reabrir.
Campos personalizados
metadata segue o formato dos campos de contato: objeto plano, até 32 chaves com letras minúsculas, dígitos e sublinhado (1 a 40 caracteres), valores de texto (até 256 caracteres), número ou booleano, e até 8192 bytes no total. null não é aceito como valor. No PATCH, o objeto enviado substitui o anterior por inteiro: leia o registro, altere as chaves e envie o objeto completo.
Criar
POST /opportunities
{
"customer_id": "UUID-DO-CLIENTE",
"contact_id": "UUID-DO-CONTATO",
"title": "Plano anual",
"value_cents": 129900,
"currency": "BRL",
"next_step": "Enviar proposta",
"next_step_at": "2026-10-01T14:00:00-03:00"
}O contato precisa pertencer ao Cliente informado e ao ambiente da chave. Etapa, responsável ou oportunidade relacionada de outro Cliente, contato ou Conta retornam 422 invalid_request. Campos fora das tabelas acima também são recusados com 422 invalid_request.
A resposta traz o registro completo, incluindo id, status, closed_at, version, created_at, updated_at e last_activity_at. Oportunidades também trazem stage_entered_at.
Editar sem sobrescrever outra alteração
Envie em PATCH apenas os campos que mudam, junto de expected_version com a version lida. Cada alteração incrementa a versão e atualiza last_activity_at.
PATCH /opportunities/{id}
{
"expected_version": 3,
"status": "lost",
"outcome_reason": "Escolheu outro fornecedor"
}- Versão diferente da atual retorna
409 conflictsem aplicar a alteração. Releia e concilie. - Sem
expected_version(inteiro positivo), o corpo é recusado com422 invalid_request. - O corpo é estrito: campo desconhecido,
customer_idoucontact_idretornam422 invalid_request. - Um PATCH só com
expected_versionretorna422 invalid_request.
Listar
GET /opportunities e GET /demands exigem customer_id e aceitam:
| Parâmetro | Valores |
|---|---|
page, per_page | Página a partir de 1; per_page padrão 20, máximo 100. |
contact_id | UUID do contato. |
owner_user_id | UUID ou unassigned. |
status | Um estado do recurso ou active (sem closed_at). Outro valor retorna 422 invalid_status. |
q | Trecho do título, até 200 caracteres. |
stage_id | Só oportunidades: UUID ou none (sem etapa). |
A ordem é do mais recente para o mais antigo. A resposta traz data e meta (page, per_page, total_pages, total_count), além dos headers de paginação. Página além do último resultado retorna lista vazia.
Histórico
GET /{recurso}/{id}/activities?page=N retorna 20 eventos por página, do mais recente para o mais antigo; per_page é ignorado. Cada item contém:
| Campo | Conteúdo |
|---|---|
event_type | crm.opportunity.created, crm.opportunity.updated, crm.demand.created, crm.demand.updated, conversation_linked, conversation_unlinked ou legacy_imported (oportunidade criada a partir do Funil antigo). |
actor_user_id | Pessoa que alterou pelo painel. Alterações feitas pela API ficam com null. |
before_data | Registro antes da alteração; null na criação e nos vínculos. |
after_data | Registro depois da alteração. Nos vínculos, inclui conversation_id. |
id, created_at | Identificador e momento do evento. |
Conversas vinculadas
GET /{recurso}/{id}/conversations lista { conversation_id, created_at }, 20 por página. POST vincula e DELETE desvincula; os dois recebem o mesmo corpo e respondem 200:
POST /demands/{id}/conversations
{ "conversation_id": "UUID-DA-CONVERSA" }
200
{ "data": { "conversation_id": "UUID-DA-CONVERSA", "linked": true } }No DELETE, a resposta traz linked: false. Repetir um vínculo existente ou remover um vínculo ausente não gera erro. A conversa precisa ser do mesmo contato e Cliente do registro (senão, 422 invalid_request) e do ambiente da chave (senão, 404 not_found). Mensagens nas conversas vinculadas contam como atividade para o Radar.
Erros
| Status | Código | Quando |
|---|---|---|
| 400 | invalid_json | Corpo que não é JSON. |
| 403 | feature_unavailable | Plano sem Funil. |
| 403 | sandbox_forbidden | Chave sandbox em PUT /radar/stage-rules/{stage_id}. |
| 404 | not_found | Cliente, registro, contato ou conversa inexistente, de outra Conta ou de outro ambiente. |
| 409 | conflict | Versão obsoleta no PATCH ou no critério do Radar. |
| 422 | invalid_id | UUID malformado no caminho, em customer_id ou em filtros. |
| 422 | invalid_status | Filtro status desconhecido. |
| 422 | invalid_request | Campo inválido ou extra, vínculo de outro Cliente, combinação de estado e desfecho inválida. |
| 422 | invalid_customer, invalid_filters | Radar sem customer_id válido ou com filtro desconhecido. |
| 500 | internal_error | Falha ao consultar o plano ou o banco; tente novamente. |
Radar de acompanhamento
GET /radar?customer_id=UUID exige crm:read e reúne, para um Cliente, o que precisa de ação: oportunidades, demandas, retornos pendentes e compromissos. A leitura não altera registros nem envia mensagens.
| Filtro | Valores |
|---|---|
bucket | critical, at_risk, scheduled |
entity_type | opportunity, demand, return, appointment |
owner_user_id | UUID ou unassigned |
reason | Um motivo da tabela abaixo. |
page, per_page | Padrão 20, máximo 100. |
Filtro com valor desconhecido retorna 422 invalid_filters. Críticos vêm primeiro, depois atenção e programados; dentro de cada grupo, os itens sem data e os de data mais próxima vêm antes. meta.counts traz os totais critical, at_risk e scheduled com os filtros de tipo, responsável e motivo, sem o filtro bucket; meta.total_count considera também o bucket. Páginas além do último resultado retornam lista vazia e preservam os totais.
Tipos de item
entity_type | Entra no Radar |
|---|---|
opportunity | Oportunidade aberta. Usa os critérios da etapa atual. |
demand | Demanda não encerrada. Usa o padrão: 24 h de atenção, 72 h de criticidade, responsável e próximo passo exigidos. |
return | Retorno pendente de uma conversa (ferramentas do Inbox). Exige responsável; o texto do retorno vira título e próximo passo. |
appointment | Compromisso pendente ou confirmado, com régua ativa ou com falha/conflito de sincronização. Exige responsável. |
Um item só aparece quando tem ao menos um motivo ou algo programado; oportunidades e demandas em dia ficam fora da lista.
Motivos
reason | No painel | Quando aparece |
|---|---|---|
unassigned | Sem responsável | Registro sem responsável quando o critério exige. Retornos e compromissos sempre exigem responsável. |
missing_next_step | Próximo passo incompleto | Sem próximo passo com data, quando o critério exige, e sem régua programada ou compromisso futuro vinculado. |
overdue | Retorno ou prazo vencido | Próximo passo, prazo da demanda ou retorno com data vencida. Não se aplica a compromissos. |
stalled_stage | Tempo excedido na etapa | Oportunidade na mesma etapa há mais horas que o prazo de atenção da etapa. |
inactive | Sem atividade recente | Oportunidade ou demanda sem atividade no registro nem mensagem nas conversas vinculadas além do prazo de atenção, sem compromisso futuro nem régua programada. |
automation_failed | Falha na régua | Régua vinculada ao registro falhou. |
automation_overdue | Envio automático atrasado | Envio programado da régua atrasado há mais de 15 minutos. |
automation_paused | Régua pausada | Régua vinculada pausada. |
automation_stopped | Régua interrompida sem retorno definido | Régua interrompida sem próximo passo definido no registro. |
confirmation_pending | Compromisso a confirmar | Compromisso a confirmar: o próprio item ou o próximo compromisso vinculado à oportunidade ou demanda. |
appointment_outcome_missing | Comparecimento não registrado | Compromisso pendente ou confirmado cujo horário já terminou, sem comparecimento registrado. |
calendar_conflict | Conflito com Google Calendar | Compromisso com conflito entre a versão do BotoZap e a do Google Calendar. |
calendar_sync_failed | Falha na sincronização do compromisso | Compromisso cuja sincronização com o Google Calendar falhou. |
Prioridade
bucket | No painel | Regra |
|---|---|---|
critical | Críticos | Motivo overdue, automation_failed, automation_overdue, appointment_outcome_missing, calendar_conflict ou calendar_sync_failed; ou oportunidade/demanda sem atividade, compromisso futuro nem régua programada além do prazo crítico; ou oportunidade na etapa além do prazo crítico. |
at_risk | Precisam de atenção | Qualquer outro motivo. |
scheduled | Programados | Sem motivo, com régua programada, compromisso futuro vinculado, item do tipo appointment ou retorno com data futura. |
Cada item traz id, entity_type, customer_id, contact_id, conversation_id (retornos e compromissos), title, owner_user_id, stage_id, next_step, next_step_at, bucket, reasons (lista), last_activity_at, automation_status, automation_due_at, automation_run_id, automation_error e bucket_priority. Quando uma oportunidade ou demanda sem próximo passo tem um compromisso futuro vinculado, o próximo passo exibido é esse compromisso.
Critérios por etapa
GET /radar/stage-rules?customer_id=UUID lista as etapas configuradas. Etapa sem configuração usa atenção após 24 horas e criticidade após 72 horas, exigindo responsável e próximo passo. O critério vale para as oportunidades da etapa: tempo na etapa e última atividade são avaliados separadamente.
PUT /radar/stage-rules/{stage_id}
{
"customer_id": "UUID-DO-CLIENTE",
"expected_version": 0,
"cold_hours": 48,
"critical_hours": 120,
"require_owner": true,
"require_next_step": false
}cold_hours(atenção): inteiro de 1 a 8760.critical_hours: inteiro de 1 a 26280, maior ou igual acold_hours.- Todos os campos são obrigatórios e o corpo é estrito. Erros de validação retornam
422 invalid_request. - Na primeira configuração, envie
expected_version: 0; depois, a versão consultada. Versão obsoleta retorna409 conflict. - Etapa de outro Cliente retorna
404 not_found.
A gravação exige crm:write e chave live, porque o critério vale para os dois ambientes do Cliente; chave sandbox recebe 403 sandbox_forbidden. A listagem do Radar respeita o ambiente da chave. No painel, qualquer membro da conta altera critérios.
Eventos
Criar ou alterar registros publica crm.opportunity.created, crm.opportunity.updated, crm.demand.created e crm.demand.updated, com before_data e after_data. Consulte o formato em Eventos de webhook.
Os erros comuns de chave, escopo e limite estão em Autenticação. A referência /v1 lista todas as rotas.
