API

Oportunidades

Consulte project_deals, o modelo atual de oportunidades, ou deals legados mantidos por compatibilidade.

Oportunidades

Uma oportunidade registra uma possível venda no pipeline comercial. Embora o recurso HTTP permaneça em /deals por compatibilidade, existem dois modelos de dados diferentes: project_deal, que é o modelo atual e recomendado, e deal, que é legado.

Use project_deal em novas integrações

deal é o modelo global legado e continua disponível apenas para não quebrar integrações existentes. Para novas integrações, consulte oportunidades por project_id ou pelo pipeline_id de um projeto; esses filtros retornam registros de project_deals.

Diferença entre deal e project_deal

ModeloTabelaSituaçãoEscopoComo consultar
project_dealproject_dealsAtual e recomendadoPertence a um projeto e ao pipeline desse projeto. O lead principal vem de project_leads.Envie project_id ou o pipeline_id de um projeto.
dealdealsLegadoCRM global, sem vínculo com projeto. O cliente principal vem de clients.Omita project_id e pipeline_id, ou envie o pipeline_id de um pipeline global legado.

Os dois modelos são expostos pelo mesmo endpoint /api/v1/deals. O campo scope da resposta elimina a ambiguidade: scope: "project" representa um project_deal; scope: "global" representa um deal legado.

GET /deals

Lista as oportunidades do seu time. Com project_id, consulta project_deals daquele projeto. Com apenas pipeline_id, a API identifica se o funil pertence a um projeto ou ao CRM global legado e aplica o escopo correto. Sem nenhum desses filtros, consulta somente deals legados.

No escopo de projeto, esta rota retorna todos os cards de oportunidade de project_deals, respeitando a paginação. Um cadastro em project_leads que ainda não esteja vinculado a uma oportunidade não é sintetizado como negócio.

Parâmetros de consulta

ParâmetroTipoPadrãoDescrição
pagenumber1Página a retornar.
limitnumber20Itens por página, entre 1 e 100.
statusstringFiltra pelo status armazenado.
phasestringFiltra pela fase do pipeline.
project_iduuidConsulta project_deals do projeto informado. O projeto deve pertencer ao time da chave.
pipeline_iduuidFiltra pelo funil. Sem project_id, também determina se a consulta usa project_deals ou deals legados.
client_iduuidFiltra pelo cliente do CRM global. No escopo de projeto, funciona como alias de lead_id.
lead_iduuidFiltra pelo lead principal no CRM de projeto. No escopo global, funciona como alias de client_id.
responsible_idstringFiltra pelo UUID da pessoa responsável.
sourcestringFiltra pela origem.
min_valuenumberRetorna valores maiores ou iguais ao informado.
max_valuenumberRetorna valores menores ou iguais ao informado.
fromstringData inicial de criação em YYYY-MM-DD.
tostringData final de criação em YYYY-MM-DD.
searchstringBusca parcial no título ou na descrição.
sortstring-created_atCampo de ordenação; prefixe com - para ordem descendente.

Os únicos campos aceitos em sort são title, value, phase, created_at, updated_at e expected_close_date.

curl "https://app.usecolmeia.com/api/v1/deals?status=ativo&min_value=5000&sort=-created_at" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"
Todas as oportunidades de um projeto
curl "https://app.usecolmeia.com/api/v1/deals?project_id=11111111-1111-4111-8111-111111111111&sort=-created_at" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"
Oportunidades de um funil
curl "https://app.usecolmeia.com/api/v1/deals?pipeline_id=22222222-2222-4222-8222-222222222222" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"

Resposta

O exemplo abaixo representa um deal global legado. Ele é resumido; os campos omitidos continuam presentes no objeto.

{
  "success": true,
  "data": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "scope": "global",
      "project_id": null,
      "pipeline_id": "33333333-3333-4333-8333-333333333333",
      "title": "Operação de marketing digital — Acme",
      "description": "Proposta para operação mensal de marketing digital.",
      "value": 8000,
      "currency": "BRL",
      "phase": "proposta",
      "priority": "alta",
      "status": "ativo",
      "probability": 70,
      "expected_close_date": "2026-09-15",
      "source": "indicacao",
      "loss_reason": null,
      "tags": ["marketing"],
      "is_starred": false,
      "client_id": "11111111-1111-4111-8111-111111111111",
      "client": {
        "id": "11111111-1111-4111-8111-111111111111",
        "name": "Acme Serviços Digitais Ltda."
      },
      "responsible_id": "33333333-3333-4333-8333-333333333333",
      "ai_summary": null,
      "ai_win_probability": null,
      "created_at": "2026-08-01T10:30:00.000Z",
      "updated_at": "2026-08-01T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "pages": 1
  }
}

No modelo atual project_deal, a mesma estrutura inclui o lead completo e os contatos vinculados:

Trecho de uma oportunidade de projeto
{
  "id": "22222222-2222-4222-8222-222222222222",
  "scope": "project",
  "project_id": "11111111-1111-4111-8111-111111111111",
  "pipeline_id": "33333333-3333-4333-8333-333333333333",
  "lead_id": "44444444-4444-4444-8444-444444444444",
  "source": "form",
  "attribution": {
    "first": {
      "utm_source": "google",
      "utm_medium": "cpc",
      "utm_campaign": "servicos-b2b",
      "utm_term": "consultoria",
      "utm_content": "anuncio-a"
    }
  },
  "metadata": { "form_id": "form_exemplo" },
  "custom_fields": { "segmento": "enterprise" },
  "lead": {
    "id": "44444444-4444-4444-8444-444444444444",
    "public_id": "le_exemplo",
    "project_id": "11111111-1111-4111-8111-111111111111",
    "full_name": "Maria Silva",
    "email": "maria@empresa-exemplo.test",
    "phone": "+5511999999999",
    "company_name": "Acme Serviços Digitais",
    "customer_source": "landing_page",
    "utm_source": "google",
    "utm_medium": "cpc",
    "utm_campaign": "servicos-b2b",
    "attribution": {
      "first": {
        "utm_term": "consultoria",
        "utm_content": "anuncio-a"
      }
    },
    "metadata": { "form_id": "form_exemplo" },
    "custom_fields": { "cargo": "CEO" },
    "identity": {
      "id": "55555555-5555-4555-8555-555555555555",
      "custom_fields": { "porte": "grande" }
    }
  },
  "contacts": [
    {
      "link_id": "66666666-6666-4666-8666-666666666666",
      "contact_id": "44444444-4444-4444-8444-444444444444",
      "contact_identity_id": "55555555-5555-4555-8555-555555555555",
      "is_primary": true,
      "position": 0,
      "linked_at": "2026-08-01T10:30:00.000Z",
      "contact": {
        "id": "44444444-4444-4444-8444-444444444444",
        "full_name": "Maria Silva",
        "email": "maria@empresa-exemplo.test",
        "phone": "+5511999999999",
        "custom_fields": { "cargo": "CEO" }
      }
    }
  ]
}

Dados retornados

Cada oportunidade inclui os campos comerciais, de captura e de operação disponíveis no seu escopo: IDs, projeto, pipeline, fase, posição, status, prioridade, valor, probabilidade, responsável, snapshots de nome/email/telefone, origem, origin_type, source_path, UTMs, attribution, metadata, custom_fields, checklist, perda, IA e timestamps. Campos que não existem naquele escopo são retornados como null para manter um formato previsível.

  • lead: cadastro principal completo. Em project_deal, vem de project_leads; em deal legado, é o cliente principal e também permanece disponível em client por compatibilidade.
  • contacts: todos os contatos vinculados à oportunidade, ordenados com o principal primeiro. Cada item informa o vínculo e traz o cadastro em contact.
  • identity: identidade compartilhada do contato, incluindo os valores dos campos personalizados de Contato (CRM).
  • attribution: estrutura completa de atribuição. Parâmetros sem coluna dedicada, como utm_term e utm_content, permanecem dentro dessa estrutura.

Campos internos de busca, dígitos normalizados e tokens de confirmação não são expostos.

POST /deals — legado

Cria um deal no CRM global legado. O único campo obrigatório é title. Esta operação existe para compatibilidade; novas integrações devem usar project_deal. A criação de project_deals ainda não é exposta por esta rota pública.

Corpo da requisição

CampoTipoObrigatórioDescrição
titlestringSimTítulo da oportunidade.
descriptionstringNãoDescrição.
valuenumberNãoValor da oportunidade. Na criação, 0 é convertido em null.
phasestringNãoFase do pipeline; o padrão é lead.
prioritystringNãoalta, media ou baixa; o padrão é media.
expected_close_datestringNãoData prevista em YYYY-MM-DD.
probabilitynumberNãoProbabilidade entre 0 e 100.
responsible_idstringNãoUUID da pessoa responsável.
sourcestringNãoOrigem.
client_idstringNãoUUID do cliente vinculado.
tagsarrayNãoLista de tags; quando omitida, inicia vazia.

Na criação, a oportunidade inicia com phase: "lead", priority: "media" e status: "ativo" quando phase e priority não são enviados. O exemplo usa um valor maior que zero porque enviar "value": 0 atualmente resulta em value: null na oportunidade criada.

Idempotência

Você pode enviar o header opcional Idempotency-Key para repetir uma tentativa de criação com segurança. A chave pode ter no máximo 512 caracteres. Para receber o replay, reenvie a mesma chave e o mesmo payload: a primeira criação retorna 201 Created e a repetição idêntica retorna a oportunidade já criada com 200 OK, sem criar um segundo registro.

curl -X POST "https://app.usecolmeia.com/api/v1/deals" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: oportunidade-acme-001" \
  -d '{
    "title": "Operação de marketing digital — Acme",
    "description": "Proposta para operação mensal de marketing digital.",
    "value": 8000,
    "priority": "alta",
    "probability": 70,
    "client_id": "11111111-1111-4111-8111-111111111111",
    "source": "indicacao",
    "tags": ["marketing"]
  }'

Se Idempotency-Key tiver mais de 512 caracteres, a API retorna 400 com o código invalid_idempotency_key. Reutilizar uma mesma chave com um payload diferente gera conflito: o ledger identifica idempotency_conflict e a rota retorna 409 com o código CONFLICT.

Resposta para chave reutilizada com payload diferente (409)
{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "Falha ao criar negócio"
  }
}

O retorno bem-sucedido usa o mesmo objeto de oportunidade mostrado na listagem, dentro de { "success": true, "data": { ... } }.

GET /deals/:id

Retorna uma oportunidade pelo seu UUID, com o mesmo objeto completo da listagem. Para um project_deal, envie project_id ou o pipeline_id do projeto na query string. Sem esse escopo, a rota procura somente um deal legado.

curl "https://app.usecolmeia.com/api/v1/deals/22222222-2222-4222-8222-222222222222" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"
Oportunidade de projeto
curl "https://app.usecolmeia.com/api/v1/deals/22222222-2222-4222-8222-222222222222?project_id=11111111-1111-4111-8111-111111111111" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"

A resposta usa o mesmo formato de oportunidade da listagem. Se o UUID não pertencer ao seu time ou não existir, a API retorna 404 com o código NOT_FOUND.

PUT /deals/:id — legado

Atualiza somente deals do CRM global legado e apenas os campos enviados. Esta rota não atualiza project_deals. Os campos aceitos são title, description, value, phase, priority, status, probability, expected_close_date, responsible_id, source, client_id, tags, is_starred e loss_reason.

Se enviar probability, informe um valor entre 0 e 100. Um corpo JSON sem nenhum campo aceito resulta em 400 com o código VALIDATION_ERROR.

curl -X PUT "https://app.usecolmeia.com/api/v1/deals/22222222-2222-4222-8222-222222222222" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "phase": "proposta",
    "probability": 75,
    "is_starred": true
  }'

DELETE /deals/:id — legado

Arquiva um deal do CRM global legado; esta rota não arquiva project_deals. A operação não remove o registro fisicamente. A resposta confirma status: "arquivado".

curl -X DELETE "https://app.usecolmeia.com/api/v1/deals/22222222-2222-4222-8222-222222222222" \
  -H "Authorization: Bearer ea_live_sua_chave_aqui"
{
  "success": true,
  "data": {
    "id": "22222222-2222-4222-8222-222222222222",
    "status": "arquivado",
    "archived_at": "2026-08-01T11:00:00.000Z"
  }
}