v1.0 • Online

API Paperclip Gateway

Gateway unificado para orquestração de geração de leads, outreach via WhatsApp e gerenciamento de CRM. Integra Serper API (Google Places), EspoCRM e Evolution API (WhatsApp) em uma interface única com proteção anti-ban.

🔍
Serper / Google Places
Busca de negócios com rotação de API keys
📱
WhatsApp Outreach
Mensagens com anti-ban e limites diários
📊
CRM EspoCRM
Leads, Oportunidades e Pipeline
🛡️
Anti-Ban
Limites, delays e horário comercial
Base URL
https://api-paperclip.olivercode.com.br

Autenticação

Todas as requisições (exceto /health e /outreach/webhook) exigem Bearer Token.

Header obrigatório
Authorization: Bearer {GATEWAY_API_KEY}
Content-Type: application/json
ℹ️
O endpoint /outreach/webhook é público — recebe eventos da Evolution API (WhatsApp).
Exemplo com curl
curl -s -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/health

Pipeline de Vendas

Fluxo completo de lead generation até conversão.

🔍 Serper busca
📥 Lead criado (New)
📱 Mensagem enviada (Contacted)
💬 Negociação (In Negotiation)
✅ Convertido
⚠️
Regras Anti-Ban: Máx. 18 novas conversas/dia • Máx. 80 mensagens/dia • Seg–Sex 8h–18h • Delay 45s–180s entre envios • Typing simulation 3s

Lead Generation — Serper

Busca de negócios via Google Places com rotação automática de API keys.

POST /serper/places Buscar negócios no Google Places

Busca empresas/negócios via Serper Google Places API. Rotaciona chaves automaticamente se 403/429.

Body (JSON)
CampoTipoDescrição
qstringobrigatórioQuery de busca (ex: "dentista São Paulo")
locationstringopcionalLocalização para refinar busca
numnumberopcionalNº de resultados (default: 10)
Exemplo
curl -X POST -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/serper/places \
  -d '{"q": "dentista Curitiba PR", "num": 5}'
Resposta
{
  "places": [
    {
      "title": "Clínica Odonto Plus",
      "address": "R. XV de Novembro, 1234",
      "phone": "+55 41 3333-4444",
      "rating": 4.8,
      "ratingCount": 127,
      "website": "https://odontoplus.com.br"
    }
  ]
}
GET /serper/config Ver configuração (nichos, localizações, keys)

Retorna nichos configurados, localizações, quantidade de API keys ativas.

Resposta
{
  "niches": ["dentista", "advogado", "restaurante", ...],
  "locations": ["São Paulo, SP", "Rio de Janeiro, RJ", ...],
  "leadsPerSearch": 2,
  "serperKeysCount": 3,
  "totalKeysConfigured": 3
}
PUT /serper/config Atualizar nichos, localizações ou adicionar API key
Body (JSON) — todos opcionais
CampoTipoDescrição
nichesstring[]Substitui array de nichos
locationsstring[]Substitui array de localizações
leadsPerSearchnumberNº de leads por busca
addSerperKeystringAdiciona nova API key ao pool
curl -X PUT -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/serper/config \
  -d '{"addSerperKey": "nova-chave-aqui"}'

Leads — Geração e Pipeline

GET /leads/random-combo Combo aleatório nicho + localização

Retorna uma combinação aleatória de nicho e localização do config para uso em buscas diversificadas.

Resposta
{ "niche": "pet shop", "location": "Goiânia, GO", "leadsPerSearch": 2 }
POST /leads/generate Pipeline completo: buscar + filtrar + inserir no CRM

Pipeline automatizado: escolhe nicho/local aleatório (ou recebe forçado), busca no Serper, filtra resultados com telefone, verifica duplicatas no CRM e insere novos leads.

🚀
Endpoint principal para geração de leads. Envie {} para modo totalmente automático.
Body (JSON) — todos opcionais
CampoTipoDescrição
nichestringNicho específico (senão, aleatório)
locationstringLocal específico (senão, aleatório)
limitnumberMáx. leads a inserir (default: 2)
Modo automático
curl -X POST -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/leads/generate \
  -d '{}'
Resposta
{
  "niche": "dentista",
  "location": "Curitiba, PR",
  "found": 10,
  "withPhone": 6,
  "inserted": 2,
  "skipped": 0,
  "leads": [
    { "id": "abc123", "name": "Dr. Silva Odontologia", "phone": "5541999887766" }
  ],
  "skippedDetails": []
}
GET /leads/new Leads novos (não contatados)

Retorna leads com status New do CRM, ordenados por data de criação.

Query Params
ParamDefaultDescrição
limit10Máximo de resultados
GET /leads/active Leads em conversa ativa

Leads com status Contacted ou In Negotiation.

Query Params
ParamDefaultDescrição
limit20Máximo de resultados
PUT /leads/:id/status Atualizar status do lead
Body (JSON)
CampoTipoDescrição
statusstringobrigatório New Contacted In Negotiation Converted Dead
POST /leads/:id/opportunity Criar oportunidade para o lead

Cria uma Opportunity no CRM vinculada ao lead. Atualiza lead para "In Negotiation" automaticamente.

Body (JSON) — todos opcionais
CampoTipoDescrição
namestringNome da oportunidade
stagestringProspecting, Qualification, Proposal, Negotiation, Closed Won, Closed Lost
amountnumberValor (R$)
descriptionstringDescrição
curl -X POST -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/leads/LEAD_ID/opportunity \
  -d '{"name": "Plano Premium - Dr Silva", "stage": "Prospecting", "amount": 2500}'

Outreach — WhatsApp

Envio de mensagens e gerenciamento de conversas com proteção anti-ban integrada.

GET /outreach/status Status dos limites anti-ban
⚠️
Sempre consulte este endpoint antes de enviar mensagens. Só envie se isBusinessHours for true e os limites não estiverem esgotados.
Resposta
{
  "isBusinessHours": true,
  "dailyConversations": { "used": 5, "limit": 18 },
  "dailyMessages": { "used": 23, "limit": 80 },
  "activeConversations": 12,
  "antiBanConfig": {
    "minDelayBetweenMessagesMs": 45000,
    "maxDelayBetweenMessagesMs": 180000,
    "maxNewConversationsPerDay": 18,
    "maxMessagesPerDay": 80,
    "businessHoursStart": 8,
    "businessHoursEnd": 18,
    "businessDays": [1, 2, 3, 4, 5],
    "typingSimulationMs": 3000
  }
}
POST /outreach/send Enviar mensagem inicial para lead

Envia primeira mensagem WhatsApp para um lead. Busca telefone no CRM, formata para Brasil, valida limites anti-ban. Atualiza status para "Contacted".

🛡️
Anti-ban ativo. Retorna 429 se fora do horário comercial ou limites esgotados. Respeite o campo recommendedNextDelayMs da resposta.
Body (JSON)
CampoTipoDescrição
leadIdstringobrigatórioID do lead no CRM
messagestringobrigatórioTexto da mensagem
curl -X POST -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/outreach/send \
  -d '{
    "leadId": "abc123",
    "message": "Olá! Tudo bem? Notei que sua empresa está em Curitiba e tenho uma proposta..."
  }'
Resposta (sucesso)
{
  "ok": true,
  "leadId": "abc123",
  "phone": "5541999887766",
  "messageSent": true,
  "recommendedNextDelayMs": 95000,
  "dailyConversationsUsed": 6,
  "dailyConversationsLimit": 18
}
POST /outreach/reply Responder conversa existente

Envia resposta para uma conversa já existente. Usa o número de telefone diretamente.

Body (JSON)
CampoTipoDescrição
phonestringobrigatórioNúmero WhatsApp (ex: 5541999887766)
messagestringobrigatórioTexto da resposta
GET /outreach/inbox Mensagens recebidas não processadas

Retorna mensagens recebidas pelo webhook que ainda não foram processadas.

Resposta
{
  "messages": [
    {
      "phone": "5541999887766",
      "text": "Oi, tenho interesse sim!",
      "timestamp": "2026-04-13T14:30:00.000Z",
      "processed": false,
      "leadId": "abc123"
    }
  ],
  "count": 1
}
PUT /outreach/inbox/:index/processed Marcar mensagem como processada

Marca a mensagem no índice informado (dentre as não-processadas) como processada.

URL Params
ParamTipoDescrição
:indexnumberÍndice (0-based) na lista de não-processadas
POST /outreach/webhook Webhook — recebe eventos da Evolution API
ℹ️
Endpoint público (sem auth). Chamado automaticamente pela Evolution API quando chegam mensagens WhatsApp. Aceita evento messages.upsert.

WhatsApp — Acesso Direto

Proxy direto para a Evolution API. Use /outreach/* para outreach com anti-ban.

GET /chat/instances Listar instâncias WhatsApp

Lista todas as instâncias WhatsApp conectadas na Evolution API.

POST /chat/send/:instance Enviar mensagem de texto
Body (JSON)
CampoTipoDescrição
numberstringNúmero WhatsApp (ex: 5511999998888)
textstringTexto da mensagem
POST /chat/send-media/:instance Enviar mídia (imagem, doc, áudio)

Proxy para /message/sendMedia/{instance} da Evolution API.

GET /chat/messages/:instance Buscar mensagens

Busca mensagens de uma instância. Query params passados direto à Evolution.

GET /chat/status/:instance Status de conexão da instância

Retorna estado de conexão (open, close, connecting) da instância WhatsApp.

CRM — Acesso Direto (EspoCRM)

Proxy genérico para qualquer entidade do EspoCRM: Lead, Contact, Account, Opportunity, etc.

GET /crm/:entity Listar registros de qualquer entidade
Query Params
ParamDefaultDescrição
limit20Máximo de registros (alias para maxSize)
where-Filtro JSON (formato EspoCRM)
orderBy-Campo para ordenação
order-asc ou desc
curl -H "Authorization: Bearer $GW_KEY" \
  "https://api-paperclip.olivercode.com.br/crm/Lead?limit=5&orderBy=createdAt&order=desc"
GET /crm/:entity/:id Buscar registro por ID
curl -H "Authorization: Bearer $GW_KEY" \
  https://api-paperclip.olivercode.com.br/crm/Lead/abc123
POST /crm/:entity Criar registro

Body JSON é passado diretamente ao EspoCRM.

curl -X POST -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/crm/Lead \
  -d '{"lastName": "Empresa XYZ", "phoneNumber": "5511999998888", "status": "New"}'
PUT /crm/:entity/:id Atualizar registro
curl -X PUT -H "Authorization: Bearer $GW_KEY" \
  -H "Content-Type: application/json" \
  https://api-paperclip.olivercode.com.br/crm/Opportunity/opp123 \
  -d '{"stage": "Closed Won"}'
DELETE /crm/:entity/:id Deletar registro
curl -X DELETE -H "Authorization: Bearer $GW_KEY" \
  https://api-paperclip.olivercode.com.br/crm/Lead/abc123