API pública de integração v1

CRM Merge IA — /api/v1/* · Fase 1, 29/09/2026 · documentação completa (com todos os campos e exemplos) em docs/API-V1.md no repositório.

Esta é a porta de entrada pra qualquer sistema do ecossistema se plugar no CRM — telefonia com IA, atendimento WhatsApp/Instagram, ordem de serviço, geração de conteúdo, e o que vier depois. Ela nunca cria conexão com canal de mensageria nenhum: WhatsApp e Instagram continuam geridos pelo Chatwoot. Esta API só recebe eventos e expõe contato/negócio/tarefa.

Autenticação

Toda chamada leva Authorization: Bearer <chave>. Sessão de usuário (cookie) não é aceita aqui, mesmo de um admin logado. A chave é criada na rota interna POST /api/keys (tela Chaves de API, precisa de sessão de admin), que agora aceita um campo opcional sistema (texto livre — ex. telefonia, whatsapp, instagram, os, conteudo).

Escopos

EscopoLibera
v1:eventos:escreverPOST /api/v1/eventos
v1:contatos:lerGET /api/v1/contatos, GET /api/v1/contatos/:id
v1:contatos:escreverPATCH /api/v1/contatos/:id
v1:negocios:lerGET /api/v1/negocios/:id
v1:negocios:escreverPATCH /api/v1/negocios/:id/etapa
v1:tarefas:escreverPOST /api/v1/negocios/:id/tarefas

Erros

Sempre {"erro": "texto legível", "codigo": "CODIGO_MAQUINA"} com o status HTTP correspondente — nunca um 500 silencioso nem um formato diferente rota a rota.

Rate limit

120 requisições/minuto por chave (não por IP). Estourou: 429, codigo: "LIMITE_EXCEDIDO".

POST /api/v1/eventos operação principal

"Algo aconteceu com uma pessoa." Acha (ou cria) o contato pela identidade, acha (ou cria) o negócio, registra o evento no histórico. Escopo: v1:eventos:escrever.

curl -s -X POST https://SEU-DOMINIO/api/v1/eventos \
  -H "Authorization: Bearer crm_xxx..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: call-a1b2c3" \
  -d '{
        "identidade": { "tipo": "whatsapp", "valor": "+55 11 99999-8888" },
        "nome": "João Silva",
        "tipo_evento": "mensagem",
        "resumo": "Perguntou o preço do plano Pro",
        "negocio": { "titulo": "Automação WhatsApp" }
      }'

Resposta 201:

{
  "contato_id": 42,
  "negocio_id": 17,
  "interacao_id": 301,
  "criado_contato": false,
  "criado_negocio": true
}

Normalização de identidade

Idempotência

Header Idempotency-Key (prioridade) ou campo externo_id no corpo. Repetir a mesma chave, com a mesma chave de API, devolve exatamente a mesma resposta sem gravar de novo.

LGPD

Identidade apontando pra contato anonimizado: 409, codigo: "CONTATO_ANONIMIZADO" — nunca recria em silêncio.

GET /api/v1/contatos

Escopo v1:contatos:ler. Com ?identidade_tipo=&identidade_valor=: busca por identidade ({"encontrado": bool, "contato"?}). Sem os dois: lista todos.

GET /api/v1/contatos/:id

Escopo v1:contatos:ler. Ficha completa (contato + negócios + identidades).

PATCH /api/v1/contatos/:id

Escopo v1:contatos:escrever. Campos básicos: nome, empresa, cargo, telefone, email, tipo_cliente, origem.

GET /api/v1/negocios/:id

Escopo v1:negocios:ler. Negócio completo (contato + interações + tarefas + propostas).

PATCH /api/v1/negocios/:id/etapa

Escopo v1:negocios:escrever. Corpo: {etapa?, resultado?, motivo_perda?} — "perdido" exige motivo_perda.

POST /api/v1/negocios/:id/tarefas

Escopo v1:tarefas:escrever. Corpo: {descricao (obrigatório), tipo?, data_prevista?, dono?}.

Auditoria

Toda escrita fica registrada (quando, chave, sistema, rota, id afetado, resultado) — nunca a chave em si nem o corpo da requisição.

Dúvida ou chave nova? Fala com quem administra o CRM — a criação de chave por sistema ainda é manual (POST /api/keys, painel de admin).