Quickstart
Em poucos minutos: contato criado, conversa aberta, mensagem enviada e etiqueta aplicada.
Antes de começar
Seção intitulada “Antes de começar”- O token: avatar → Perfil → Token de acesso. Veja autenticação
- O número da conta: está na URL do painel —
/app/accounts/1/... - O número da caixa de entrada: Configurações → Caixas de entrada, na URL da caixa
Passo 1 — Criar contato
Seção intitulada “Passo 1 — Criar contato”curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/contacts" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Maria Silva", "email": "[email protected]", "phone_number": "+5511999990000", "identifier": "ERP-8842" }'{ "payload": { "contact": { "id": 4521, "name": "Maria Silva", "phone_number": "+5511999990000", "identifier": "ERP-8842" }, "contact_inbox": { "inbox": null, "source_id": null } }}Guarde o id — 4521 aqui. Repare que o contato vem dois níveis abaixo: payload.contact.id.
O telefone precisa vir no formato internacional, com + e o código do país.
Passo 2 — Abrir a conversa
Seção intitulada “Passo 2 — Abrir a conversa”curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversations" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "inbox_id": 3, "contact_id": 4521, "status": "open" }'{ "id": 8821, "inbox_id": 3, "status": "open", "meta": { "sender": { "id": 4521, "name": "Maria Silva" }, "assignee_type": "User" }, "created_at": 1758542400}O id é 8821 — esse é o número que aparece na URL da conversa no painel, e o que você usa nas chamadas seguintes.
Repare no created_at: número, não texto. Conversa usa segundos desde 1970. Veja convenções.
Passo 3 — Mandar a mensagem
Seção intitulada “Passo 3 — Mandar a mensagem”curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversations/8821/messages" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "content": "Oi Maria! Recebi seu pedido e já estou vendo aqui.", "message_type": "outgoing" }'Isso sai de verdade pelo canal da caixa de entrada — chega no WhatsApp, no e-mail, no que for.
| Campo | Para quê |
|---|---|
content | O texto |
message_type | outgoing sai para o cliente; incoming registra algo que ele disse por outro meio |
private | true grava nota interna — fica na conversa, o cliente não vê |
A nota interna é o uso mais comum para integração — avisar o atendente sem falar com o cliente:
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversations/8821/messages" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "content": "Pedido #8842 faturado no ERP.", "private": true }'Passo 4 — Etiquetar
Seção intitulada “Passo 4 — Etiquetar”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-premium"] }'A lista é substituída, não somada: mande sempre todas as etiquetas que o contato deve ficar tendo. Para etiquetar a conversa em vez do contato, o caminho é /conversations/8821/labels.
Etiqueta serve de base para segmento, campanha e relatório — vale usar um punhado de nomes combinados, não inventar um por integração.
Tudo junto, em Python
Seção intitulada “Tudo junto, em Python”import requests
BASE = "https://app.smart2.com.br/api/v1/accounts/1"H = {"api_access_token": "SEU_TOKEN", "Content-Type": "application/json"}
# 1. contator = requests.post(f"{BASE}/contacts", headers=H, json={ "name": "Maria Silva", "phone_number": "+5511999990000", "identifier": "ERP-8842",})r.raise_for_status()contato_id = r.json()["payload"]["contact"]["id"]
# 2. conversar = requests.post(f"{BASE}/conversations", headers=H, json={ "inbox_id": 3, "contact_id": contato_id, "status": "open",})r.raise_for_status()conversa_id = r.json()["id"]
# 3. mensagemrequests.post(f"{BASE}/conversations/{conversa_id}/messages", headers=H, json={ "content": "Oi Maria! Recebi seu pedido e já estou vendo aqui.", "message_type": "outgoing",}).raise_for_status()
# 4. etiquetasrequests.post(f"{BASE}/contacts/{contato_id}/labels", headers=H, json={ "labels": ["lead", "site"],}).raise_for_status()
print(f"contato {contato_id}, conversa {conversa_id}")Tudo junto, em JavaScript
Seção intitulada “Tudo junto, em JavaScript”Do lado do servidor — o token nunca vai ao navegador. Veja CORS.
const BASE = 'https://app.smart2.com.br/api/v1/accounts/1';const H = { api_access_token: process.env.SMART_TOKEN, 'Content-Type': 'application/json',};
async function post(caminho, corpo) { const r = await fetch(`${BASE}${caminho}`, { method: 'POST', headers: H, body: JSON.stringify(corpo), }); if (!r.ok) throw new Error(`${r.status} em ${caminho}: ${await r.text()}`); return r.json();}
async function quickstart() { const { payload } = await post('/contacts', { name: 'Maria Silva', phone_number: '+5511999990000', identifier: 'ERP-8842', }); const contatoId = payload.contact.id;
const conversa = await post('/conversations', { inbox_id: 3, contact_id: contatoId, status: 'open', });
await post(`/conversations/${conversa.id}/messages`, { content: 'Oi Maria! Recebi seu pedido e já estou vendo aqui.', message_type: 'outgoing', });
await post(`/contacts/${contatoId}/labels`, { labels: ['lead', 'site'] });
console.log(`contato ${contatoId}, conversa ${conversa.id}`);}
quickstart().catch(console.error);Conferir no painel
Seção intitulada “Conferir no painel”Abra Contatos, procure por Maria Silva. A ficha mostra as etiquetas e a conversa; a conversa mostra a mensagem que você enviou.
Daqui para onde
Seção intitulada “Daqui para onde”Campos personalizados no contato
Seção intitulada “Campos personalizados no contato”{ "name": "Maria Silva", "custom_attributes": { "cnpj": "12.345.678/0001-90", "plano": "premium" }}A chave precisa ser a de um campo já criado no painel. Chave desconhecida é gravada mas não aparece em lugar nenhum — nem na ficha, nem em filtro, nem em relatório.
Registrar uma conversão com a origem
Seção intitulada “Registrar uma conversão com a origem”É o caminho para lead de site e venda, e o que alimenta a atribuição:
curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversion_events" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "conversion_identifier": "orcamento-site", "email": "[email protected]", "phone_number": "+5511999990000", "name": "Maria Silva", "value": 1200.00, "utm_source": "google", "utm_medium": "cpc", "utm_campaign": "institucional", "landing_page": "https://seusite.com.br/orcamento" }'Veja eventos de conversão.
Passar a conversa para um atendente
Seção intitulada “Passar a conversa para um atendente”curl -X POST "https://app.smart2.com.br/api/v1/accounts/1/conversations/8821/assignments" \ -H "api_access_token: SEU_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "assignee_id": 7 }'Ser avisado em vez de ficar perguntando
Seção intitulada “Ser avisado em vez de ficar perguntando”Se o seu sistema precisa reagir a mensagem nova ou lead novo, webhook é melhor que consultar de tempos em tempos — lendo antes as três limitações dele, que estão logo na abertura da página.
Erros comuns
Seção intitulada “Erros comuns”401 — token ausente, errado, ou com espaço colado junto. Use .strip() no valor que veio da variável de ambiente.
404 na conversa — o número da conta ou da conversa está errado. Lembre que recurso de outra conta também devolve 404, não 403.
422 ao criar contato — a resposta diz o que foi, mas em inglês e tudo numa string:
{ "message": "Email is invalid", "attributes": ["email"] }Repare na chave: é message, e os campos vêm em attributes. Os outros erros usam error. Veja convenções.
A mensagem não chegou no celular — a chamada pode ter dado certo e o canal ter recusado. No WhatsApp, quase sempre é a janela de 24 horas. Confira a conversa no painel: a mensagem aparece lá com o estado de entrega.
Próximos passos
Seção intitulada “Próximos passos”- Convenções — as regras que valem em tudo
- Contatos
- Conversas
- Webhooks
- Exemplo: lead do formulário caindo no CRM