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_attributionelatest_touch_attributionno Contact (UTMs + click IDs) - Cria uma Activity do tipo
conversionna timeline do contato - Dispara o evento
conversion_event.createdno 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.
Endpoints
Seção intitulada “Endpoints”Há duas formas de chamar — escolha conforme o cenário:
Autenticado (servidor → CRM)
Seção intitulada “Autenticado (servidor → CRM)”POST /api/v1/accounts/{account_id}/conversion_eventsHeader: 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.
Público (browser → CRM, sem token de admin)
Seção intitulada “Público (browser → CRM, sem token de admin)”POST /public/api/v1/inboxes/{website_token}/conversion_eventsUse 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.
Payload completo
Seção intitulada “Payload completo”{ "conversion_identifier": "lead-formulario-contato", "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", "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" }}Resposta
Seção intitulada “Resposta”{ "event_id": 69172, "contact_id": 38197, "activity_id": 69172, "status": "processed"}status tem três valores possíveis:
status | O que aconteceu |
|---|---|
processed | Evento registrado |
duplicate_skipped | unique_per_contact: true e aquele contato já tinha convertido nesse identificador. Volta o id do evento anterior |
blocked | O identificador foi barrado na tela de Conversões. Nada entra — nem o contato |
Identificação do evento
Seção intitulada “Identificação do evento”| Campo | Tipo | Obrigatório | O que é |
|---|---|---|---|
conversion_identifier | string | sim | Slug ú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 |
platform | string | não | Origem (api, wordpress, web, system, import, etc.). Default api. Lista válida: ver SOURCES no model Activity |
occurred_at | ISO8601 | não | Quando o evento aconteceu. Default now() |
value | número | não | Valor monetário do evento (R$). Útil pra Purchase, mas pode marcar Lead também |
unique_per_contact | boolean | não | Se true, o mesmo conversion_identifier só conta 1 vez por contato (resto vira duplicate_skipped). Default false |
Identificação do contato
Seção intitulada “Identificação do contato”Não precisa de contact_id — o app.smart acha ou cria automaticamente. Forneça pelo menos UM destes:
| Campo | Como é usado |
|---|---|
email | Match exato (case-insensitive). Se não achar, cria contact novo |
phone_number | Normaliza pra E.164 (+5511999999999). Match via PhoneNormalizer |
identifier | ID externo (seu sistema). Match exato |
contact_id | Nú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 |
name | Nome 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).
Atribuição (UTMs + Click IDs)
Seção intitulada “Atribuição (UTMs + Click IDs)”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.
| Campo | O que é |
|---|---|
utm_source / utm_medium / utm_campaign / utm_term / utm_content | UTM padrão Google Analytics |
click_ids.fbc | Cookie _fbc gerado pelo Meta Pixel — essencial pra Meta CAPI |
click_ids.fbp | Cookie _fbp gerado pelo Meta Pixel — essencial pra Meta CAPI |
click_ids.gclid | Google Ads click ID — fechamento Google Ads Enhanced Conversions |
click_ids.fbclid | Meta click ID (URL param) |
click_ids.gbraid / wbraid / msclkid | Outros click IDs (TikTok, Bing, etc.) |
fields (campos do formulário pra mapear)
Seção intitulada “fields (campos do formulário pra mapear)”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.
custom_attributes (metadados do contexto)
Seção intitulada “custom_attributes (metadados do contexto)”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áriopage_url— URL onde o form foi enviadolead_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)”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 esquecefetch('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 } })});Exemplo 3 — Purchase (deal fechado)
Seção intitulada “Exemplo 3 — Purchase (deal fechado)”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.
Ligando com Meta CAPI
Seção intitulada “Ligando com Meta CAPI”O fluxo completo de atribuição funciona assim:
- Visitante chega no seu site com
?utm_source=google&gclid=xxx - Form/script captura UTMs + cookies
_fbc/_fbp(gerados pelo Meta Pixel no browser) - Você posta
conversion_eventscomemail,utm_*eclick_ids - CRM cria/atualiza Contact com
first_touch_attribution - CRM dispara
conversion_event.created - Workflow no CRM (configurado pelo admin) chama
send_meta_capi_eventcomLead SendMetaCapiEventServicefaz SHA-256 do email/phone, lê fbc/fbp do attribution, e posta pragraph.facebook.com/v21.0/{pixel_id}/events- Meta recebe o evento server-side — bypass iOS/AdBlock
Pra configurar: ver Meta CAPI no manual.
Workflow conversion_event.created
Seção intitulada “Workflow conversion_event.created”Crie um Workflow no CRM com:
- Gatilho:
conversion_event.created - Condição (opcional):
conversion_identifierigual alead(ou outro) - Ação:
send_meta_capi_event— escolha o pixel e configure:- Nome do evento Meta:
Lead(ouPurchase,Schedule,Contact— nomes padrão da Meta, não confundir com oconversion_identifierdo CRM) - Valor: usar
valuedo evento se existir - PII: o serviço pega automaticamente do contact (email/phone → SHA-256)
- Nome do evento Meta:
Você pode encadear outras ações: atribuir a um agente, criar deal, mover deal de fase, etc.
A tela de Conversões
Seção intitulada “A tela de Conversões”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.
platform — sources válidos {#sources-validos}
Seção intitulada “platform — sources válidos {#sources-validos}”Lista de valores aceitos no campo platform:
api · form · web · widget · system · import · manual · whatsapp · facebook · ig · instagram · google · wordpress · email · landing_page · siteQualquer outro valor derruba a chamada com 422. O padrão, quando você não manda nada, é api.
Erros comuns
Seção intitulada “Erros comuns”| HTTP | Causa | Como resolver |
|---|---|---|
401 | Token inválido ou ausente (caminho autenticado) | Conferir o api_access_token |
404 | O 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 list | platform fora da lista | Use um valor da lista acima |
422 — outros | Campo inválido | Ler 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.
Próximos passos
Seção intitulada “Próximos passos”- Capturar lead via form do site — exemplo de ponta a ponta
- Plugin WordPress — usa esse endpoint nativamente, sem dev
- Meta CAPI no manual — configurar o pixel
- Webhooks — receber notificação quando um evento entra