/integrations/external/leads; oportunidades usam /integrations/external/deals. Todas as chamadas exigem Authorization: Bearer SUA_CHAVE e operam na empresa da chave. O usuário que criou a chave é o ator das operações e o responsável padrão quando responsible_id é omitido.
Criar e evitar duplicidades
title é obrigatório e aceita até 150 caracteres. Se stage_id for omitido, a API utiliza a primeira etapa do funil principal correspondente. visibility assume 0: leads aceitam 0 (privado) ou 1 (time); oportunidades também aceitam 2 (público).
responsible_id recebe o ID de um usuário da empresa. Se o usuário informado existir, mas estiver inativo ou arquivado, a criação não falha: o registro é atribuído ao usuário master da conta e recebe uma nota automática explicando a substituição. Um usuário inexistente ou de outra empresa retorna 400. Essa substituição vale apenas para a criação; no PUT, um responsável inativo retorna 400.
Contatos pertencem à pessoa. Para cadastrar e associar uma pessoa, envie person.name e person.contacts. Para vincular pessoas existentes, envie persons_id como uma lista de objetos com person_id. No lead, phone e email no primeiro nível são rejeitados com 400.
201:
/deals e, quando necessário, inclua value, expected_close_date, temperature (1, 2 ou 3) e primary_person_id.
A deduplicação de pessoa e a idempotência resolvem situações diferentes:
- Na criação,
person.avoid_duplicate: truecomduplicate_check_typespreenchido procura uma pessoa da empresa que corresponda a qualquer contato dos tipos indicados. Reutiliza a primeira correspondência e acrescenta contatos faltantes. O nome, documentos e outros dados enviados não substituem os da pessoa reutilizada. Telefones consideram variantes brasileiras com e sem DDI55. x-idempotency-keyidentifica a tentativa lógica de criar o lead ou a oportunidade. Também é possível enviaridempotency_keyno body, com até 255 caracteres; o header preenchido tem prioridade. Repetições de uma tentativa já concluída retornam o mesmo registro. Uma tentativa ainda em processamento retorna409. Use a mesma chave para repetir uma chamada que ficou sem resposta e outra chave para uma nova criação. A chave vale por chave de integração e é compartilhada entre leads e oportunidades.
409: corrija a requisição e envie uma nova chave. Isso acontece, por exemplo, quando a etapa, a tag, a pessoa, a organização ou a origem informada não existe, quando falta um campo personalizado obrigatório ou quando há erro ao gravar seguidores ou nota. Erros de validação do corpo, de consentimento e de responsável ocorrem antes disso e não consomem a chave.
Os tipos de contato são 0 WhatsApp, 1 e-mail, 2 celular, 3 telefone, 4 Instagram, 5 Facebook, 6 LinkedIn e 7 outros. Telefones (tipos 0, 2 e 3) devem ter 10 ou 11 dígitos, com DDD e sem o DDI 55; os caracteres não numéricos são removidos antes da validação. O tipo 1 precisa ser um e-mail válido. A pessoa também aceita documents, address e addresses. Consulte os schemas das rotas para formatos, tipos de documento e campos de endereço.
Origem, rastreio e consentimento
Para informar uma origem cadastrada manualmente, usecrm_lead_source_id. O campo de entrada lead_source é rejeitado tanto em leads quanto em oportunidades.
Quando crm_lead_source_id é enviado, ele define a origem exibida no registro. Sem ele, vale a origem do tracker ativo indicado por marketing.wegly_code e, por último, a origem textual em marketing.wegly_source ou marketing.utm_source. Se o tracker e crm_lead_source_id forem enviados juntos, o tracker continua vinculado à aquisição, mas a origem retornada em lead_source ou deal_source e usada nos filtros é a de crm_lead_source_id.
A origem textual busca uma origem ativa pelo ID ou pelo nome e cria uma quando o nome ainda não existe; um texto em formato de UUID que não corresponda a uma origem ativa não cria origem. wegly_source tem prioridade sobre utm_source. IG, em qualquer combinação de maiúsculas e minúsculas, é tratado como a origem Instagram e não cria outra origem.
marketing.url_conversion preenche parâmetros de rastreio ausentes no objeto, incluindo parâmetros Wegly/UTM, gclid, fbclid, oppref e obref. Valores informados explicitamente têm prioridade. utm_medium é preservado. O contrato também aceita fbc, fbp, client_ip_address, client_user_agent e ga_client_id.
measurement_consent no primeiro nível é o campo canônico e aceita GRANTED, DENIED ou UNSPECIFIED. O valor deve representar a decisão efetiva do contato. Na criação, a omissão usa GRANTED; no PUT, a omissão preserva o valor existente.
O alias legado marketing.measurement_consent e o parâmetro measurement_consent em marketing.url_conversion continuam aceitos. Valores conflitantes retornam 400 antes de qualquer mutação. Um valor desconhecido na URL, parâmetros repetidos divergentes ou uma URL malformada que contenha a chave são tratados como UNSPECIFIED.
Sem consentimento efetivo GRANTED, a API remove obref e suas ocorrências na query da URL e descarta o fragmento da URL. A revogação também sanitiza o histórico. Alterar apenas o consentimento, enviar marketing: {} ou somente valores vazios não cria um novo registro de aquisição.
No PUT, marketing corrige a aquisição atual do registro em vez de criar outra: os campos enviados substituem os valores atuais, os omitidos são preservados e null limpa o campo. Uma aquisição nova só é criada quando o registro ainda não tem nenhuma. crm_lead_source_id: null remove a origem do registro e da aquisição atual.
Nas respostas, measurement_consent contém a decisão efetiva. O campo marketing_lead_source no detalhe representa o snapshot ativo de aquisição mais recente, que pode ser diferente do snapshot utilizado como compatibilidade para resolver o consentimento.
Atualizar dados e associações
UsePUT /leads/{id} ou PUT /deals/{id} com o UUID do registro. title continua obrigatório, mesmo quando a intenção é alterar outro campo. Campos opcionais omitidos são preservados. A exceção é custom_fields: quando enviado com itens, substitui todas as respostas do registro, então reenvie o conjunto completo.
persons_id adiciona participantes, e delete: true remove participantes existentes. Remover uma pessoa que não participa do registro é ignorado; em leads, um person_id que não existe retorna 404. organization_id: null remove a organização atual. Em leads ganhos ou perdidos, essas duas remoções retornam 404, e as demais alterações do corpo já terão sido aplicadas. Para cadastrar uma organização, envie organization.name e os demais dados; para associar uma existente, envie seu organization_id. Não envie a criação de organização e um ID de organização juntos.
No PUT, person sempre cadastra uma nova pessoa e a torna a principal; em oportunidades, primary_person_id pode indicar outra pessoa como principal. A deduplicação só ocorre na criação. Para associar alguém já cadastrado, use persons_id.
O PUT retorna um resumo da alteração. Em leads, inclui id, code, title, quality_rating, quality_reason, status, lost_reason_description, measurement_consent e value. Em oportunidades, inclui os mesmos campos de identificação, qualificação, status e consentimento, além de won_reason_description, sem value. Consulte o GET de detalhe para ler as associações após a atualização.
No PUT de oportunidade, expected_close_date: null limpa a previsão de fechamento. tags e primary_person_id também podem ser enviados; as tags informadas são acrescentadas às existentes. value é ignorado quando a oportunidade negocia por produtos ou por proposta, porque o valor passa a ser calculado pelos itens. Para indicar ganho, use status: 2:
status não preenche datas automaticamente: envie won_date ou lost_date quando quiser registrá-las. A mudança de status pelo PUT gera o webhook deal.updated, e não deal.won ou deal.lost; consulte os eventos de webhook.
proposal_deadline_starts_on confirma a data-base do cronograma da proposta principal. Aceita uma data civil entre 1980-01-01 e 2100-12-31 somente na requisição que muda o status para ganho; em uma oportunidade que já está ganha, retorna 400. Quando omitida, um cronograma existente recebe a data civil do ganho no fuso do cronograma. Os detalhes e exemplos do cronograma estão nas rotas de propostas.
Campos personalizados e seguidores
Para enviarcustom_fields, use uma lista de objetos com id da definição do campo e value, option_id ou option_ids, conforme seu tipo. Consulte /integrations/external/custom-fields para descobrir os campos configurados. Na criação, todos os campos personalizados obrigatórios da entidade precisam ser enviados; a falta de um deles retorna 400. Campos do tipo arquivo não podem ser preenchidos por estas rotas. Campos temporais usam formatos locais canônicos, sem Z nem offset:
Na criação,
followers recebe uma lista com user_id, role_id e notes opcional de até 1.000 caracteres. note adiciona uma nota inicial com content obrigatório e is_pinned opcional; o conteúdo aceita texto simples ou HTML, que é higienizado. Seguidores e nota são processados antes da resposta de criação, mas depois que o registro já foi gravado: se um deles falhar, a API retorna erro e o lead ou a oportunidade permanece criado. Nesse caso, consulte o registro antes de tentar de novo. Webhooks e notificações podem ser entregues de forma assíncrona.
Depois da criação, gerencie seguidores pelas rotas específicas:
O POST recebe
user_id, role_id e notes opcional. O usuário e a função precisam estar ativos e pertencer à empresa. Adicionar um seguidor existente atualiza sua função e observações; adicionar um seguidor removido reativa o vínculo. Em leads, essas rotas só funcionam enquanto o lead está aberto: em um lead ganho ou perdido, retornam 404.
Listagem, filtros e retorno de detalhe
As listagens usamskip e take; envie take explicitamente para limitar a página. O retorno é { "total": ..., "records": [...] } e projection_context nas consultas completas. count_only=true retorna somente total e records: [].
responsible_ids, created_by, excluded_ids, partner_ids, follower_ids, only_followed_by_me, icp_ids, without_icp, pontuação e qualificação, stagnation_status, abandoned e filtros de resposta do cliente no WhatsApp. O valor only_followed_by_me usa o criador da chave como referência.
Filtros de listas aceitam valores separados por vírgula ou parâmetros repetidos. custom_field_filters recebe um array serializado em JSON e codificado na query, com objetos contendo id e value, option_id ou option_ids.
Oportunidades também aceitam lead_created_from, lead_created_to, only_without_expected_close_date e crm_gain_reason_ids. order_by difere entre os recursos: leads aceitam name, created_at, last_activity_at, quality_rating e score; oportunidades aceitam title, created_at, last_activity_at, quality_rating, score, value, expected_close_date e temperature.
Os filtros de marketing podem usar attribution_mode. Para selecionar o recorte correto, consulte a descrição dos parâmetros na referência da rota. A origem exibida em lead_source e deal_source é a origem efetiva: a da aquisição mais recente e, na falta dela, a gravada no registro. Os filtros crm_lead_source_id e without_lead_source usam essa mesma origem, assim como lead_sources quando attribution_mode não é enviado; lead_sources aceita IDs, nomes de origem e o valor unknown. O filtro tags aceita apenas IDs de tags. O histórico de aquisição fica separado no detalhe.
GET /leads/{id} e GET /deals/{id} aceitam UUID ou código sequencial. Cada consulta por ID registra uma visualização do criador da chave: views_count aumenta e o registro deixa de aparecer em only_new=true. O detalhe inclui participantes, organização, seguidores, campos personalizados, propostas, qualificação, ICPs, parceiros e os valores comerciais em valuation. projection_context informa o modo de exibição e o horizonte de recorrência usados nos valores projetados; value permanece o valor atual.
O detalhe de lead também retorna deals, com as oportunidades associadas e visíveis. O detalhe de oportunidade retorna products com os produtos diretamente associados à oportunidade; itens de propostas permanecem nas propostas. proposals[].delivery_schedule contém o cronograma calculado. Sem uma data-base confirmada, o cronograma utiliza a data atual como referência de leitura.
Os campos has_channel_chat, channel_chats, has_whatsapp_chat e whatsapp_chats dependem da permissão crm/chats.read da própria chave. Sem ela, as flags são false e as listas são vazias. Nas consultas externas, os campos com nome whatsapp são aliases de compatibilidade da projeção multicanal e podem incluir Instagram.