Guias de IA: passo a passo e prompts prontos para Lovable, Claude, Cursor, ChatGPT, Bolt, v0, Replit, n8n, Make e Zapier
# Integrar com IA
> Como usar a API da TopTalking com Lovable, Claude, Cursor, ChatGPT, Bolt, v0, Replit, n8n, Make e Zapier - llms.txt, OpenAPI, MCP, as regras de ouro e um bloco de contexto pronto para colar em qualquer IA.
Você não precisa ser programador para integrar com a TopTalking. As ferramentas de IA (Lovable, Claude, Cursor, ChatGPT…) escrevem o código por você — desde que recebam **a documentação certa** e **as regras certas**. Esta seção entrega as duas coisas, com prompts prontos para copiar e colar. ## Como as IAs leem esta documentação | Recurso | Endereço | Para quê | | ------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------- | | **llms-full.txt** | `https://platform.toptalking.com.br/llms-full.txt` | A documentação **inteira** em texto puro. É o que você entrega para a IA escrever código. | | **llms.txt** | `https://platform.toptalking.com.br/llms.txt` | Índice curto com as regras essenciais e links para as outras versões. | | **llms-small.txt** | `https://platform.toptalking.com.br/llms-small.txt` | Versão compacta, para IAs com pouco contexto. | | **openapi.yaml** | `https://platform.toptalking.com.br/openapi.yaml` | O contrato da API (OpenAPI 3.1). Ideal para ChatGPT Actions, Postman e geradores de código. | | **Servidor MCP** | `https://platform.toptalking.com.br/mcp` | Para a IA **usar** a sua conta (consultar, enviar), em vez de escrever código. | Mais detalhes em [llms.txt](/recursos/llms-txt/) e [OpenAPI](/recursos/openapi/). ## Escolha o seu caminho | Você usa… | Quer… | Caminho | | ------------------------- | ---------------------------------- | -------------------------------------------------------------------- | | Lovable | Um app com WhatsApp | [Guia do Lovable](/ia/lovable/) — Edge Functions + prompts prontos | | Claude Code | Código ou operar a conta | [Claude](/ia/claude/) — MCP + `CLAUDE.md` | | claude.ai | Tirar dúvidas, gerar código | [Claude](/ia/claude/#claudeai-projetos) — Projeto com a documentação | | Cursor, Windsurf, Copilot | Código no seu editor | [Cursor, Windsurf e Copilot](/ia/cursor/) — `@Docs`, regras e MCP | | ChatGPT | Um assistente que consulta a conta | [ChatGPT](/ia/chatgpt/) — GPT personalizado com Actions | | Bolt, v0, Replit | Um app full-stack | [Bolt, v0 e Replit](/ia/bolt-v0-replit/) | | n8n, Make, Zapier | Automação sem código | [n8n, Make e Zapier](/ia/n8n-make-zapier/) | ## As regras de ouro Estas regras valem para qualquer ferramenta. Os prompts desta seção já as incluem — se você escrever os seus, inclua também. 1. **A chave fica só no servidor.** Nunca no React, no HTML, no app mobile ou no chat com a IA. A API não aceita chamadas do navegador. Use Edge Function, rota de API, servidor ou n8n/Make/Zapier, com a chave em um *secret* (`TOPTALKING_API_KEY`). 2. **Toda mensagem enviada leva `Idempotency-Key`.** IAs e automações repetem chamadas; a chave de idempotência impede mensagens duplicadas no WhatsApp do cliente. 3. **Só mande mensagem para quem pediu.** Nada de disparos em massa com `POST /messages`: o WhatsApp pode banir o número. Para campanhas, use [Campanhas](/referencia/campanhas/) (WhatsApp Oficial, com aprovação). 4. **Webhooks: valide a assinatura** (`X-TopTalking-Signature`) com o corpo cru antes de confiar no evento. 5. **Para explorar, use uma chave “Somente leitura”.** Libere escrita só quando o fluxo estiver testado. 6. **Trate erros pelo `code`** e respeite o `Retry-After` em `429`. ## Bloco de contexto (cole em qualquer IA) Se a sua ferramenta não está nos guias, comece a conversa colando este bloco:
```text
Contexto: vou integrar meu sistema com a API da TopTalking (WhatsApp + CRM com Kanban).
Documentação completa (leia antes de escrever código): https://platform.toptalking.com.br/llms-full.txt
Contrato OpenAPI 3.1: https://platform.toptalking.com.br/openapi.yaml
Regras obrigatórias:
- URL base: https://platform.toptalking.com.br/v1 — JSON em UTF-8.
- Autenticação: cabeçalho "Authorization: Bearer ". A chave fica numa variável de ambiente/secret chamada TOPTALKING_API_KEY.
- NUNCA coloque a chave em código de front-end (navegador/app) nem no código-fonte. A API bloqueia chamadas do navegador (sem CORS): toda chamada deve sair do backend (servidor, Edge Function, rota de API, automação).
- Envios (POST /messages e POST /scheduled-messages) sempre com o cabeçalho Idempotency-Key, derivado do ID da operação (ex.: "pedido-1234-despachado").
- Erros vêm como { "error": { "type", "code", "message", "param", "request_id" } }. Trate pelo "code". Em 429, espere os segundos do cabeçalho Retry-After.
- Listas usam paginação por cursor: { "object": "list", "data": [...], "has_more", "next_cursor" }; envie ?cursor=; limit de 1 a 100.
- Telefones com DDI e DDD, só dígitos (ex.: 5511999998888).
- Webhooks: valide X-TopTalking-Signature ("t=,v1="; v1 = HMAC-SHA256 em hex de "." com o secret whsec_... guardado em TOPTALKING_WEBHOOK_SECRET; tolerância de 300 s; comparação em tempo constante). Responda 2xx em até 10 s e deduplique pelo "id" do evento.
- Não invente endpoints nem campos: use só o que está na documentação.
- Nada de envio em massa: uma mensagem por ação do usuário/cliente.
```
## Guias [Lovable](/ia/lovable/)Secrets, Edge Functions e 4 prompts prontos. [Claude](/ia/claude/)Claude Code, Projetos no claude.ai e Claude Desktop. [Cursor, Windsurf e Copilot](/ia/cursor/)@Docs, regras do projeto e MCP. [ChatGPT](/ia/chatgpt/)GPT personalizado com Actions e prompts para Codex. [Bolt, v0 e Replit](/ia/bolt-v0-replit/)Rotas de backend e prompts por plataforma. [n8n, Make e Zapier](/ia/n8n-make-zapier/)Configuração do nó HTTP e do gatilho de webhook.
# Lovable
> Passo a passo para integrar um app do Lovable com a API da TopTalking - secret TOPTALKING_API_KEY, Supabase Edge Functions como ponte, recebimento de webhooks com assinatura e prompts prontos (formulário que envia WhatsApp, painel do Kanban, webhook para tabela, lembretes).
Apps do Lovable têm duas partes: o **front-end** (React, roda no navegador de quem usa o app) e o **back-end** (Lovable Cloud / Supabase, com banco e **Edge Functions**). A chave da TopTalking só pode ficar no back-end.
```text
Navegador (React) → Edge Function (Supabase) → API da TopTalking
sem chave lê TOPTALKING_API_KEY https://platform.toptalking.com.br/v1
```
O erro mais comum Pedir para o Lovable “chamar a API da TopTalking” sem dizer onde faz ele colocar o `fetch` (e a chave) direto no React. Isso **não funciona** (a API bloqueia o navegador — você verá um erro de CORS) e **expõe a chave** para qualquer visitante. Os prompts abaixo já evitam isso. ## 1. Gere a chave Em [Configurações → Desenvolvedor](https://toptalking.com.br/configuracoes/desenvolvedor), clique em **Criar chave**. Dê um nome como “App Lovable” e escolha: * **Somente leitura** se o app só vai consultar (painéis, relatórios); * **Acesso total** se vai enviar mensagens, criar contatos ou mover cards. ## 2. Guarde a chave como secret O nome do secret deve ser exatamente **`TOPTALKING_API_KEY`**. * **Jeito mais fácil:** mande o primeiro prompt abaixo. Quando o Lovable precisar da chave, ele mostra um **formulário seguro para adicionar o secret** — cole a chave ali, **nunca na conversa**. * **Manual:** adicione o secret nas configurações de secrets do backend do projeto (Lovable Cloud) ou, se o projeto usa uma conta Supabase própria, no painel da Supabase em **Edge Functions → Secrets**. ## 3. Prepare a ponte (Edge Function) Cole este prompt no Lovable antes de pedir qualquer funcionalidade:
```text
Vou integrar este app com a API da TopTalking (WhatsApp + CRM com Kanban).
Leia a documentação completa antes de escrever código: https://platform.toptalking.com.br/llms-full.txt
Configure a base da integração:
1. Crie um secret chamado TOPTALKING_API_KEY (me peça para colar o valor pelo formulário seguro de secrets; não peça a chave no chat).
2. Crie um módulo compartilhado para Edge Functions em supabase/functions/_shared/toptalking.ts com:
- const API = "https://platform.toptalking.com.br/v1"
- uma função toptalking(path, { method, body, idempotencyKey }) que faz fetch para `${API}${path}` com os cabeçalhos
"Authorization: Bearer " + Deno.env.get("TOPTALKING_API_KEY"), "Content-Type: application/json"
e, se informado, "Idempotency-Key".
- Se a resposta não for 2xx, o corpo é { "error": { "type", "code", "message", "param", "request_id" } }:
lance um erro com status, code, message e request_id. Em 429, inclua o valor do cabeçalho Retry-After.
3. Crie a Edge Function "toptalking-status" que chama GET /me e devolve { organizacao: organization.name, acesso: api_key.access }.
Ela deve exigir usuário logado (verificação de JWT do Supabase ligada) e tratar CORS (OPTIONS).
4. Adicione na tela de configurações do app um botão "Testar conexão com a TopTalking" que chama essa função
com supabase.functions.invoke e mostra o nome da organização ou o erro.
Regras obrigatórias para tudo o que fizermos com a TopTalking a partir de agora:
- NUNCA chame https://platform.toptalking.com.br a partir do front-end (React) e NUNCA escreva a chave no código.
A API bloqueia o navegador (sem CORS). Toda chamada sai de uma Edge Function usando o módulo _shared/toptalking.ts.
- Não crie uma função "proxy" genérica que repassa qualquer caminho/método vindo do front-end: crie uma Edge Function por ação, validando os dados recebidos.
- Envios de mensagem sempre com Idempotency-Key derivada do ID da operação.
- Use só endpoints e campos que existem na documentação.
```
## 4. Peça a funcionalidade Escolha um dos prompts prontos abaixo (ou adapte). Todos já repetem as regras de segurança — é proposital: o Lovable segue melhor quando a regra está no mesmo prompt. ### Prompt: enviar WhatsApp quando alguém preencher o formulário
```text
Quero que, quando um visitante preencher o formulário de contato deste site, ele receba uma mensagem de boas-vindas no WhatsApp pela API da TopTalking e já entre no Kanban da empresa na etapa "Novo lead".
Documentação da API (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
- URL base: https://platform.toptalking.com.br/v1
- Autenticação: cabeçalho "Authorization: Bearer ", com a chave lida de Deno.env.get("TOPTALKING_API_KEY") (secret do Supabase).
Segurança (obrigatório):
- A chave NUNCA vai para o front-end nem para o código. O React chama só a nossa Edge Function; a Edge Function chama a TopTalking.
- A API da TopTalking não aceita chamadas do navegador (sem CORS). Não tente chamá-la do React.
O que construir:
1. Formulário com: nome, WhatsApp com DDD e uma caixa obrigatória "Aceito receber mensagens no WhatsApp".
Valide o telefone no front e no back: só dígitos; com DDD são 10 ou 11 dígitos; se não começar com 55, adicione 55.
2. Tabela "leads": id (uuid), nome, telefone, consentimento (boolean), status ('pendente' | 'enviado' | 'erro'),
toptalking_contact_id, toptalking_message_id, erro_codigo, erro_mensagem, created_at.
RLS: visitantes não leem nem escrevem direto; só a Edge Function (service role) grava. Usuários logados podem ler.
3. Edge Function "enviar-boas-vindas" (pública, sem exigir login, com CORS liberado só para o domínio do app):
a. Recebe { nome, telefone, consentimento }. Recuse se consentimento não for true ou se o telefone for inválido.
b. Anti-abuso: se já existe lead com o mesmo telefone nas últimas 24 h, não envie de novo (responda sucesso sem reenviar).
c. Grave o lead com status 'pendente'.
d. Busque as etapas: GET /v1/stages → { data: [{ id, name, is_final, ... }] }. Pegue o id da etapa com name "Novo lead"
(se não existir, siga sem etapa).
e. Crie/atualize o contato: POST /v1/contacts com { "phone": telefone, "name": nome, "stage_id": }.
A resposta (201 criado ou 200 já existia) traz o contato com "id".
f. Envie a mensagem: POST /v1/messages com
{ "contact_id": , "text": "Olá, ! 👋 Recebemos seu contato e logo vamos falar com você por aqui." }
e o cabeçalho "Idempotency-Key: lead--boas-vindas".
A resposta 201 traz a mensagem com "id" e "status".
g. Atualize o lead com status 'enviado', toptalking_contact_id e toptalking_message_id.
h. Em erro, a TopTalking responde { "error": { "type", "code", "message", "request_id" } }:
salve erro_codigo/erro_mensagem, status 'erro', e devolva ao front uma mensagem amigável.
Exemplos de code: "channel_unavailable" (WhatsApp da empresa desconectado), "invalid_phone" (telefone inválido),
"rate_limit_exceeded" (muitas requisições; respeite o cabeçalho Retry-After).
4. Depois de enviar o formulário, mostre "Pronto! Enviamos uma mensagem no seu WhatsApp." ou o erro amigável.
Não faça nenhum envio em massa: exatamente uma mensagem por formulário enviado.
```
### Prompt: painel com as conversas e as etapas do Kanban
```text
Quero uma página "Atendimento" (só para usuários logados) que mostre as conversas do WhatsApp da minha empresa organizadas pelas etapas do Kanban da TopTalking, com histórico de mensagens e a opção de mover um card de etapa.
Documentação da API (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
- URL base: https://platform.toptalking.com.br/v1
- Autenticação: cabeçalho "Authorization: Bearer ", chave em Deno.env.get("TOPTALKING_API_KEY").
Segurança (obrigatório):
- Nunca chame a TopTalking do front-end e nunca exponha a chave. Crie Edge Functions que exigem usuário logado
(verificação de JWT do Supabase ligada) e chamam a TopTalking pelo servidor.
- Não crie uma função genérica que repassa qualquer caminho: uma função por ação.
Edge Functions:
1. "toptalking-quadro" (GET):
- GET /v1/stages → lista de etapas em ordem: { data: [{ id, name, color, position, is_final }] }.
- Para cada etapa: GET /v1/contacts?stage_id=&archived=false&limit=100 → { data: [contatos], has_more, next_cursor }.
Campos do contato: id, name, phone, stage { id, name, is_final }, ai_enabled, unread_count,
last_message_at, last_message_preview, resolved_at.
- Devolva [{ etapa, contatos }]. Guarde o resultado em cache por 60 segundos (limite da API: 120 requisições/minuto).
2. "toptalking-conversa" (GET ?contact_id=):
- GET /v1/contacts/{contact_id}/messages?limit=50 → mensagens da mais recente para a mais antiga
(campos: id, direction "inbound"|"outbound", type, text, media { url, mime_type, filename } ou null, status, created_at).
3. "toptalking-mover" (POST { contact_id, stage_id }):
- Confira que stage_id está entre os ids de GET /v1/stages (ou é null para tirar do Kanban).
- PATCH /v1/contacts/{contact_id} com { "stage_id": stage_id } → devolve o contato atualizado.
Front-end:
- Uma coluna por etapa (nome e cor da etapa). Cards com nome (ou telefone, se não houver nome), prévia da última mensagem,
horário relativo em português ("há 5 min") e um selo com unread_count quando > 0.
- Arrastar e soltar entre colunas (ou menu "Mover para…") chama toptalking-mover. Atualize de forma otimista e desfaça se der erro.
Se a etapa de destino tiver is_final = true, peça confirmação: "Mover para esta etapa finaliza a conversa".
- Clicar no card abre um painel lateral com o histórico (toptalking-conversa), em ordem cronológica:
inbound à esquerda, outbound à direita, mostrando texto, imagem/arquivo (media.url) e status de entrega.
- Botão "Atualizar" para recarregar o quadro.
- Trate erros pelo error.code da resposta ({ "error": { "type", "code", "message", "request_id" } }).
Esta página não envia mensagens.
```
### Prompt: receber mensagens via webhook e salvar numa tabela
```text
Quero salvar no banco deste app as mensagens que os clientes mandam para o WhatsApp da empresa, recebendo os webhooks da TopTalking em uma Edge Function.
Documentação (leia as seções de Webhooks, Eventos e Verificar a assinatura): https://platform.toptalking.com.br/llms-full.txt
1. Tabela "mensagens_whatsapp":
id (uuid, primary key = data.message.id), evento_id (uuid, unique = id do evento), contato_id (uuid), contato_nome (text),
telefone (text), direcao (text), tipo (text), texto (text), midia_url (text), recebida_em (timestamptz = data.message.created_at),
payload (jsonb com o evento inteiro), created_at (default now()).
RLS: só usuários logados podem ler; ninguém escreve pelo front-end.
2. Edge Function pública "toptalking-webhook":
- Desligue a verificação de JWT dela em supabase/config.toml ([functions.toptalking-webhook] verify_jwt = false),
porque a TopTalking não envia token do Supabase.
- Leia o corpo CRU com await req.text() ANTES de qualquer JSON.parse.
- Valide o cabeçalho X-TopTalking-Signature, no formato "t=,v1=":
v1 = HMAC-SHA256 em hexadecimal, com chave = Deno.env.get("TOPTALKING_WEBHOOK_SECRET") (o valor inteiro, começando com whsec_)
e mensagem = t + "." + corpo cru.
Use Web Crypto (crypto.subtle.importKey com HMAC/SHA-256 e crypto.subtle.verify, que compara em tempo constante).
Rejeite com 401 se a assinatura não bater ou se a diferença entre agora e t for maior que 300 segundos.
- Só então faça JSON.parse. O evento tem o formato { id, object: "event", type, created_at, organization_id, data }.
- Se type = "message.received": grave em mensagens_whatsapp usando data.message (id, direction, type, text, media?.url, created_at)
e data.contact (id, name, phone), com o cliente Supabase usando a service role (SUPABASE_SERVICE_ROLE_KEY) só dentro da função.
Use upsert/on conflict do nothing: o mesmo evento pode chegar mais de uma vez.
- Se type = "ping" (teste do painel) ou qualquer outro tipo: apenas responda 200.
- Responda 200 rapidamente (em menos de 10 segundos). Qualquer resposta fora de 2xx faz a TopTalking tentar de novo.
3. Página "Mensagens recebidas" (só usuários logados) listando a tabela, mais recentes primeiro, com atualização em tempo real.
4. No fim, me diga:
- a URL da função (https://.supabase.co/functions/v1/toptalking-webhook) para eu cadastrar no painel da TopTalking
em Configurações → Desenvolvedor → Webhooks → Novo webhook, assinando o evento message.received;
- que preciso adicionar o secret TOPTALKING_WEBHOOK_SECRET com o "segredo de assinatura" (whsec_...) que o painel mostra.
Não use a chave de API da TopTalking no front-end e não escreva nenhum segredo no código.
```
### Prompt: lembrete automático no WhatsApp (mensagem agendada)
```text
Quero que, ao criar um agendamento neste app, o cliente receba um lembrete no WhatsApp 24 horas antes, usando as mensagens agendadas da TopTalking (elas aparecem na Agenda do painel da empresa).
Documentação (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
- URL base: https://platform.toptalking.com.br/v1
- Autenticação: "Authorization: Bearer ", chave em Deno.env.get("TOPTALKING_API_KEY"). Nunca no front-end nem no código.
1. Na tabela de agendamentos, adicione a coluna toptalking_lembrete_id (uuid, opcional).
2. Edge Function "agendar-lembrete" (exige usuário logado), recebe { agendamento_id }:
- Leia nome, telefone (com DDD; adicione 55 se faltar) e data_hora do agendamento.
- Calcule send_at = data_hora − 24 horas, em ISO 8601 COM fuso (ex.: "2026-12-01T09:00:00-03:00").
Se send_at já passou, não agende (send_at precisa estar no futuro e em até 365 dias).
- POST /v1/scheduled-messages com
{ "to": telefone, "send_at": send_at, "title": "Lembrete de agendamento",
"text": "Oi {{nome}}! Passando para lembrar do seu horário amanhã às HH:MM. Qualquer coisa, é só responder aqui." }
e o cabeçalho "Idempotency-Key: agendamento--lembrete-24h".
Atenção: {{nome}} é uma variável da própria TopTalking — mantenha as chaves duplas literalmente no texto. Troque só HH:MM.
- A resposta 201 traz { id, status: "pending", ... }. Salve o id em toptalking_lembrete_id.
3. Edge Function "cancelar-lembrete", recebe { agendamento_id }:
- DELETE /v1/scheduled-messages/{toptalking_lembrete_id}. Resposta 200 = cancelado (status "canceled").
- Se vier 409 com error.code "invalid_state", o lembrete já foi enviado ou não está mais pendente: só registre.
- Limpe toptalking_lembrete_id.
4. Chame "agendar-lembrete" ao criar um agendamento; ao remarcar, chame "cancelar-lembrete" e depois "agendar-lembrete"
(use uma Idempotency-Key nova na remarcação, por exemplo com a nova data: agendamento--lembrete-).
Ao cancelar o agendamento, chame "cancelar-lembrete".
Trate erros pelo error.code da resposta ({ "error": { "type", "code", "message", "request_id" } }).
```
### Prompt: tela para conectar um WhatsApp por QR Code
```text
Quero uma página "Conectar WhatsApp" (só para usuários logados) onde eu crio uma conexão de WhatsApp na TopTalking
e leio o QR Code com o celular, sem precisar abrir o painel da TopTalking.
Documentação (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
Passo a passo de referência: https://platform.toptalking.com.br/referencia/canais/
- URL base: https://platform.toptalking.com.br/v1
- Autenticação: "Authorization: Bearer ", chave em Deno.env.get("TOPTALKING_API_KEY"). Nunca no front-end nem no código.
Edge Functions (exigem usuário logado; o front-end chama SÓ estas funções, nunca a TopTalking):
1. "whatsapp-conectar" (POST { nome }):
- POST /v1/channels com { "name": nome } e o cabeçalho "Idempotency-Key: ".
- Resposta 201: { object: "channel_connection", channel: { id, name, phone, status }, status, qr_code, qr_code_generated_at, pairing_code }.
- Se vier 422 com error.code "limit_reached", devolva a error.message (o plano não permite mais conexões).
- Devolva { id: channel.id, status, qrCode: qr_code, telefone: channel.phone }.
2. "whatsapp-status" (GET ?id=):
- GET /v1/channels/{id}/qr → mesmo formato acima. Devolva { id, status, qrCode, telefone }.
- Se status for "disconnected" e qr_code for null, chame POST /v1/channels/{id}/connect com {} para gerar um novo QR Code
e devolva o resultado dele.
Front-end:
- Botão "Conectar WhatsApp" → chama whatsapp-conectar.
- Enquanto status for diferente de "connected", chame whatsapp-status a cada 4 segundos.
- qrCode é uma imagem PNG em data URL ("data:image/png;base64,..."): use direto em
(264×264).
Se qrCode vier null, mostre "Gerando o QR Code…" (é normal nos primeiros segundos).
- Instruções abaixo da imagem: "No celular: WhatsApp → Aparelhos conectados → Conectar um aparelho".
- Quando status for "connected", pare de consultar e mostre "WhatsApp conectado!".
- Desista depois de 3 minutos sem leitura e mostre um botão "Gerar novo QR Code" (que chama whatsapp-status de novo).
Trate erros pelo error.code da resposta ({ "error": { "type", "code", "message", "request_id" } }).
```
## Receber webhooks numa Edge Function Resumo do que o prompt acima faz, para você conferir: 1. A função `toptalking-webhook` fica **pública** (`verify_jwt = false`), porque quem chama é a TopTalking, não um usuário logado. A segurança vem da **assinatura**. 2. Ela lê o corpo cru, valida `X-TopTalking-Signature` com o secret `TOPTALKING_WEBHOOK_SECRET` e só então processa. O código de referência está em [Verificar a assinatura](/webhooks/assinatura/) (aba “Deno / Supabase Edge Function”). 3. No painel da TopTalking, em [Configurações → Desenvolvedor](https://toptalking.com.br/configuracoes/desenvolvedor) → **Webhooks** → **Novo webhook**, cadastre `https://.supabase.co/functions/v1/toptalking-webhook` e escolha os eventos. 4. Copie o **segredo de assinatura** (`whsec_...`) e adicione como secret `TOPTALKING_WEBHOOK_SECRET` no Lovable. 5. Clique em **Enviar teste** e veja em **Ver entregas** se a resposta foi `200`. ## Problemas comuns | Sintoma | Causa e solução | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | Erro de **CORS** no console do navegador | O app está chamando a TopTalking direto do React. Peça: “Mova a chamada para uma Edge Function; o front-end só chama a Edge Function”. | | `401 invalid_api_key` / `missing_api_key` | O secret `TOPTALKING_API_KEY` não existe, tem outro nome ou foi colado com espaços. | | `403 read_only_key` | A chave é Somente leitura. Crie outra com Acesso total para enviar ou alterar. | | `422 channel_unavailable` | O WhatsApp da empresa está desconectado. Reconecte no painel em Configurações → Conexões. | | O webhook recebe `401` da própria Supabase | A função está com verificação de JWT ligada. Desligue para `toptalking-webhook`. | | Assinatura do webhook nunca bate | A função fez `req.json()` antes de validar. Valide com `await req.text()`. | | A chave apareceu no código ou no chat | Revogue a chave no painel na hora e crie outra. |
# Claude
> Use a TopTalking com o Claude - Claude Code (MCP, CLAUDE.md pronto e prompt para escrever a integração), Projetos no claude.ai com o llms-full.txt como conhecimento e Claude Desktop via MCP.
O Claude pode trabalhar com a TopTalking de dois jeitos: * **Operar a conta** pelo [servidor MCP](/mcp/visao-geral/): consultar conversas, mover cards, enviar mensagens (com a sua aprovação). * **Escrever código** de integração com a API REST, lendo esta documentação. ## Claude Code ### 1. Conecte o MCP
```bash
claude mcp add --transport http toptalking https://platform.toptalking.com.br/mcp --header "Authorization: Bearer tt_live_SUA_CHAVE"
```
Detalhes, escopos e permissões em [MCP no Claude Code](/mcp/claude-code/). Para o Claude Code só escrever código, o MCP é opcional — mas ajuda: ele pode consultar as etapas reais do seu Kanban e testar a chave. ### 2. Adicione as regras ao `CLAUDE.md` Cole no `CLAUDE.md` do seu projeto. O Claude Code lê esse arquivo em toda sessão: CLAUDE.md
```markdown
## Integração com a TopTalking (WhatsApp + CRM)
- Documentação completa: https://platform.toptalking.com.br/llms-full.txt
Contrato OpenAPI 3.1: https://platform.toptalking.com.br/openapi.yaml
Consulte antes de usar um endpoint. Não invente endpoints nem campos.
- API REST: base `https://platform.toptalking.com.br/v1`, JSON, cabeçalho `Authorization: Bearer `.
- A chave vem SEMPRE da variável de ambiente `TOPTALKING_API_KEY`. Nunca escreva a chave no código, em testes,
em logs, em fixtures ou em commits. Nunca chame a API a partir de código que roda no navegador (a API não tem CORS).
- Envios (`POST /messages`, `POST /scheduled-messages`) sempre com `Idempotency-Key` derivada do ID da operação
(ex.: `pedido--despachado`), para retentativas não duplicarem mensagens.
- Erros: `{ "error": { "type", "code", "message", "param", "request_id" } }`. Trate pelo `code`.
Em 429, espere `Retry-After` segundos. Não repita erros 4xx. Registre o `request_id` nos logs.
- Listas: paginação por cursor (`has_more`, `next_cursor` → `?cursor=`), `limit` de 1 a 100.
- Telefones: DDI + DDD, só dígitos (ex.: `5511999998888`).
- Webhooks: validar `X-TopTalking-Signature` (`t=,v1=`; v1 = HMAC-SHA256 hex de `.`
com `TOPTALKING_WEBHOOK_SECRET`), tolerância de 300 s, comparação em tempo constante, responder 2xx em até 10 s,
deduplicar pelo `id` do evento.
- Testes automatizados nunca chamam a API real para enviar mensagens: use mocks.
- Nada de envio em massa (risco de banimento do número de WhatsApp).
- Ferramentas MCP `toptalking` que enviam mensagens ou alteram contatos: só use quando eu pedir explicitamente.
```
### 3. Peça a integração
```text
Leia https://platform.toptalking.com.br/llms-full.txt e as regras da TopTalking no CLAUDE.md.
Crie um módulo de integração com a API da TopTalking neste projeto:
1. Um cliente pequeno (sem dependências novas, usando fetch) com:
- request(method, path, { body, idempotencyKey, query }) que usa https://platform.toptalking.com.br/v1,
o cabeçalho Authorization: Bearer ${process.env.TOPTALKING_API_KEY} e lança um erro tipado com status, code,
message e requestId quando a resposta não for 2xx. Em 429, espere Retry-After e tente de novo até 3 vezes.
- Funções: getMe(), listStages(), findContactByPhone(phone) (GET /contacts?phone=),
upsertContact({ phone, name, email, stageId }), moveContact(contactId, stageId),
sendMessage({ to | contactId, text, media, idempotencyKey }), listAllContacts() (percorre todas as páginas com cursor).
2. Uma rota POST /webhooks/toptalking que valida X-TopTalking-Signature com o corpo cru
(TOPTALKING_WEBHOOK_SECRET, tolerância de 300 s, comparação em tempo constante), responde 200 rápido
e despacha o evento por tipo (message.received, contact.stage_changed, ping), ignorando duplicados pelo id do evento.
3. Testes unitários com fetch mockado, incluindo o vetor de teste da assinatura que está na documentação.
4. Atualize o .env.example com TOPTALKING_API_KEY= e TOPTALKING_WEBHOOK_SECRET= (sem valores).
Antes de escrever, mostre o plano e os arquivos que vai criar.
```
## Claude.ai (Projetos) No claude.ai, os **Projetos** guardam arquivos como conhecimento fixo. Coloque a documentação lá e todas as conversas do projeto já sabem usar a API. 1. Abra [llms-full.txt](/llms-full.txt) no navegador e salve como arquivo (`Ctrl+S` / `Cmd+S`), por exemplo `toptalking-llms-full.txt`. 2. No claude.ai, crie um projeto (ex.: “Integração TopTalking”). 3. Em **Conhecimento do projeto**, envie o arquivo `toptalking-llms-full.txt`. 4. Em **Instruções do projeto**, cole:
```text
Você me ajuda a integrar sistemas com a API da TopTalking (WhatsApp + CRM com Kanban).
Use APENAS o arquivo de documentação do projeto como referência: não invente endpoints, campos ou eventos.
Sempre: chamadas só pelo backend (nunca no navegador), chave em variável de ambiente TOPTALKING_API_KEY,
Idempotency-Key em envios, tratamento de erros pelo "code", validação da assinatura dos webhooks.
Responda em português do Brasil, com código completo e explicando onde cada arquivo fica.
```
5. Comece uma conversa no projeto com um pedido concreto. Prompt de exemplo:
```text
Tenho uma loja em Next.js (App Router) com pedidos numa tabela "orders" (id, customer_name, customer_phone, status).
Quero que, quando o status mudar para "shipped", o cliente receba no WhatsApp: "Olá, ! Seu pedido # saiu para entrega."
Escreva:
1. A função de servidor que envia a mensagem pela API da TopTalking (POST /messages) com Idempotency-Key "order--shipped".
2. Onde chamar essa função no fluxo de atualização do pedido.
3. O tratamento dos erros channel_unavailable, invalid_phone e rate_limit_exceeded.
4. Como configurar TOPTALKING_API_KEY na Vercel.
Use a documentação do projeto como fonte.
```
## Claude Desktop Para o Claude Desktop **operar a conta** (consultar conversas, mover cards, enviar com aprovação), conecte o MCP pelo `mcp-remote`: veja [MCP no Claude Desktop](/mcp/claude-desktop/). Você pode combinar com um Projeto: as conversas do projeto têm a documentação, e o MCP dá acesso aos dados reais.
```text
Usando as ferramentas da TopTalking: liste as conversas da etapa "Negociação" que não recebem mensagem há mais de 3 dias.
Para cada uma, leia as últimas 10 mensagens e sugira uma mensagem de follow-up curta e educada.
NÃO envie nada: só me mostre as sugestões para eu aprovar uma por uma.
```
# Cursor, Windsurf e Copilot
> Integre a TopTalking no Cursor, Windsurf e GitHub Copilot - MCP, documentação via @Docs (llms-full.txt), regras prontas (.cursor/rules, .windsurf/rules, copilot-instructions.md) e prompt para gerar a integração.
Nos editores com IA, combine três coisas: 1. **Documentação** — para a IA escrever código certo (`@Docs` com o `llms-full.txt`). 2. **Regras do projeto** — para ela nunca expor a chave nem duplicar mensagens. 3. **MCP** (opcional) — para ela consultar dados reais da sua conta enquanto programa. ## 1. Adicione a documentação * Cursor 1. Abra as configurações do Cursor, na seção de **Docs** (indexação de documentação). 2. Adicione uma nova documentação com a URL `https://platform.toptalking.com.br/llms-full.txt` e o nome **TopTalking**. 3. No chat, digite `@TopTalking` (ou `@Docs` → TopTalking) para incluir a documentação no contexto. * Windsurf e Copilot Inclua o link direto no pedido — o agente consegue ler a página:
```text
Leia https://platform.toptalking.com.br/llms-full.txt antes de começar.
```
Ou baixe o arquivo para dentro do projeto (ex.: `docs/toptalking-llms-full.txt`) e referencie-o no chat. ## 2. Adicione as regras do projeto O conteúdo é o mesmo nos três editores; muda só o arquivo. * Cursor .cursor/rules/toptalking.mdc
```markdown
---
description: Regras para integrar com a API da TopTalking (WhatsApp, contatos, Kanban, mensagens agendadas e webhooks)
alwaysApply: true
---
# TopTalking
- Documentação: https://platform.toptalking.com.br/llms-full.txt (use @TopTalking). OpenAPI: https://platform.toptalking.com.br/openapi.yaml
- Não invente endpoints, campos ou eventos: use só o que está na documentação.
- API REST: https://platform.toptalking.com.br/v1, JSON, cabeçalho `Authorization: Bearer `.
- A chave vem SEMPRE de `process.env.TOPTALKING_API_KEY` (ou equivalente). Nunca no código-fonte, testes, logs ou commits.
- Nunca chame a API a partir de código de navegador (componentes React/Vue client-side, `"use client"`, HTML).
A API não tem CORS. Use rotas de API/Server Actions/Edge Functions.
- Envios (`POST /messages`, `POST /scheduled-messages`) sempre com `Idempotency-Key` derivada do ID da operação.
- Erros: `{ "error": { "type", "code", "message", "param", "request_id" } }`. Trate pelo `code`; em 429 respeite `Retry-After`.
- Listas: cursor (`has_more`, `next_cursor` → `?cursor=`), `limit` até 100.
- Telefones: DDI + DDD, só dígitos (ex.: `5511999998888`).
- Webhooks: validar `X-TopTalking-Signature` (`t=,v1=`, HMAC-SHA256 hex de `.` com
`TOPTALKING_WEBHOOK_SECRET`), tolerância 300 s, comparação em tempo constante, 2xx em até 10 s, deduplicar pelo `id`.
- Testes nunca enviam mensagens reais: use mocks.
- Nada de envio em massa pelo WhatsApp.
```
* Windsurf Crie um arquivo de regra do workspace em `.windsurf/rules/` (ex.: `.windsurf/rules/toptalking.md`) com o mesmo conteúdo da aba Cursor (sem o bloco `---` do topo) e configure a ativação como **sempre ativa** (Always On) nas regras do Cascade. * GitHub Copilot .github/copilot-instructions.md
```markdown
# TopTalking
- Documentação: https://platform.toptalking.com.br/llms-full.txt. OpenAPI: https://platform.toptalking.com.br/openapi.yaml
- Não invente endpoints, campos ou eventos.
- API REST: https://platform.toptalking.com.br/v1, cabeçalho `Authorization: Bearer `.
- Chave só em `TOPTALKING_API_KEY` (variável de ambiente). Nunca no código nem no navegador (a API não tem CORS).
- `Idempotency-Key` em `POST /messages` e `POST /scheduled-messages`.
- Erros pelo `code`; 429 → `Retry-After`.
- Paginação por cursor (`next_cursor`).
- Webhooks: validar `X-TopTalking-Signature` (HMAC-SHA256 de `.` com `TOPTALKING_WEBHOOK_SECRET`).
- Testes com mocks; nada de envio em massa.
```
## 3. Conecte o MCP (opcional) Com o MCP, o agente pode, por exemplo, buscar os IDs reais das etapas do seu Kanban enquanto escreve o código. * Cursor: [MCP no Cursor](/mcp/cursor/) * VS Code (Copilot) e Windsurf: [MCP no VS Code e Windsurf](/mcp/vscode-windsurf/) Use uma chave **Somente leitura** para o MCP no editor, a menos que você queira que o agente envie mensagens. ## 4. Peça a integração
```text
@TopTalking Leia a documentação da TopTalking e siga as regras do projeto (.cursor/rules/toptalking.mdc).
Neste projeto Next.js (App Router), crie a integração com a API da TopTalking:
1. lib/toptalking.ts (só servidor: adicione import "server-only"):
- função request(method, path, { body, query, idempotencyKey }) com base https://platform.toptalking.com.br/v1,
Authorization: Bearer process.env.TOPTALKING_API_KEY, Content-Type: application/json.
- erro tipado TopTalkingError { status, code, message, requestId } a partir de { error: { type, code, message, request_id } }.
- em 429, esperar Retry-After e tentar de novo até 3 vezes.
- funções: sendMessage({ to?, contactId?, text?, media?, idempotencyKey }), upsertContact({ phone, name?, email?, stageId? }),
listStages(), moveContact(contactId, stageId | null), listContacts({ search?, stageId?, cursor?, limit? }).
2. app/api/whatsapp/send/route.ts (POST): exige usuário logado, valida { phone, text } com zod e chama sendMessage
com Idempotency-Key recebida do cliente (crypto.randomUUID() gerado uma vez por envio no front).
3. app/api/webhooks/toptalking/route.ts (POST): lê o corpo cru com await req.text(), valida X-TopTalking-Signature
(TOPTALKING_WEBHOOK_SECRET, 300 s, comparação em tempo constante), responde 200 e trata message.received e
contact.stage_changed; ignora duplicados pelo id do evento. Garanta runtime "nodejs".
4. Testes com fetch mockado e o vetor de teste da assinatura da documentação.
5. .env.example com TOPTALKING_API_KEY= e TOPTALKING_WEBHOOK_SECRET=.
Nenhum componente client-side pode importar lib/toptalking.ts.
```
# ChatGPT
> Crie um GPT personalizado com Actions que acessa a sua conta da TopTalking importando o OpenAPI (https://platform.toptalking.com.br/openapi.yaml) com autenticação Bearer, e use prompts prontos no ChatGPT e no Codex para escrever integrações.
Os conectores do ChatGPT exigem login por OAuth, que a TopTalking ainda não suporta. O caminho é um **GPT personalizado com Actions**: o ChatGPT lê o contrato OpenAPI da TopTalking e passa a chamar a API com a sua chave. ## GPT personalizado com Actions Quem usa o GPT usa a sua chave A chave fica salva no GPT. **Qualquer pessoa com acesso ao GPT age na sua conta.** Deixe o GPT como **só eu** (ou compartilhe só com quem pode), use uma chave **Somente leitura** sempre que possível e uma chave exclusiva para o GPT, que você pode revogar a qualquer momento. 1. Gere uma chave em [Configurações → Desenvolvedor](https://toptalking.com.br/configuracoes/desenvolvedor) com o nome “ChatGPT” (comece com **Somente leitura**). 2. No ChatGPT, vá em **GPTs → Criar** e abra a aba **Configurar**. (É preciso um plano que permita criar GPTs.) 3. Preencha nome (ex.: “Atendimento TopTalking”), descrição e cole as **instruções** abaixo. 4. Em **Ações**, clique em **Criar nova ação**. 5. Em **Autenticação**, escolha **Chave de API**, tipo **Bearer**, e cole a chave `tt_live_...`. 6. Em **Esquema**, use **Importar de URL** com:
```text
https://platform.toptalking.com.br/openapi.yaml
```
As ações aparecem listadas (getMe, listContacts, sendMessage…). 7. Clique em **Testar** na ação `getMe`: a resposta deve trazer o nome da sua organização. 8. Salve o GPT com visibilidade **Somente eu**. Instruções do GPT:
```text
Você é o assistente de atendimento da minha empresa e acessa a conta da TopTalking (WhatsApp + CRM com Kanban) pelas ações da API.
Regras:
- Responda em português do Brasil, de forma objetiva.
- Antes de qualquer ação que ENVIA mensagem (sendMessage, createScheduledMessage) ou ALTERA dados
(upsertContact, updateContact, cancelScheduledMessage, createWebhook, updateWebhook, deleteWebhook),
mostre exatamente o que vai fazer (destinatário, texto, horário) e só execute depois que eu disser "confirmo".
- Nunca envie a mesma mensagem para várias pessoas de uma vez. Nada de envio em massa.
- Ao enviar mensagem, sempre informe o cabeçalho Idempotency-Key com um valor único para aquele envio.
- Para mover um card no Kanban: busque as etapas com listStages e use updateContact com stage_id.
Avise que mover para a etapa com is_final = true finaliza a conversa.
- Para datas (send_at), use ISO 8601 com o fuso de Brasília (-03:00).
- Se uma ação falhar, explique o error.code e o error.message em linguagem simples.
- Nunca mostre a chave de API.
```
Exemplos de uso no GPT:
```text
Quais conversas estão na etapa "Negociação"? Mostre nome, telefone e a prévia da última mensagem.
```
```text
Leia o histórico da conversa com o telefone 5511999998888 e resuma o que o cliente pediu.
```
### Problemas comuns | Sintoma | O que fazer | | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | A ação responde 401 | Confira se a autenticação é **Chave de API → Bearer** e se a chave está certa (sem espaços). | | A ação de envio responde 403 `read_only_key` | A chave é Somente leitura. Crie outra com Acesso total se quiser permitir envios. | | O importador mostra avisos sobre o esquema | Avisos não impedem o uso. Se a importação falhar, abra `https://platform.toptalking.com.br/openapi.json`, copie o conteúdo e cole no campo de esquema. | | Erro de CORS ou “Failed to fetch” | Não acontece em Actions (a chamada sai dos servidores da OpenAI). Se aparecer, é porque o código está rodando no navegador — veja [Autenticação](/comecando/autenticacao/#a-chave-nunca-vai-para-o-navegador). | ## ChatGPT para escrever código No chat normal (sem GPT), entregue a documentação e as regras no começo:
```text
Vou integrar meu sistema com a API da TopTalking (WhatsApp + CRM).
Use como referência a documentação em https://platform.toptalking.com.br/llms-full.txt e o contrato https://platform.toptalking.com.br/openapi.yaml.
Se não conseguir abrir os links, me avise que eu colo o conteúdo.
Regras: chamadas só pelo backend (a API não aceita chamadas do navegador), chave na variável de ambiente TOPTALKING_API_KEY
(nunca no código), cabeçalho Authorization: Bearer, Idempotency-Key em todo envio de mensagem, tratamento de erros pelo
campo error.code, paginação por cursor e validação da assinatura X-TopTalking-Signature nos webhooks.
Não invente endpoints nem campos.
O que eu preciso: [descreva aqui — ex.: "uma rota em Express que envia a confirmação do pedido pelo WhatsApp quando o pagamento é aprovado"].
```
## Codex O Codex lê o arquivo `AGENTS.md` do repositório. Adicione as regras da TopTalking nele — o conteúdo é o mesmo do [`CLAUDE.md` do guia do Claude](/ia/claude/#2-adicione-as-regras-ao-claudemd) — e peça a tarefa:
```text
Leia https://platform.toptalking.com.br/llms-full.txt e as regras da TopTalking no AGENTS.md.
Implemente o envio de confirmação de pedido pelo WhatsApp:
- Quando um pedido mudar para status "paid", envie POST https://platform.toptalking.com.br/v1/messages com
{ "to": , "text": "Olá, ! Recebemos o pagamento do pedido #. Obrigado!" }
e Idempotency-Key "order--paid".
- A chave vem de TOPTALKING_API_KEY. Trate os erros pelo error.code (channel_unavailable, invalid_phone,
rate_limit_exceeded com Retry-After) e registre o request_id.
- Falha no WhatsApp não pode impedir a mudança de status do pedido: registre e siga.
- Escreva testes com a chamada HTTP mockada.
```
# Bolt, v0 e Replit
> Como integrar a API da TopTalking em apps criados no Bolt, no v0 (Next.js na Vercel) e no Replit - onde guardar a chave, o padrão de rota de backend e prompts prontos para cada plataforma.
Em todas essas plataformas o padrão é o mesmo: **o front-end chama uma rota do seu backend, e só o backend chama a TopTalking**, com a chave guardada como variável de ambiente.
```text
Navegador → rota do seu backend (/api/...) → https://platform.toptalking.com.br/v1
sem chave lê TOPTALKING_API_KEY
```
## O padrão de rota Um exemplo de rota de backend em Next.js (o mesmo raciocínio vale para Express, Flask, Edge Functions…): app/api/whatsapp/boas-vindas/route.ts
```ts
import { NextResponse } from 'next/server';
const API = 'https://platform.toptalking.com.br/v1';
export async function POST(req: Request) {
const { nome, telefone, leadId } = await req.json();
const digitos = String(telefone ?? '').replace(/\D/g, '');
if (digitos.length < 10 || !nome || !leadId) {
return NextResponse.json({ erro: 'Dados inválidos' }, { status: 400 });
}
const res = await fetch(`${API}/messages`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TOPTALKING_API_KEY}`, // só existe no servidor
'Content-Type': 'application/json',
'Idempotency-Key': `lead-${leadId}-boas-vindas`,
},
body: JSON.stringify({
to: digitos,
contact_name: nome,
text: `Olá, ${nome}! Recebemos seu contato e logo falamos com você por aqui.`,
}),
});
const body = await res.json();
if (!res.ok) {
// body.error = { type, code, message, request_id }
return NextResponse.json({ erro: body.error.message, codigo: body.error.code }, { status: 502 });
}
return NextResponse.json({ ok: true, mensagemId: body.id });
}
```
Atenção Variáveis com prefixo público (`NEXT_PUBLIC_`, `VITE_`, `PUBLIC_`, `EXPO_PUBLIC_`) vão parar no navegador. **Nunca** coloque a chave da TopTalking numa delas. ## Por plataforma * Bolt Projetos do Bolt costumam ser front-end (Vite + React). Para ter um backend, use a **integração com Supabase** do Bolt (Edge Functions) ou um framework com rotas de servidor (ex.: Next.js, Remix, Astro com SSR). * Guarde a chave como `TOPTALKING_API_KEY` nos secrets do backend escolhido (Supabase: Edge Functions → Secrets). * Se usar Supabase, os prompts do [guia do Lovable](/ia/lovable/) funcionam quase sem mudança.
```text
Quero integrar este projeto com a API da TopTalking (WhatsApp + CRM).
Documentação (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
URL base: https://platform.toptalking.com.br/v1 — cabeçalho "Authorization: Bearer ".
Regras obrigatórias:
- A API NÃO aceita chamadas do navegador (sem CORS) e a chave NUNCA pode ir para o front-end.
Crie o backend com Supabase Edge Functions (conecte o Supabase se ainda não estiver conectado).
A chave fica no secret TOPTALKING_API_KEY e é lida com Deno.env.get("TOPTALKING_API_KEY").
- Nada de variável VITE_ com a chave. Nada de chave no código.
- Envio de mensagem sempre com o cabeçalho Idempotency-Key.
Tarefa: na página de checkout, depois que o pedido for criado, chame uma Edge Function "confirmar-pedido-whatsapp"
que envia POST /v1/messages com { "to": , "contact_name": ,
"text": "Olá, ! Recebemos seu pedido #. Avisaremos por aqui quando ele sair para entrega." }
e Idempotency-Key "pedido--confirmado". Trate erros pelo error.code ({ "error": { "type", "code", "message" } })
e não bloqueie a finalização do pedido se o WhatsApp falhar.
```
* v0 (Next.js) O v0 gera apps Next.js que rodam na Vercel. Use **Route Handlers** (`app/api/.../route.ts`) ou **Server Actions**. * Adicione `TOPTALKING_API_KEY` nas variáveis de ambiente do projeto (no v0, na área de variáveis do projeto; na Vercel, em **Settings → Environment Variables**). * Não use `NEXT_PUBLIC_`.
```text
Integre este app Next.js com a API da TopTalking (WhatsApp + CRM com Kanban).
Documentação (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
URL base: https://platform.toptalking.com.br/v1 — cabeçalho "Authorization: Bearer ${process.env.TOPTALKING_API_KEY}".
Regras obrigatórias:
- Chame a TopTalking SOMENTE em código de servidor (Route Handlers em app/api ou Server Actions). Nunca em componentes
"use client". A API não aceita chamadas do navegador. Coloque import "server-only" no módulo da TopTalking.
- A chave vem da variável de ambiente TOPTALKING_API_KEY (sem NEXT_PUBLIC_). Me peça para adicioná-la.
- Envios com o cabeçalho Idempotency-Key.
Tarefa: crie uma página /leads com um formulário (nome, WhatsApp, consentimento obrigatório) que envia para
app/api/leads/route.ts. A rota:
1. valida os dados (zod) e normaliza o telefone para só dígitos com 55;
2. busca as etapas (GET /v1/stages) e pega o id da etapa "Novo lead";
3. cria/atualiza o contato com POST /v1/contacts { phone, name, stage_id };
4. envia a mensagem de boas-vindas com POST /v1/messages { contact_id, text } e Idempotency-Key "lead--boas-vindas";
5. responde { ok: true } ou a mensagem de erro amigável a partir de error.code.
```
* Replit No Replit, crie um backend (Node com Express ou Python com Flask/FastAPI) e guarde a chave na ferramenta **Secrets** do Replit, com o nome `TOPTALKING_API_KEY`. No código, ela aparece como variável de ambiente (`process.env.TOPTALKING_API_KEY` / `os.environ["TOPTALKING_API_KEY"]`).
```text
Crie um backend em Node.js + Express integrado à API da TopTalking (WhatsApp + CRM).
Documentação (leia antes de codar): https://platform.toptalking.com.br/llms-full.txt
URL base: https://platform.toptalking.com.br/v1 — cabeçalho "Authorization: Bearer ".
Regras obrigatórias:
- A chave fica no Secret TOPTALKING_API_KEY (me peça para criar). Nunca no código e nunca enviada ao front-end.
- O front-end (se houver) chama só as rotas deste backend; a API da TopTalking não aceita chamadas do navegador.
- Envio de mensagem sempre com Idempotency-Key.
Tarefas:
1. POST /api/avisar-entrega { pedidoId, nome, telefone }: envia POST /v1/messages com
{ "to": telefone, "contact_name": nome, "text": "Olá, ! Seu pedido # saiu para entrega. 🚚" }
e Idempotency-Key "pedido--saiu". Proteja a rota com um token próprio (cabeçalho X-Admin-Token
comparado com o Secret ADMIN_TOKEN).
2. POST /webhooks/toptalking: usa express.raw({ type: "application/json" }) para ler o corpo cru, valida
X-TopTalking-Signature ("t=,v1="; HMAC-SHA256 hex de "." com o Secret TOPTALKING_WEBHOOK_SECRET;
tolerância de 300 s; crypto.timingSafeEqual), responde 200 e registra no console os eventos message.received.
Ignore eventos repetidos pelo id.
3. Mostre a URL pública do webhook para eu cadastrar no painel da TopTalking (Configurações → Desenvolvedor → Webhooks).
```
# n8n, Make e Zapier
> Configure o nó HTTP do n8n, o módulo HTTP do Make e o Webhooks by Zapier para chamar a API da TopTalking (cabeçalhos, corpo JSON, Idempotency-Key) e para receber os webhooks com segurança.
Ferramentas de automação rodam no servidor delas — então a chave fica protegida lá, nas **credenciais** da ferramenta. Você usa dois blocos: * **Chamar a API** (enviar mensagem, criar contato, mover card): um nó/módulo **HTTP**. * **Receber eventos** (mensagem recebida, etapa alterada): um gatilho de **webhook**. ## Chamar a API Os dados são sempre os mesmos: | Campo | Valor | | ------------------ | -------------------------------------------------------------------------------------------------------------- | | Método | `POST` (enviar), `GET` (consultar), `PATCH` (atualizar) | | URL | `https://platform.toptalking.com.br/v1/messages` (ou outro endpoint da [referência](/referencia/visao-geral/)) | | Cabeçalho | `Authorization: Bearer tt_live_...` | | Cabeçalho | `Content-Type: application/json` | | Cabeçalho (envios) | `Idempotency-Key: ` | | Corpo | JSON | Exemplo de corpo para enviar mensagem:
```json
{
"to": "5511999998888",
"contact_name": "Maria Souza",
"text": "Olá, Maria! Recebemos seu pedido #1234. Obrigado pela compra!"
}
```
* n8n 1. Adicione um nó **HTTP Request**. 2. **Method:** `POST`. **URL:** `https://platform.toptalking.com.br/v1/messages`. 3. **Authentication:** *Generic Credential Type* → *Header Auth*. Crie a credencial com **Name** `Authorization` e **Value** `Bearer tt_live_SUA_CHAVE`. (Assim a chave fica guardada nas credenciais, e não visível no fluxo.) 4. **Send Headers:** ligado, com `Idempotency-Key` = uma expressão única por operação, por exemplo:
```text
{{ 'pedido-' + $json.pedido_id + '-confirmado' }}
```
5. **Send Body:** ligado, **Body Content Type** `JSON`, **Specify Body** *Using JSON* (com o campo em modo **Expression** para os `{{ }}` funcionarem):
```json
{
"to": "{{ $json.telefone }}",
"contact_name": "{{ $json.nome }}",
"text": "Olá, {{ $json.nome }}! Recebemos seu pedido #{{ $json.pedido_id }}."
}
```
6. Em **Settings** do nó, ative **Retry On Fail** se quiser retentativas — a `Idempotency-Key` garante que não haverá mensagens duplicadas. Para listas grandes, use a opção **Pagination** do nó com o parâmetro `cursor` recebendo `{{ $response.body.next_cursor }}` e pare quando `has_more` for `false`. * Make 1. Adicione o módulo **HTTP → Make a request**. 2. **URL:** `https://platform.toptalking.com.br/v1/messages`. **Method:** `POST`. 3. **Headers:** * `Authorization` = `Bearer tt_live_SUA_CHAVE` * `Idempotency-Key` = por exemplo `pedido-{{1.id}}-confirmado` (mapeado do módulo anterior) 4. **Body type:** *Raw*. **Content type:** *JSON (application/json)*. 5. **Request content:** o JSON da mensagem, mapeando os campos dos módulos anteriores. 6. **Parse response:** *Yes* — assim você pode usar `id`, `status` e, em erro, `error.code` nos próximos módulos. Adicione uma rota de erro (*error handler*) para tratar respostas `4xx/5xx` pelo `error.code`. * Zapier 1. Adicione a ação **Webhooks by Zapier → Custom Request**. 2. **Method:** `POST`. **URL:** `https://platform.toptalking.com.br/v1/messages`. 3. **Data:** o JSON da mensagem (mapeando os campos dos passos anteriores). 4. **Headers:** * `Authorization` = `Bearer tt_live_SUA_CHAVE` * `Content-Type` = `application/json` * `Idempotency-Key` = um valor único da operação (ex.: `pedido-` + ID do pedido + `-confirmado`) 5. Teste o passo e confira a resposta `201` com o `id` da mensagem. Automação não é disparo em massa Um fluxo que roda para uma lista inteira de contatos é um disparo em massa — e o WhatsApp pode banir o número. Use automações para mensagens **transacionais** (uma por evento: pedido, cadastro, agendamento). Para campanhas, use o recurso de Campanhas do painel. Veja [Boas práticas no WhatsApp](/comecando/boas-praticas-whatsapp/). ## Receber webhooks 1. Crie o gatilho de webhook na ferramenta e copie a **URL de produção** dele: * n8n: nó **Webhook**, método `POST`. * Make: módulo **Webhooks → Custom webhook**. * Zapier: gatilho **Webhooks by Zapier → Catch Raw Hook** (mantém o corpo cru e os cabeçalhos). 2. No painel da TopTalking, em [Configurações → Desenvolvedor](https://toptalking.com.br/configuracoes/desenvolvedor) → **Webhooks** → **Novo webhook**, cole a URL e escolha os eventos. 3. Clique em **Enviar teste**: a ferramenta deve receber um evento `ping`. Use-o para mapear os campos (`type`, `data.message.text`, `data.contact.phone`…). 4. No fluxo, filtre pelo campo `type` (ex.: só `message.received`) e ignore o `ping`. ### Segurança dos webhooks nas automações A URL do gatilho é pública: qualquer um que a descubra pode mandar eventos falsos. Escolha uma das proteções: **Opção 1 — validar a assinatura (recomendado quando a ferramenta tem o corpo cru e um passo de código).** A regra é a de [Verificar a assinatura](/webhooks/assinatura/): `v1` = HMAC-SHA256 em hex de `.` com o segredo `whsec_...`. No **n8n**, ative a opção **Raw Body** do nó Webhook e adicione um nó **Code** (JavaScript) logo depois: n8n — nó Code (Run Once for All Items)
```js
const crypto = require('crypto');
const SECRET = 'whsec_SEU_SEGREDO'; // segredo de assinatura do webhook na TopTalking
const item = $input.first();
const cabecalho = item.json.headers['x-toptalking-signature'] || '';
// Corpo cru (opção "Raw Body" do nó Webhook).
const corpo = (await this.helpers.getBinaryDataBuffer(0, 'data')).toString('utf8');
const partes = Object.fromEntries(
cabecalho.split(',').map((p) => {
const i = p.indexOf('=');
return [p.slice(0, i).trim(), p.slice(i + 1).trim()];
}),
);
const t = partes.t;
const v1 = partes.v1 || '';
const esperado = Buffer.from(
crypto.createHmac('sha256', SECRET).update(`${t}.${corpo}`).digest('hex'),
);
const recebido = Buffer.from(v1);
const recente = Math.abs(Date.now() / 1000 - Number(t)) <= 300;
const valido =
recente && recebido.length === esperado.length && crypto.timingSafeEqual(recebido, esperado);
if (!valido) throw new Error('Assinatura inválida: evento ignorado.');
return [{ json: JSON.parse(corpo) }];
```
Se o seu n8n bloquear o `require('crypto')`, libere o módulo com a variável de ambiente `NODE_FUNCTION_ALLOW_BUILTIN=crypto` (n8n auto-hospedado). No **Zapier**, o *Catch Raw Hook* entrega o corpo cru e os cabeçalhos; dá para validar num passo **Code by Zapier** (JavaScript) com a mesma lógica acima. **Opção 2 — tratar o webhook só como aviso e confirmar na API.** Quando não der para validar a assinatura (comum no Make), não confie no conteúdo do evento: use apenas o ID e busque o dado real na API com a sua chave. Um evento falso não terá um ID válido na sua conta. | Evento | Confirme com | | ------------------------------------------------------------- | -------------------------------------------------------- | | `message.received`, `message.sent`, `message.status_updated` | `GET /v1/messages/{data.message.id}` | | `contact.created`, `contact.updated`, `contact.stage_changed` | `GET /v1/contacts/{data.contact.id}` | | `scheduled_message.sent`, `scheduled_message.failed` | `GET /v1/scheduled-messages/{data.scheduled_message.id}` | | `channel.status_updated` | `GET /v1/channels/{data.channel.id}` | | `campaign.status_updated` | `GET /v1/campaigns/{data.campaign.id}` | Em qualquer opção: responda rápido (a ferramenta normalmente já responde `200` sozinha), e deduplique pelo `id` do evento — a mesma entrega pode chegar mais de uma vez. Veja [Entregas e novas tentativas](/webhooks/entregas/).