Contatos (API)
Criar, consultar, filtrar e corrigir contatos — e aplicar etiquetas.
Listar e filtrar
curl "https://www.scalacrm.com/api/v1/contacts?origin=ads&created_after=2026-08-01T00:00:00Z" \
-H "Authorization: Bearer sk_live_…"
| filtro | exemplo |
|---|---|
phone | 5551999998888 (aceita com ou sem o nono dígito) |
email | maria@empresa.com |
search | maria — busca em nome, e-mail e (com ≥4 dígitos) telefone |
origin | ads, organic, import, manual, api |
tag_id | só contatos com a etiqueta |
company_id / owner_user_id | por empresa ou responsável |
created_after / created_before | data ISO |
updated_after | data ISO — "o que mudou desde a última sincronização" |
qualified | true — só os marcados como qualificados |
limit / cursor | ver paginação |
origin=adsé mais esperto do que parece. Ele considera lead de anúncio quem temsource='ads'ou referral de anúncio gravado — porque lead de Lead Ads às vezes chega com o referral e sem o source. É a mesma régua do filtro "De anúncio" da tela de Contatos, então API e CRM nunca discordam sobre o mesmo lead.
Consultar um contato
curl https://www.scalacrm.com/api/v1/contacts/3f9a… \
-H "Authorization: Bearer sk_live_…"
Vem com todos os números do contato e o card ativo no funil — que é o que a automação precisa para decidir entre criar e mover, sem uma segunda chamada.
{
"ok": true,
"contact": { "id": "3f9a…", "name": "Maria", "wa_id": "5551999998888", "source": "ads", … },
"identities": [{ "wa_id": "5551999998888", "is_primary": true }],
"active_card": { "id": "8b1c…", "stage_id": "7c2b…", "stage_name": "Em conversa" }
}
Criar
curl -X POST https://www.scalacrm.com/api/v1/contacts \
-H "Authorization: Bearer sk_live_…" \
-H "Idempotency-Key: form-2026-08-05-0042" \
-H "Content-Type: application/json" \
-d '{
"phone": "5551999998888",
"name": "Maria Silva",
"email": "maria@empresa.com",
"utm": { "utm_source": "google", "utm_campaign": "institucional" }
}'
Resposta: { "ok": true, "contact_id": "3f9a…", "created": true }.
created: false significa que o telefone já existia — os campos vazios foram completados, os preenchidos ficaram como estavam.
Não cria card no funil. É diferente do endpoint antigo, que criava por padrão. Aqui os dois recursos são independentes: para colocar o lead no funil, chame
POST /v1/cardsescolhendo a etapa. Nada acontece que você não tenha pedido.
Lead de anúncio (Lead Ads, click IDs, campos do formulário)
O POST /v1/contacts aceita os mesmos blocos de atribuição do endpoint antigo:
{
"phone": "5551999998888",
"name": "Maria Silva",
"utm": { "utm_source": "meta", "utm_medium": "conjunto-x", "utm_campaign": "captacao" },
"lead_ads": {
"leadgen_id": "1234567890",
"form_id": "111",
"ad_id": "222",
"ad_name": "Criativo A",
"campaign_name": "Captação agosto"
},
"click_ids": { "fbclid": "IwAR…" },
"note": "Lead do Facebook Lead Ads",
"custom_fields": { "leads_por_dia": "10 a 20" }
}
lead_ads.leadgen_idé o identificador mais forte para a Meta atribuir a conversão de volta ao formulário (Conversion Leads) — sempre envie quando o lead vier de Lead Ads.click_idsaceitafbclid,gclid,gbraidewbraid, sempre crus (a plataforma monta o formato final no envio da conversão).- Com
utm,lead_adsouclick_idspresentes, o contato nasce com origem Anúncio — é o que dispara os eventos de conversão configurados na conta. notevira uma nota no contato, só na criação (o retry da automação não duplica).custom_fieldssó preenche chaves já criadas em Configurações → Preferências; chave desconhecida volta emignored_fields, nunca é descartada calada.tag_idsaplica etiquetas já na criação (liste-as comGET /v1/tags); idempotente — repetir não duplica.
Corrigir
curl -X PATCH https://www.scalacrm.com/api/v1/contacts/3f9a… \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{ "name": "Maria Silva Souza", "custom_fields": { "cnpj": "12345678000190" } }'
Campos personalizados só aceitam chaves já criadas em Configurações → Preferências. Chave desconhecida volta em ignored_fields — a API não inventa campo, e também não descarta calada.
O PATCH também corrige atribuição (utm e click_ids) — aqui a semântica é sobrescrever (é correção explícita; null limpa), diferente do POST, que só completa o que está vazio.
Qualificar o lead
curl -X PATCH https://www.scalacrm.com/api/v1/contacts/3f9a… \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{ "qualified": true }'
É o mesmo efeito do botão "Qualificar" da tela: marca o lead no CRM e dispara o evento QualifiedLead para as plataformas de anúncio configuradas na conta — com o mesmo dedupe (1 evento por contato, para sempre; repetir a chamada não reenvia). Opcional: qualified_value_cents manda um valor junto; sem ele, vale o valor do card ativo no funil.
Efeito externo real. Esse evento alimenta a otimização das campanhas do cliente na Meta/Google. Só qualifique por automação quando o critério for confiável — qualificar todo mundo ensina o algoritmo errado.
Etiquetas
# quais existem na conta
curl https://www.scalacrm.com/api/v1/tags -H "Authorization: Bearer sk_live_…"
# etiquetar
curl -X POST https://www.scalacrm.com/api/v1/contacts/3f9a…/tags \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{ "tag_id": "5d3e…" }'
# desetiquetar
curl -X DELETE "https://www.scalacrm.com/api/v1/contacts/3f9a…/tags?tag_id=5d3e…" \
-H "Authorization: Bearer sk_live_…"
As duas operações são idempotentes: etiquetar quem já está etiquetado (ou remover quem já não está) devolve sucesso.
Para criar uma etiqueta nova, POST /v1/tags com { "name": "Cliente VIP" }. Nome repetido devolve a existente em vez de duplicar.
