Pular para o conteúdo

Exemplo — Etiquetar e segmentar contatos

Cenário: você quer organizar a base de contatos por comportamento, origem ou perfil pra disparar campanhas direcionadas, automações, ou atribuir filas de atendimento diferentes. A API tem 3 ferramentas pra isso:

FerramentaPra que serve
LabelsMarcação livre tipo tag (lead, vip, inadimplente) — aparece visualmente no contato
Custom AttributesCampos personalizados estruturados (cpf, plano, data_aniversario, valor_compras_total)
SegmentsGrupos dinâmicos baseados em regras (compradores no último mês, inadimplentes) ou listas estáticas (importação BlackFriday 2026)
CasoFerramenta
”Esse é um lead novo”Label lead
”Esse cliente é VIP”Label vip
”CPF do cliente é X”Custom attribute cpf
”Plano contratado é Pro”Custom attribute plano
”Quero atingir todos que compraram em maio”Segment dinâmico baseado em filtro
”Quero atingir essa lista específica que importei”Segment estático (Lista)
Terminal window
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/contacts/4521/labels" \
-H "api_access_token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"labels": ["lead", "site", "interesse-pro"]
}'

Importante: este endpoint sobrescreve todas as labels atuais. Se o contato já tinha labels que você quer manter, busque primeiro e mescle:

import requests
HEADERS = {'api_access_token': SMART_TOKEN, 'Content-Type': 'application/json'}
BASE = f"https://app.smart2.com.br/api/v1/accounts/{ACCOUNT}/contacts/{CONTACT_ID}"
# 1. Buscar labels atuais
current = requests.get(f"{BASE}/labels", headers=HEADERS).json()['payload']
# 2. Mesclar e enviar
novos = list(set(current + ['vip', 'recompra']))
requests.post(f"{BASE}/labels", headers=HEADERS, json={'labels': novos})
Terminal window
curl -X GET "https://app.smart2.com.br/api/v1/accounts/1/labels" \
-H "api_access_token: SEU_TOKEN"

Labels novas são criadas automaticamente ao aplicar no contato — não precisa cadastrar antes. Mas se quiser pré-criar com cor:

Terminal window
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/labels" \
-H "api_access_token: SEU_TOKEN" \
-d '{ "title": "vip", "description": "Cliente premium", "color": "#FFD700" }'
Terminal window
curl -X PATCH "https://app.smart2.com.br/api/v1/accounts/1/contacts/4521" \
-H "api_access_token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"custom_attributes": {
"cpf": "123.456.789-00",
"plano": "Pro",
"data_aniversario": "1985-04-23",
"valor_compras_total": 4870.00,
"ultima_compra": "2026-05-28"
}
}'

Antes de usar via API, o atributo precisa estar definido na conta (em Configurações → Custom Attributes do painel). Atributos que aparecem na resposta do contato mas não estão definidos ficam guardados mas não aparecem na UI.

Para listar definições atuais:

Terminal window
curl -X GET "https://app.smart2.com.br/api/v1/accounts/1/custom_attribute_definitions" \
-H "api_access_token: SEU_TOKEN"

Listas são manuais — você adiciona contatos explicitamente:

Terminal window
# 1. Criar a lista (uma vez) — os campos vão dentro de "segment"
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/segments" \
-H "api_access_token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"segment": {
"name": "Importação BlackFriday 2026",
"segment_type": "list"
}
}'
# Resposta: { "payload": { "id": 17, ... } }
# 2. Acrescentar contatos — a ação é add_contacts
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/segments/17/add_contacts" \
-H "api_access_token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "contact_ids": [4521, 4522, 4523] }'

Para tirar da lista, POST .../segments/17/remove_contacts com os mesmos contact_ids. Para ver quem está dentro, GET .../segments/17/members.

Segmentos dinâmicos são computados — você define o filtro, e o app.smart calcula os contatos que se encaixam:

Terminal window
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/segments" \
-H "api_access_token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"segment": {
"name": "Compradores VIP",
"segment_type": "dynamic",
"query": {
"payload": [
{ "attribute_key": "labels", "filter_operator": "contains",
"values": ["vip"], "query_operator": "and" },
{ "attribute_key": "valor_compras_total", "attribute_model": "custom_attribute",
"filter_operator": "is_greater_than", "values": [1000] }
]
}
}
}'

Dois detalhes que derrubam a chamada: o operador é is_greater_than, com o prefixo is_, e o query_operator vai em minúsculo (and, or). Veja a lista em convenções.

Contatos passam a aparecer no segmento automaticamente quando atendem aos critérios. Não dá pra adicionar manualmente em segmento dinâmico.

Fluxo realista de e-commerce:

def processar_primeira_compra(contact_id, pedido):
# 1. Marcar como cliente (não mais só lead)
labels_atuais = get_contact_labels(contact_id)
novas_labels = [l for l in labels_atuais if l != 'lead'] + ['cliente']
set_contact_labels(contact_id, novas_labels)
# 2. Preencher dados estruturados
requests.patch(f"{BASE}/contacts/{contact_id}", headers=HEADERS, json={
'custom_attributes': {
'primeira_compra': pedido['data'],
'valor_primeira_compra': pedido['valor'],
'origem_aquisicao': pedido.get('utm_source', 'direto'),
'plano_inicial': pedido.get('plano')
}
})
# 3. Se compra > R$ 1000, vira VIP
if pedido['valor'] >= 1000:
labels_vip = list(set(novas_labels + ['vip']))
set_contact_labels(contact_id, labels_vip)
# 4. Entrar na lista de boas-vindas (lista estática)
requests.post(f"{BASE}/segments/17/add_contacts", headers=HEADERS, json={
'contact_ids': [contact_id]
})

Se você manda "VIP" e depois "vip", vira duas labels diferentes na UI. Padronize minúsculo sempre.

Se definiu valor_compras_total como number no painel mas mandar "4870.00" (string), a interface mostra mal. Sempre mande o tipo correto:

  • number, currency, percent → número, não string
  • date → "2026-05-28"
  • checkbox → true / false
  • list → exatamente uma das opções cadastradas

E a chave precisa ser a attribute_key de um campo que existe. Chave errada não dá erro: grava e some de todo filtro, segmento e relatório.

Segmento dinâmico não atualiza retroativamente em massa

Seção intitulada “Segmento dinâmico não atualiza retroativamente em massa”

Quando você cria segmento dinâmico, o cálculo inicial pode demorar (até 30s pra bases grandes). Não confie na contagem imediata — espere o last_computed_at atualizar.