Documentação da API
Para o seu sistema (de pagamento, CRM ou outro) criar clientes, liberar e bloquear o acesso, mudar plano e créditos e cuidar dos membros da equipe de cada cliente, sem ninguém entrar no painel. E, pelos webhooks, receber um aviso quando algo acontece.
Começo rápido
- No seu painel de administração, abra Integração e crie uma chave. Copie na hora: ela aparece uma vez só.
- Copie a URL base mostrada na mesma tela. Todas as rotas abaixo começam nela.
- Confira a chave:
curl https://<URL base>/eu \
-H "Authorization: Bearer mp_live_..."
Para criar um cliente:
curl -X POST https://<URL base>/clientes \
-H "Authorization: Bearer mp_live_..." \
-H "Content-Type: application/json" \
-d '{"nome":"Empresa X","email":"dono@empresax.com","plano":"Growth","creditos_mes":100,"acesso_ate":"2026-12-31"}'
O cliente recebe por e-mail, com a sua marca, o acesso ao painel. Se o e-mail não sair, a resposta traz a senha_inicial para você passar por outro canal.
Autenticação e limites
- Envie a chave em todo pedido:
Authorization: Bearer <chave>(ouX-Api-Key: <chave>). - A chave é um segredo do seu servidor. Nunca coloque no código de um site, de um aplicativo ou do navegador.
- Uma chave revogada para de funcionar na hora. Com a sua empresa suspensa, toda chave responde
403. - Corpo e respostas em JSON, com os campos em
snake_case. Datas em ISO 8601 (UTC), como2026-12-31ou2026-12-31T23:59:59Z. - Limite por chave: 120 leituras e 60 escritas por minuto. Passou disso, a resposta é
429: espere alguns segundos e tente de novo. - Cada pedido só enxerga os clientes da sua empresa. O id de qualquer outro responde
404. - Tudo o que a chave faz fica no Histórico do painel, com o nome da chave.
Erros
Todo erro vem no mesmo formato:
{ "erro": { "codigo": "EMAIL_EM_USO", "mensagem": "Este e-mail já tem uma conta no sistema." } }
| Status | Código | Quando |
|---|---|---|
| 400 | DADOS_INVALIDOS | Campo faltando, fora do formato ou que não existe na documentação. |
| 401 | NAO_AUTENTICADO | Sem chave, ou a chave fora do formato. |
| 401 | CHAVE_INVALIDA | Chave desconhecida ou revogada. |
| 403 | PARCEIRO_INATIVO | O acesso da sua empresa está suspenso. |
| 404 | NAO_ENCONTRADO | Cliente ou membro que não existe (ou não é da sua empresa). |
| 404 | ROTA_INEXISTENTE | Método ou endereço errado. |
| 409 | EMAIL_EM_USO | Já existe uma conta com esse e-mail. |
| 409 | PACOTE_INSUFICIENTE | No modo pacote, os créditos pedidos não cabem no seu pacote do mês. |
| 409 | EQUIPE_CHEIA | O cliente já tem o máximo de membros ativos. |
| 409 | E_ADMIN | A conta é de um administrador da sua empresa (não se bloqueia pela API). |
| 429 | LIMITE_DE_REQUISICOES | Muitos pedidos em pouco tempo com a mesma chave. |
| 500 | ERRO_INTERNO | Erro do nosso lado. A resposta traz um id: informe ao suporte. |
Clientes
Cliente é a empresa que paga a você: o titular da conta, que tem a equipe dele e os créditos do mês.
O objeto cliente
| Campo | O que é |
|---|---|
id | O id do cliente (use nas outras rotas). |
nome, email, telefone | Do titular. |
papel | titular, ou admin quando a conta é de um administrador da sua empresa que também usa o sistema. |
plano | Growth, Scale ou Enterprise. |
creditos_mes | Créditos por mês (cada reunião de até 2 h gasta 1 crédito; a prorrogada, até 4 h, gasta 2). null = sem limite próprio. |
limite_membros | Membros ativos que a equipe pode ter. null = o do plano. |
membros_ativos | Quantos membros ativos ele tem agora. |
acesso_ate | Até quando o acesso vale. Depois dessa data, o cliente e a equipe ficam sem acesso. null = sem data. |
bloqueado, bloqueado_em | Bloqueado por você (pelo painel ou pela API). |
observacoes | Anotação sua; o cliente não vê. |
criado_em | Quando foi criado. |
A lista, mais novos primeiro. Parâmetros: pagina (padrão 1), por_pagina (padrão 50, máximo 200) e email (filtra por um e-mail). Resposta: { pagina, por_pagina, total, itens: [cliente] }.
Cria o cliente e manda o acesso por e-mail. Obrigatórios: nome (2 a 120 letras) e email. Opcionais: telefone, plano, creditos_mes (0 a 100000), limite_membros (0 a 1000), acesso_ate, observacoes. O que não vier usa os padrões que você definiu em Personalização. Resposta 201: { cliente, email_enviado, senha_inicial } (a senha só vem quando o e-mail não saiu).
Se o seu sistema repetir o pedido (por exemplo, depois de uma queda), a segunda tentativa responde 409 EMAIL_EM_USO. Busque o cliente com GET /clientes?email=... e siga com ele.
O cliente e o uso do mês corrente (horário de Brasília): { cliente, uso_do_mes: { mes, creditos, reunioes } }.
Muda só o que vier: nome, telefone, plano, creditos_mes, limite_membros, acesso_ate, observacoes. O e-mail não muda pela API. Resposta: { cliente, campos_alterados }.
Bloquear corta o acesso do titular e de toda a equipe dele no próximo pedido (e a reunião aberta em até 60 segundos). Os dados ficam guardados. Repetir não tem efeito. Resposta: { cliente, mudou }.
Manda ao titular, com a sua marca, um link para ele criar uma senha nova (vale 1 hora). Resposta: { email_enviado }.
Membros da equipe
As pessoas que usam o sistema na conta de um cliente. Elas gastam os créditos do cliente e contam no limite_membros dele enquanto estiverem ativas.
O objeto membro
| Campo | O que é |
|---|---|
id, cliente_id | O membro e o cliente de quem ele é. |
nome, email, telefone, documento | Cadastro da pessoa. |
cargo | closer (padrão), headcloser, sdr ou financeiro. |
suspenso, suspenso_em | Sem acesso e sem ocupar vaga. |
criado_em | Quando foi criado. |
Todos os membros do cliente, ativos e suspensos: { itens: [membro] }.
Cria o membro na equipe do cliente e manda o acesso por e-mail com a sua marca. Obrigatórios: nome e email. Opcionais: telefone, documento, cargo. Responde 409 EQUIPE_CHEIA se o cliente já estiver no limite. Resposta 201: { membro, email_enviado, senha_inicial }.
Muda nome, telefone, documento ou cargo. Resposta: { membro }.
Suspender corta o acesso e libera a vaga; a conta e o que a pessoa fez ficam. Reativar devolve o acesso e ocupa a vaga de novo (409 EQUIPE_CHEIA sem vaga). Resposta: { membro }.
Tira a pessoa da equipe do cliente: ela fica sem acesso e os leads dela no CRM ficam sem responsável. O e-mail dela continua ocupado. Para quem pode voltar, prefira suspender. Resposta: { membro, leads_liberados }.
O link de senha nova, como o do cliente. Resposta: { email_enviado }.
Outras
A sua empresa e a chave usada: { parceiro: { id, nome, slug, situacao, ambiente }, chave: { id, nome } }. Bom para testar a chave.
A lista dos eventos de webhook, com nome e descrição.
Webhooks
Cadastre em Integração → Webhooks a URL (https) que vai receber os avisos e escolha os eventos. Cada aviso é um POST com este corpo:
{
"id": "evt_8f1c...",
"tipo": "cliente.bloqueado",
"criado_em": "2026-10-26T15:00:00.000Z",
"criado_em_brasilia": "2026-10-26T12:00:00.000-03:00",
"ambiente": "producao",
"parceiro_id": "...",
"versao": 1,
"dados": { "cliente": { ... } }
}
E com estes cabeçalhos:
X-Webhook-Evento | O tipo do evento. |
X-Webhook-Evento-Id | O id do evento (o mesmo do corpo). |
X-Webhook-Tentativa | 1 na primeira entrega, 2 na segunda... |
X-Webhook-Assinatura | t=<segundos unix>,v1=<HMAC-SHA256 em hexadecimal> |
Conferir a assinatura
Calcule o HMAC-SHA256 do texto <t>.<corpo exatamente como chegou> com o segredo do webhook (mostrado na criação) e compare com o v1. Recuse se não bater ou se o t tiver mais de 5 minutos. Em Node.js:
import crypto from 'node:crypto';
function avisoVerdadeiro(segredo, corpoCru, cabecalho) {
const partes = Object.fromEntries(cabecalho.split(',').map((p) => p.trim().split('=')));
const t = Number(partes.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const esperado = crypto.createHmac('sha256', segredo).update(t + '.' + corpoCru).digest('hex');
const a = Buffer.from(esperado, 'hex');
const b = Buffer.from(partes.v1 || '', 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Respostas, novas tentativas e repetidos
- Responda com qualquer status 2xx em até 10 segundos. Redirecionamento não é seguido.
- Sem 2xx, tentamos de novo depois de 1 min, 5 min, 15 min, 1 h e 6 h (6 tentativas no total). Na tela Entregas dá para ver cada tentativa e reenviar.
- Com 20 falhas seguidas o webhook desliga sozinho. Corrija, use Testar e religue.
- O mesmo evento pode chegar mais de uma vez. Guarde o
ide ignore o que já tratou. - A ordem de chegada não é garantida: use o
criado_empara saber o que é mais novo.
Eventos
| Tipo | Quando | dados |
|---|---|---|
cliente.criado | Cliente novo (pelo painel ou pela API). | { cliente } |
cliente.atualizado | Mudou plano, créditos, validade, limite de membros, nome, telefone ou observações. | { cliente, campos_alterados } |
cliente.bloqueado | Acesso bloqueado. | { cliente } |
cliente.desbloqueado | Acesso de volta. | { cliente } |
membro.criado | Pessoa nova na equipe de um cliente. | { membro } |
membro.suspenso | Membro suspenso. | { membro } |
membro.reativado | Membro reativado. | { membro } |
membro.removido | Membro tirado da equipe. | { membro } |
reuniao.concluida | Uma reunião com fala terminou. Nunca leva o conteúdo (transcrição, gravação, análise). | { reuniao: { id, inicio, fim, duracao_minutos, creditos }, cliente: { id, nome, email }, usuario: { id, nome, email, papel } } |
creditos.acabando | O cliente passou de 80% dos créditos do mês. Uma vez por cliente e mês. | { cliente: { id, nome, email }, mes, creditos_usados, creditos_mes, percentual } |
creditos.esgotados | O cliente usou todos os créditos do mês. Uma vez por cliente e mês. | O mesmo de creditos.acabando. |
webhook.teste | O botão Testar. Não volta para a fila. | { webhook_id, mensagem } |
Ligando ao sistema de pagamento
| No seu sistema | Chame |
|---|---|
| Primeira compra aprovada | POST /clientes com o plano, os créditos e o acesso_ate do período pago. Guarde o id devolvido. |
| Renovação paga | PATCH /clientes/{id} com o novo acesso_ate (e /desbloquear, se você tinha bloqueado). |
| Troca de plano | PATCH /clientes/{id} com plano, creditos_mes e limite_membros. |
| Pagamento atrasado ou cancelado | POST /clientes/{id}/bloquear. Os dados ficam; desbloquear devolve tudo. |
| Reembolso ou fim do contrato | POST /clientes/{id}/bloquear. Excluir a conta é pelo suporte. |
| O cliente comprou mais vagas | PATCH /clientes/{id} com limite_membros e, se for você quem cadastra a equipe, POST /clientes/{id}/membros. |
Com o acesso_ate sempre igual ao fim do período pago, o acesso vence sozinho se a renovação não chegar, mesmo que o seu sistema fique fora do ar.