API do Connect Close
Conecte sua conta do Connect Close com outros sistemas: consulte propostas, crie clientes, receba notificações em tempo real via webhook e sincronize tudo com seu CRM.
Introdução
A API do Connect Close é organizada em volta dos recursos principais do sistema: clientes, propostas, produtos e webhooks. Todas as respostas são em JSON e usam HTTPS.
Bearer Token
Autenticação via header HTTP padrão.
Webhooks com HMAC
Eventos assinados para garantir origem.
Connect+ nativo
Sincronização automática com seu CRM.
URL base:
https://proposal-builder-eight-omega.vercel.app/api/v1Autenticação
Todas as requisições para a API precisam de uma chave de API no header Authorization.
Como gerar uma chave de API
- Acesse Configuracoes > API
- Clique em "Nova chave de API"
- Da um nome para identificar a chave (ex: "Integracao Connect+")
- Copie a chave completa imediatamente. Ela comeca com
pb_live_e só e exibida uma vez.
Use no header de cada requisicao:
Authorization: Bearer pb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/jsonExemplo completo com curl:
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/clients" \
-H "Authorization: Bearer pb_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json"Convenções de resposta
Resposta de objeto único
{
"data": {
"id": "uuid",
"razao_social": "Acme Industria LTDA",
"...": "..."
}
}Resposta paginada
{
"data": [
{ "id": "uuid1", "..." : "..." },
{ "id": "uuid2", "..." : "..." }
],
"pagination": {
"page": 1,
"limit": 20,
"total": 153
}
}Use os parametros page (padrao 1) e limit (padrao 20, maximo 100) para navegar pelas paginas.
Resposta de erro
{
"error": {
"code": "NOT_FOUND",
"message": "Proposta não encontrada."
}
}Clientes
/api/v1/clientsLista os clientes da sua empresa. Suporta paginação e busca por texto.
Query params: page, limit, q (busca por nome, e-mail ou CNPJ).
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/clients?page=1&limit=20&q=acme" \
-H "Authorization: Bearer pb_live_xxx"/api/v1/clientsCria um novo cliente. Apenas razao_social é obrigatório.
curl -X POST "https://proposal-builder-eight-omega.vercel.app/api/v1/clients" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"razao_social": "Acme Industria LTDA",
"nome_fantasia": "Acme",
"cnpj": "12.345.678/0001-90",
"email": "contato@acme.com.br",
"telefone": "+5511999999999",
"responsavel": "Joao da Silva",
"segmento": "Industria"
}'/api/v1/clients/{id}Detalhes de um cliente, incluindo todos os contatos vinculados.
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/clients/UUID_DO_CLIENTE" \
-H "Authorization: Bearer pb_live_xxx"/api/v1/clients/{id}Atualiza dados do cliente. Envie apenas os campos que quer alterar.
curl -X PUT "https://proposal-builder-eight-omega.vercel.app/api/v1/clients/UUID_DO_CLIENTE" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "telefone": "+5511988887777" }'Propostas
/api/v1/proposalsLista propostas com filtros opcionais.
Query params: page, limit, status (RASCUNHO, ENVIADA, APROVADA, RECUSADA, EXPIRADA, CANCELADA).
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals?status=ENVIADA&limit=50" \
-H "Authorization: Bearer pb_live_xxx"/api/v1/proposalsCria uma proposta em rascunho. Itens são adicionados pela UI do app.
curl -X POST "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"client_id": "UUID_DO_CLIENTE",
"validade": "2026-12-31",
"observacoes": "Proposta gerada via API"
}'/api/v1/proposals/{id}Detalhes da proposta com todos os itens e o link público.
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals/UUID_DA_PROPOSTA" \
-H "Authorization: Bearer pb_live_xxx"/api/v1/proposals/{id}/statusAtualiza o status da proposta. Dispara webhooks correspondentes.
curl -X PATCH "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals/UUID_DA_PROPOSTA/status" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "status": "APROVADA" }'Produtos
/api/v1/productsLista produtos ativos do catálogo.
Query params: page, limit, q, tipo (UNICO ou RECORRENTE).
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/products?tipo=RECORRENTE" \
-H "Authorization: Bearer pb_live_xxx"Webhooks
Receba notificações em tempo real quando eventos acontecem no seu Connect Close. Cada webhook e uma requisicao POST para a URL que voce cadastrou, com payload JSON e assinatura HMAC-SHA256 no header.
/api/v1/webhooksCria uma nova subscrição. A resposta retorna o secret APENAS na criação - guarde-o, ele e usado para validar a assinatura.
curl -X POST "https://proposal-builder-eight-omega.vercel.app/api/v1/webhooks" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seusistema.com/webhook/connect-close",
"events": ["proposal.approved", "proposal.sent"]
}'Resposta:
{
"data": {
"id": "uuid-da-subscricao",
"url": "https://seusistema.com/webhook/connect-close",
"events": ["proposal.approved", "proposal.sent"],
"ativo": true,
"criado_em": "2026-06-07T17:00:00Z",
"secret": "abc123...(64 chars - GUARDE ESTE VALOR!)"
}
}/api/v1/webhooksLista todas as subscrições da sua empresa (sem expor o secret).
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/webhooks" \
-H "Authorization: Bearer pb_live_xxx"/api/v1/webhooks/{id}Atualiza url, events ou ativo de uma subscrição.
curl -X PUT "https://proposal-builder-eight-omega.vercel.app/api/v1/webhooks/UUID" \
-H "Authorization: Bearer pb_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "ativo": false }'/api/v1/webhooks/{id}Remove permanentemente a subscrição.
curl -X DELETE "https://proposal-builder-eight-omega.vercel.app/api/v1/webhooks/UUID" \
-H "Authorization: Bearer pb_live_xxx"Eventos disponíveis
Eventos enviados como webhook quando você assina. Todos seguem o mesmo formato de payload.
| Evento | Quando dispara |
|---|---|
proposal.created | Nova proposta salva |
proposal.updated | Proposta existente foi editada |
proposal.sent | Proposta enviada por e-mail ao cliente |
proposal.approved | Cliente aprovou a proposta |
proposal.expired | Proposta passou da data de validade |
proposal.cancelled | Proposta foi cancelada ou recusada |
client.created | Novo cliente cadastrado |
client.updated | Cliente existente foi editado |
Formato do payload
Todos os webhooks enviam o mesmo formato JSON no corpo:
{
"event": "proposal.approved",
"created_at": "2026-06-07T17:30:00Z",
"organization_id": "uuid-da-sua-empresa",
"data": {
"id": "uuid-da-proposta",
"numero": "0042",
"status": "APROVADA",
"total_unico": 15000.00,
"total_recorrente_mensal": 1500.00,
"client_id": "uuid-do-cliente"
}
}Headers enviados
Content-Type: application/json
X-Webhook-Signature: sha256=abc123def456...
X-Webhook-Event: proposal.approved
User-Agent: ProposalBuilder-Webhooks/1.0Verificar a assinatura HMAC
Para garantir que o webhook foi mesmo enviado pelo Proposal Builder (e nao por um atacante), voce deve verificar a assinatura no header X-Webhook-Signature. Use o secret que voce recebeu ao criar a subscricao.
Exemplo em Node.js
import crypto from "crypto";
function verificarAssinatura(payloadString, signatureHeader, secret) {
const expectedHash = crypto
.createHmac("sha256", secret)
.update(payloadString)
.digest("hex");
const expectedSignature = `sha256=${expectedHash}`;
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expectedSignature)
);
}
// Em um handler Express:
app.post("/webhook/connect-close", (req, res) => {
const signature = req.header("X-Webhook-Signature");
const payloadString = JSON.stringify(req.body);
const valido = verificarAssinatura(payloadString, signature, process.env.WEBHOOK_SECRET);
if (!valido) {
return res.status(401).json({ error: "Assinatura inválida" });
}
// Processa o evento
console.log("Evento recebido:", req.body.event);
res.status(200).json({ ok: true });
});Exemplo em Python
import hmac, hashlib
def verificar_assinatura(payload_bytes: bytes, signature_header: str, secret: str) -> bool:
expected_hash = hmac.new(
secret.encode(),
payload_bytes,
hashlib.sha256
).hexdigest()
expected_signature = f"sha256={expected_hash}"
return hmac.compare_digest(signature_header, expected_signature)Política de retry
Se sua URL retornar status diferente de 2xx ou demorar mais de 10 segundos, o evento e marcado como pendente e será reenviado automaticamente. Maximo de 3 tentativas. Responda com 200 OK o mais rápido possível - você pode processar o evento depois.
Integração nativa com Connect+
O Connect Close tem integracao nativa com a plataforma Connect+ (CRM e WhatsApp). Voce nao precisa programar nada: clientes viram contatos automaticamente e propostas viram cartões no painel do Connect+.
Como ativar
- No Connect+, va em Configuracoes > Tokens e gere uma API Key para a integração.
- Anote o ID do painel onde os cartões de proposta devem aparecer (Configuracoes > Paineis).
- No Connect Close, va em Configuracoes > Integracoes
- Cole a API Key, a URL base da Connect+ e o ID do painel. Marque as opções de sincronização desejadas.
- Clique em Testar conexao. Se aparecer "Conexao OK", clique em Conectar Connect+.
o que é sincronizado automaticamente
Cliente → Contato
- nome_fantasia ou razao_social vira nome
- telefone (obrigatorio)
- CNPJ vira campo personalizado
- responsável vira campo personalizado
- segmento vira tag
Proposta → Cartao
- Titulo: "Proposta #0001"
- Valor unico (campo personalizado)
- Valor recorrente (campo personalizado)
- Status atual
- Validade
- Link público da proposta
Códigos de erro HTTP
| Codigo | Significado | Quando acontece |
|---|---|---|
200 | OK | Requisição bem sucedida |
201 | Created | Recurso criado com sucesso (POST) |
400 | Bad Request | Body inválido ou campo obrigatório faltando |
401 | Unauthorized | API key inválida, ausente ou revogada |
404 | Not Found | Recurso não encontrado ou não pertence a sua empresa |
500 | Internal Server Error | Erro no servidor. Tente novamente em alguns segundos. |
Codigos de erro internos
Cada erro JSON tem um campo code com identificador especifico:
UNAUTHORIZED- sem auth ou auth invalidaACCOUNT_SUSPENDED- conta da empresa suspensa (HTTP 403)NOT_FOUND- recurso inexistenteVALIDATION_ERROR- dado invalido no bodyINVALID_JSON- body nao e JSON validoDB_ERROR- erro no banco de dadosINTERNAL_ERROR- erro inesperado
Pronto para comecar?
Crie sua primeira chave de API em poucos segundos e comece a integrar.
Gerar chave de API