REST API v1

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/v1

Autenticação

Todas as requisições para a API precisam de uma chave de API no header Authorization.

Como gerar uma chave de API

  1. Acesse Configuracoes > API
  2. Clique em "Nova chave de API"
  3. Da um nome para identificar a chave (ex: "Integracao Connect+")
  4. Copie a chave completa imediatamente. Ela comeca com pb_live_ e só e exibida uma vez.

Use no header de cada requisicao:

bash
Authorization: Bearer pb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Exemplo completo com curl:

bash
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/clients" \
  -H "Authorization: Bearer pb_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json"
Mantenha sua chave em segredo. Quem tem a chave tem acesso total aos dados da sua empresa. Nunca publique em código aberto, repositorios publicos ou aplicativos client-side. Use variáveis de ambiente.

Convenções de resposta

Resposta de objeto único

json
{
  "data": {
    "id": "uuid",
    "razao_social": "Acme Industria LTDA",
    "...": "..."
  }
}

Resposta paginada

json
{
  "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

json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Proposta não encontrada."
  }
}

Clientes

GET/api/v1/clients

Lista os clientes da sua empresa. Suporta paginação e busca por texto.

Query params: page, limit, q (busca por nome, e-mail ou CNPJ).

bash
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"
POST/api/v1/clients

Cria um novo cliente. Apenas razao_social é obrigatório.

bash
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"
  }'
GET/api/v1/clients/{id}

Detalhes de um cliente, incluindo todos os contatos vinculados.

bash
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/clients/UUID_DO_CLIENTE" \
  -H "Authorization: Bearer pb_live_xxx"
PUT/api/v1/clients/{id}

Atualiza dados do cliente. Envie apenas os campos que quer alterar.

bash
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

GET/api/v1/proposals

Lista propostas com filtros opcionais.

Query params: page, limit, status (RASCUNHO, ENVIADA, APROVADA, RECUSADA, EXPIRADA, CANCELADA).

bash
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals?status=ENVIADA&limit=50" \
  -H "Authorization: Bearer pb_live_xxx"
POST/api/v1/proposals

Cria uma proposta em rascunho. Itens são adicionados pela UI do app.

bash
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"
  }'
GET/api/v1/proposals/{id}

Detalhes da proposta com todos os itens e o link público.

bash
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/proposals/UUID_DA_PROPOSTA" \
  -H "Authorization: Bearer pb_live_xxx"
PATCH/api/v1/proposals/{id}/status

Atualiza o status da proposta. Dispara webhooks correspondentes.

bash
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

GET/api/v1/products

Lista produtos ativos do catálogo.

Query params: page, limit, q, tipo (UNICO ou RECORRENTE).

bash
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.

POST/api/v1/webhooks

Cria uma nova subscrição. A resposta retorna o secret APENAS na criação - guarde-o, ele e usado para validar a assinatura.

bash
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:

json
{
  "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!)"
  }
}
GET/api/v1/webhooks

Lista todas as subscrições da sua empresa (sem expor o secret).

bash
curl -X GET "https://proposal-builder-eight-omega.vercel.app/api/v1/webhooks" \
  -H "Authorization: Bearer pb_live_xxx"
PUT/api/v1/webhooks/{id}

Atualiza url, events ou ativo de uma subscrição.

bash
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 }'
DELETE/api/v1/webhooks/{id}

Remove permanentemente a subscrição.

bash
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.

EventoQuando dispara
proposal.createdNova proposta salva
proposal.updatedProposta existente foi editada
proposal.sentProposta enviada por e-mail ao cliente
proposal.approvedCliente aprovou a proposta
proposal.expiredProposta passou da data de validade
proposal.cancelledProposta foi cancelada ou recusada
client.createdNovo cliente cadastrado
client.updatedCliente existente foi editado

Formato do payload

Todos os webhooks enviam o mesmo formato JSON no corpo:

json
{
  "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

bash
Content-Type: application/json
X-Webhook-Signature: sha256=abc123def456...
X-Webhook-Event: proposal.approved
User-Agent: ProposalBuilder-Webhooks/1.0

Verificar 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

javascript
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

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

  1. No Connect+, va em Configuracoes > Tokens e gere uma API Key para a integração.
  2. Anote o ID do painel onde os cartões de proposta devem aparecer (Configuracoes > Paineis).
  3. No Connect Close, va em Configuracoes > Integracoes
  4. Cole a API Key, a URL base da Connect+ e o ID do painel. Marque as opções de sincronização desejadas.
  5. 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)
  • email
  • 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

CodigoSignificadoQuando acontece
200OKRequisição bem sucedida
201CreatedRecurso criado com sucesso (POST)
400Bad RequestBody inválido ou campo obrigatório faltando
401UnauthorizedAPI key inválida, ausente ou revogada
404Not FoundRecurso não encontrado ou não pertence a sua empresa
500Internal Server ErrorErro 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 invalida
  • ACCOUNT_SUSPENDED - conta da empresa suspensa (HTTP 403)
  • NOT_FOUND - recurso inexistente
  • VALIDATION_ERROR - dado invalido no body
  • INVALID_JSON - body nao e JSON valido
  • DB_ERROR - erro no banco de dados
  • INTERNAL_ERROR - erro inesperado

Pronto para comecar?

Crie sua primeira chave de API em poucos segundos e comece a integrar.

Gerar chave de API