Kanban
O Kanban da TopTalking organiza as conversas em etapas (colunas), como um funil de vendas ou de atendimento. Cada contato está em no máximo uma etapa. As etapas são configuradas no painel em Configurações → Etapas do Kanban.
A etapa com is_final: true (normalmente “Finalizado”) é especial: mover um card para ela finaliza a conversa, igual ao painel.
O objeto etapa
Seção intitulada “O objeto etapa”{ "id": "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11", "object": "stage", "name": "Negociação", "color": "#8b5cf6", "position": 2, "is_final": false}| Campo | Tipo | Descrição |
|---|---|---|
id |
UUID | ID da etapa. Use em stage_id. |
object |
string | Sempre stage. |
name |
string | Nome da coluna. |
color |
string | Cor da coluna no painel (hexadecimal). |
position |
inteiro | Ordem da coluna (0 = primeira). |
is_final |
booleano | Etapa terminal (“Finalizado”). Mover um card para ela finaliza a conversa. |
Nos contatos e nos webhooks, a etapa aparece resumida (id, name, is_final).
Listar etapas
Seção intitulada “Listar etapas”GET/v1/stages
Devolve as etapas na ordem das colunas. Use para descobrir o id de cada etapa antes de mover cards ou filtrar contatos.
Não tem parâmetros. A lista vem inteira numa página (has_more: false).
curl https://platform.toptalking.com.br/v1/stages \ -H "Authorization: Bearer $TOPTALKING_API_KEY"const res = await fetch('https://platform.toptalking.com.br/v1/stages', { headers: { Authorization: `Bearer ${process.env.TOPTALKING_API_KEY}` },});const { data: etapas } = await res.json();const porNome = Object.fromEntries(etapas.map((e) => [e.name, e.id]));// porNome['Negociação'] → "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11"import osimport requests
res = requests.get( "https://platform.toptalking.com.br/v1/stages", headers={"Authorization": f"Bearer {os.environ['TOPTALKING_API_KEY']}"}, timeout=30,)res.raise_for_status()por_nome = {e["name"]: e["id"] for e in res.json()["data"]}# por_nome["Negociação"] -> "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11"Resposta 200
Seção intitulada “Resposta 200”{ "object": "list", "data": [ { "id": "e63d8231-3992-457e-a8b0-d1be2fa591d4", "object": "stage", "name": "Novo lead", "color": "#3b82f6", "position": 0, "is_final": false }, { "id": "5f861a0a-9667-4215-b498-3be9da314b60", "object": "stage", "name": "Em atendimento", "color": "#f59e0b", "position": 1, "is_final": false }, { "id": "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11", "object": "stage", "name": "Negociação", "color": "#8b5cf6", "position": 2, "is_final": false }, { "id": "3c671a88-07fb-4ccc-80db-184be834360c", "object": "stage", "name": "Finalizado", "color": "#22c55e", "position": 3, "is_final": true } ], "has_more": false, "next_cursor": null}Só os gerais: 401 (chave) e 429 (limite por minuto). Veja Erros.
Mover um card
Seção intitulada “Mover um card”Para mover um contato de etapa, use PATCH /contacts/{contact_id} com stage_id:
PATCH/v1/contacts/{contact_id}
| Corpo | Efeito |
|---|---|
{ "stage_id": "<id da etapa>" } |
Move o card para a etapa. |
{ "stage_id": "<id da etapa final>" } |
Move para a etapa final e finaliza a conversa. |
{ "stage_id": null } |
Tira o card de qualquer etapa. |
curl -X PATCH https://platform.toptalking.com.br/v1/contacts/3f1c2b9a-7d4e-4c55-8a0e-1b2c3d4e5f60 \ -H "Authorization: Bearer $TOPTALKING_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "stage_id": "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11" }'async function moverCard(contactId, stageId) { const res = await fetch(`https://platform.toptalking.com.br/v1/contacts/${contactId}`, { method: 'PATCH', headers: { Authorization: `Bearer ${process.env.TOPTALKING_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ stage_id: stageId }), // null tira de qualquer etapa }); const body = await res.json(); if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`); return body; // contato atualizado, com body.stage}
await moverCard('3f1c2b9a-7d4e-4c55-8a0e-1b2c3d4e5f60', '9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11');import osimport requests
def mover_card(contact_id: str, stage_id: str | None) -> dict: res = requests.patch( f"https://platform.toptalking.com.br/v1/contacts/{contact_id}", headers={"Authorization": f"Bearer {os.environ['TOPTALKING_API_KEY']}"}, json={"stage_id": stage_id}, # None tira de qualquer etapa timeout=30, ) body = res.json() if not res.ok: raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}") return body # contato atualizado, com body["stage"]
mover_card("3f1c2b9a-7d4e-4c55-8a0e-1b2c3d4e5f60", "9b2f5a8e-6a3b-4d0e-9a51-2a7f4f1d0c11")A resposta 200 é o contato atualizado, já com o novo stage. Um stage_id que não é etapa da organização responde 400 invalid_field (param: "stage_id"); um contato inexistente, 404 resource_not_found.
Ler um quadro inteiro
Seção intitulada “Ler um quadro inteiro”Para montar o seu próprio Kanban, busque as etapas e depois os contatos de cada uma com o filtro stage_id:
const API = 'https://platform.toptalking.com.br/v1';const headers = { Authorization: `Bearer ${process.env.TOPTALKING_API_KEY}` };
const { data: etapas } = await (await fetch(`${API}/stages`, { headers })).json();
const quadro = [];for (const etapa of etapas) { const url = `${API}/contacts?stage_id=${etapa.id}&archived=false&limit=100`; const { data: cards } = await (await fetch(url, { headers })).json(); quadro.push({ ...etapa, cards });}Ser avisado quando um card muda de etapa
Seção intitulada “Ser avisado quando um card muda de etapa”Assine o webhook contact.stage_changed. Ele chega toda vez que um card muda de coluna — pelo painel, pela IA ou pela API — com a etapa nova e a anterior.