Pular para o conteúdo

API — Eventos de Conversão

Endpoint pra registrar eventos de conversão vindos do seu site, plugin, app ou integração. Cada evento:

  • Acha (ou cria) um Contact automaticamente baseado em email / phone_number / identifier
  • Popula first_touch_attribution e latest_touch_attribution no Contact (UTMs + click IDs)
  • Cria uma Activity do tipo conversion na timeline do contato
  • Dispara o evento conversion_event.created no app.smart — workflows e Pipeline Automations podem reagir (ex: disparar Meta CAPI, atribuir a um agente, mover deal de fase)
  • Aparece na tela Conversões (menu Marketing → Captação → Conversões)

É o mesmo endpoint que o Plugin WordPress oficial usa pra mandar leads pro CRM.


Há duas formas de chamar — escolha conforme o cenário:

POST /api/v1/accounts/{account_id}/conversion_events
Header: api_access_token: <token de um agente>

Use quando você controla o backend (plugin, integração server-side, webhook). Token de agente tem permissão limitada (não acessa Settings/Billing) — mais seguro se vazar.

POST /public/api/v1/inboxes/{website_token}/conversion_events

Use quando o evento parte do navegador do visitante (form de site, click WhatsApp, scroll-tracking). Cria 1 inbox tipo “Website” no CRM só pra ter um website_token público que não dá acesso a admin.


{
"conversion_identifier": "lead-formulario-contato",
"email": "[email protected]",
"phone_number": "+5511999999999",
"name": "Ana Silva",
"identifier": "user-987",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "crm-whatsapp-jun26",
"utm_term": "crm whatsapp",
"utm_content": "anuncio-headline-A",
"click_ids": {
"fbc": "fb.1.1717.IwAR0xxx",
"fbp": "fb.1.1717.123456789",
"gclid": "Cj0KCQjwxxxx",
"fbclid": "IwAR0xxx"
},
"platform": "wordpress",
"occurred_at": "2026-06-22T14:30:00Z",
"value": 487.00,
"unique_per_contact": false,
"fields": {
"nome": "Ana Silva",
"email": "[email protected]",
"telefone": "(11) 99999-9999",
"empresa": "Tech Solutions",
"dor": "Perdendo leads por falta de follow-up",
"tamanho_time": "6-15"
},
"custom_attributes": {
"form_name": "Formulário de contato — Página inicial",
"page_url": "https://meusite.com.br/contato"
}
}
{
"event_id": 69172,
"contact_id": 38197,
"activity_id": 69172,
"status": "processed"
}

status tem três valores possíveis:

statusO que aconteceu
processedEvento registrado
duplicate_skippedunique_per_contact: true e aquele contato já tinha convertido nesse identificador. Volta o id do evento anterior
blockedO identificador foi barrado na tela de Conversões. Nada entra — nem o contato

CampoTipoObrigatórioO que é
conversion_identifierstringsimSlug único do evento. Eventos com o mesmo identifier são agrupados na tela de Conversões. Ex: lead, schedule, quote, purchase, cf7-form-1, lead-contato-home
platformstringnãoOrigem (api, wordpress, web, system, import, etc.). Default api. Lista válida: ver SOURCES no model Activity
occurred_atISO8601nãoQuando o evento aconteceu. Default now()
valuenúmeronãoValor monetário do evento (R$). Útil pra Purchase, mas pode marcar Lead também
unique_per_contactbooleannãoSe true, o mesmo conversion_identifier só conta 1 vez por contato (resto vira duplicate_skipped). Default false

Não precisa de contact_id — o app.smart acha ou cria automaticamente. Forneça pelo menos UM destes:

CampoComo é usado
emailMatch exato (case-insensitive). Se não achar, cria contact novo
phone_numberNormaliza pra E.164 (+5511999999999). Match via PhoneNormalizer
identifierID externo (seu sistema). Match exato
contact_idNúmero do contato no CRM, quando você já o conhece (o plugin do WordPress usa isso no clique de WhatsApp). Dispensa e-mail e telefone
nameNome do contato (preenchido só se vazio na ficha existente)

Se vier email + phone + name, todos são enriquecidos no contato existente (não sobrescreve dados já preenchidos).

Tudo aqui é gravado em Contact.first_touch_attribution (1ª vez) e Contact.latest_touch_attribution (sempre). Daí o SendMetaCapiEventService lê na hora de disparar Meta CAPI server-side.

CampoO que é
utm_source / utm_medium / utm_campaign / utm_term / utm_contentUTM padrão Google Analytics
click_ids.fbcCookie _fbc gerado pelo Meta Pixel — essencial pra Meta CAPI
click_ids.fbpCookie _fbp gerado pelo Meta Pixel — essencial pra Meta CAPI
click_ids.gclidGoogle Ads click ID — fechamento Google Ads Enhanced Conversions
click_ids.fbclidMeta click ID (URL param)
click_ids.gbraid / wbraid / msclkidOutros click IDs (TikTok, Bing, etc.)

Quando vc manda dados de um form, jogue tudo em fields como pares chave-valor. Esses campos aparecem na tela de Conversões em “Campos detectados”, e você pode mapear cada um pra:

  • contact.email / contact.name / contact.phone_number (popula a ficha do contato)
  • custom_attribute.X (vira atributo personalizado)

O mapeamento é lembrado — uma vez que você mapeia fields.empresa → custom_attribute.empresa, os próximos eventos com esse identifier aplicam o mapeamento automático.

Diferente de fields, esses vão direto pro contact.custom_attributes (sem passar por mapeamento). Use pra metadados que você quer que apareçam na ficha:

  • form_name — nome legível do formulário
  • page_url — URL onde o form foi enviado
  • lead_source — qualquer rótulo de origem

Exemplo 1 — Form de contato (server-side, plugin WP-style)

Seção intitulada “Exemplo 1 — Form de contato (server-side, plugin WP-style)”
Terminal window
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversion_events" \
-H "Content-Type: application/json" \
-H "api_access_token: SEU_TOKEN" \
-d '{
"conversion_identifier": "lead-contato-home",
"email": "[email protected]",
"phone_number": "+5511999999999",
"name": "Ana Silva",
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "crm-whatsapp-jun26",
"platform": "wordpress",
"click_ids": {
"fbp": "fb.1.1717.123456789",
"fbc": "fb.1.1717.IwAR0xxx",
"gclid": "Cj0KCQjwxxxx"
},
"fields": {
"nome": "Ana Silva",
"email": "[email protected]",
"telefone": "(11) 99999-9999",
"empresa": "Tech Solutions",
"mensagem": "Preciso saber se atendem clínicas"
},
"custom_attributes": {
"form_name": "Contato — Página inicial",
"page_url": "https://meusite.com.br/"
}
}'

Exemplo 2 — Lead via browser (endpoint público, sem token)

Seção intitulada “Exemplo 2 — Lead via browser (endpoint público, sem token)”

Quando o evento parte direto do navegador do visitante, você usa website_token (criado em uma caixa de entrada do tipo Site no CRM) — assim o token público não dá acesso a nada além de registrar conversão.

// Roda no navegador do visitante — dispara e esquece
fetch('https://app.smart2.com.br/public/api/v1/inboxes/SEU_WEBSITE_TOKEN/conversion_events', {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
conversion_identifier: 'lead',
email: form.email.value,
phone_number: form.telefone.value,
name: form.nome.value,
utm_source: getUtm('utm_source'),
utm_medium: getUtm('utm_medium'),
utm_campaign: getUtm('utm_campaign'),
click_ids: {
fbp: getCookie('_fbp'),
fbc: getCookie('_fbc'),
gclid: getUtm('gclid')
},
platform: 'web',
fields: {
empresa: form.empresa.value,
dor: form.dor.value
},
custom_attributes: {
form_name: 'Form pocket WhatsApp',
page_url: location.href
}
})
});
Terminal window
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversion_events" \
-H "Content-Type: application/json" \
-H "api_access_token: SEU_TOKEN" \
-d '{
"conversion_identifier": "purchase",
"email": "[email protected]",
"value": 7490.00,
"unique_per_contact": false,
"platform": "system",
"custom_attributes": {
"produto": "iPhone 15 Pro 256GB",
"external_id": "PED-2026-1287"
}
}'

Quando o evento entra, o workflow conversion_event.created pode disparar send_meta_capi_event (Purchase) automaticamente — Meta recebe server-side com fbc/fbp/UTMs já capturados no first_touch.


O fluxo completo de atribuição funciona assim:

  1. Visitante chega no seu site com ?utm_source=google&gclid=xxx
  2. Form/script captura UTMs + cookies _fbc/_fbp (gerados pelo Meta Pixel no browser)
  3. Você posta conversion_events com email, utm_* e click_ids
  4. CRM cria/atualiza Contact com first_touch_attribution
  5. CRM dispara conversion_event.created
  6. Workflow no CRM (configurado pelo admin) chama send_meta_capi_event com Lead
  7. SendMetaCapiEventService faz SHA-256 do email/phone, lê fbc/fbp do attribution, e posta pra graph.facebook.com/v21.0/{pixel_id}/events
  8. Meta recebe o evento server-side — bypass iOS/AdBlock

Pra configurar: ver Meta CAPI no manual.


Crie um Workflow no CRM com:

  • Gatilho: conversion_event.created
  • Condição (opcional): conversion_identifier igual a lead (ou outro)
  • Ação: send_meta_capi_event — escolha o pixel e configure:
    • Nome do evento Meta: Lead (ou Purchase, Schedule, Contact — nomes padrão da Meta, não confundir com o conversion_identifier do CRM)
    • Valor: usar value do evento se existir
    • PII: o serviço pega automaticamente do contact (email/phone → SHA-256)

Você pode encadear outras ações: atribuir a um agente, criar deal, mover deal de fase, etc.


Onde os eventos aparecem: menu Marketing → seção Captação → Conversões.

Cada conversion_identifier único vira uma linha com:

  • Total de eventos
  • Contatos únicos
  • Data do primeiro / último evento
  • UTM breakdown (quantos vieram de cada utm_source)
  • Lista de atividades + contatos

Clicando em um identifier, você acessa a aba Mapeamento — onde os fields que vc mandou aparecem como “Campos detectados” e você mapeia pra contact.email, contact.name, custom_attribute.X.


Lista de valores aceitos no campo platform:

api · form · web · widget · system · import · manual · whatsapp · facebook · ig · instagram · google · wordpress · email · landing_page · site

Qualquer outro valor derruba a chamada com 422. O padrão, quando você não manda nada, é api.


HTTPCausaComo resolver
401Token inválido ou ausente (caminho autenticado)Conferir o api_access_token
404O website_token não bate com nenhuma caixa (caminho público)Conferir o token na caixa do tipo Site
422 — Source is not included in the listplatform fora da listaUse um valor da lista acima
422 — outrosCampo inválidoLer a resposta

A resposta de erro vem em dois formatos diferentes, dependendo do tipo:

{ "error": "You are not authorized to do this action" }
{ "message": "Source is not included in the list", "attributes": ["source"] }

Não existe um objeto errors com a mensagem por campo. Veja convenções.