API REST · v1

Conecte o ClinPRO a qualquer ferramenta

Uma API REST simples pra ler e escrever contatos, agendamentos, pipeline e enviar mensagens no WhatsApp da clínica. Ideal pra conectar via Zapier, Make ou n8n — sem escrever código — ou direto do seu sistema.

# Base URL
https://app.gestaoclinpro.com.br/api/v1

Autenticação

Toda requisição precisa da sua chave no cabeçalho Authorization. Gere a chave dentro da sua conta em Configurações → API & Webhooks (só o dono/admin pode). A chave aparece uma única vez — guarde num lugar seguro.

Authorization: Bearer clinpro_live_sua_chave_aqui

Cada chave carrega só os escopos que você marcou. Se faltar escopo, a API responde 403 insufficient_scope.

Escopos / permissões

O que cada chave pode fazer:

contacts:readLer contatos / leads
contacts:writeCriar e atualizar contatos
appointments:readLer agendamentos
appointments:writeCriar e atualizar agendamentos
pipeline:readLer o pipeline (estágios e leads)
messages:sendEnviar mensagem no WhatsApp

Endpoints

GET/api/v1/contactsescopo: contacts:read

Lista os contatos/leads da clínica (paginado por cursor).

curl "https://app.gestaoclinpro.com.br/api/v1/contacts?limit=50" \
  -H "Authorization: Bearer clinpro_live_sua_chave"
POST/api/v1/contactsescopo: contacts:write

Cria um novo contato. Deduplica por telefone.

curl -X POST "https://app.gestaoclinpro.com.br/api/v1/contacts" \
  -H "Authorization: Bearer clinpro_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Maria Silva",
    "phone": "41999998888",
    "email": "maria@email.com",
    "procedure_interest": "Botox",
    "source": "site"
  }'
GET/api/v1/appointmentsescopo: appointments:read

Lista agendamentos. Filtre por período com from e to (ISO 8601).

curl "https://app.gestaoclinpro.com.br/api/v1/appointments?from=2026-07-01&to=2026-07-31" \
  -H "Authorization: Bearer clinpro_live_sua_chave"
POST/api/v1/appointmentsescopo: appointments:write

Cria um agendamento.

curl -X POST "https://app.gestaoclinpro.com.br/api/v1/appointments" \
  -H "Authorization: Bearer clinpro_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_name": "Maria Silva",
    "phone": "41999998888",
    "procedure": "Botox",
    "professional": "Dra. Lorraine",
    "datetime": "2026-07-20T14:30:00-03:00",
    "duration_minutes": 30
  }'
GET/api/v1/pipelineescopo: pipeline:read

Retorna os estágios do pipeline com a contagem de leads em cada um.

curl "https://app.gestaoclinpro.com.br/api/v1/pipeline" \
  -H "Authorization: Bearer clinpro_live_sua_chave"
POST/api/v1/messagesescopo: messages:send

Envia uma mensagem de texto pelo WhatsApp da clínica. O campo tipo decide quais travas se aplicam: sem ele, a mensagem é tratada como marketing, que é o mais restrito. Veja a seção “Envio de WhatsApp” logo abaixo.

curl -X POST "https://app.gestaoclinpro.com.br/api/v1/messages" \
  -H "Authorization: Bearer clinpro_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "41999998888",
    "message": "Oi! Sua consulta está confirmada 💜",
    "tipo": "transacional"
  }'

# 200 · a mensagem saiu
{ "sent": true, "phone": "41999998888", "tipo": "transacional",
  "limite_diario": 500, "enviadas_hoje": 12 }

Envio de WhatsApp · tipos, limites e recusas

O WhatsApp da clínica é o número dela. Um script que despeja a base em minutos derruba esse número, e aí a clínica perde todo o atendimento. Por isso POST /messages passa por travas de horário, teto diário e descadastro, e a resposta sempre diz por que uma mensagem não saiu.

O campo tipo

É opcional. Se você não mandar, vale marketing, que é o mais restrito. O padrão é o apertado de propósito: errar para esse lado custa uma mensagem parada com o motivo escrito na resposta, errar para o outro custa mensagem para quem pediu para não receber mais.

"marketing"

Padrão · quando você não manda nada

Promoção, reativação de paciente antigo, aviso que a clínica resolveu enviar. A pessoa não pediu.

  • Quem pediu para não receber mais (respondeu PARE) fica de fora.
  • Conversa que a equipe assumiu no painel não recebe mensagem automática por cima.
  • Janela do disparo em massa da clínica (09h às 20h por padrão), sem domingo.
  • Teto diário da clínica (200 por padrão, no máximo 500), compartilhado com follow-up e disparo em massa.
  • Número novo envia menos: 30/dia na 1ª semana, 60 na 2ª, 120 na 3ª, 200 no 1º mês.
"transacional"

Serviço sobre algo que a pessoa pediu

Confirmação da consulta dela, orçamento que ela solicitou, resultado de exame, retorno que ela pediu.

  • Não é bloqueado por descadastro de campanha: quem saiu da propaganda não pediu para perder a própria consulta.
  • Janela civil de 08h às 21h, todos os dias.
  • Teto próprio de 500 por dia, mais alto que o de marketing.
  • Não sofre o aquecimento do número: confirmação de consulta não pode esperar o chip envelhecer.

O teto de marketing é do número, não da funcionalidade: follow-up, disparo em massa e API somam no mesmo balde. Toda chamada, aceita ou recusada, fica registrada com o tipo que você declarou.

Quando a mensagem é recusada

A resposta traz error (o código), message (a frase que explica o motivo em português) e o contexto para você decidir o que fazer: limite_diario, enviadas_hoje, janela e proxima_abertura. Nunca reenvie em laço: 429 e 503 pedem para esperar, e 403 não vai mudar tentando de novo.

# 429 · fora do horário
{
  "error": "fora_da_janela",
  "message": "Fora da janela de envio (das 09:00 às 20:00, horário de Brasília). Mensagem automática de clínica não sai de madrugada.",
  "tipo": "marketing",
  "limite_diario": 200,
  "enviadas_hoje": 37,
  "janela": { "inicio": "09:00", "fim": "20:00" },
  "proxima_abertura": "2026-07-12T12:00:00.000Z"
}
errorHTTPO que aconteceuO que fazer
invalid_phone400phone vazio ou com menos de 10 dígitos.Envie DDD + número, só dígitos.
empty_message400message vazio.Preencha o texto.
invalid_type400tipo veio com um valor que não existe.Use "transacional" ou "marketing" (aceita também transactional, promocional, promotional).
sem_telefone400O número não é um telefone brasileiro válido.Confira o número na origem.
whatsapp_not_connected409A clínica não tem WhatsApp conectado.Conecte o WhatsApp em Configurações.
tenant_inativo403A conta da clínica não está ativa.Regularize a assinatura. Nada sai enquanto isso, nem transacional.
modo_de_teste403A clínica está em modo de teste e este número não está na lista autorizada.Desligue o modo de teste ou inclua o número na lista.
opt_out403A pessoa pediu para não receber mais mensagens desta clínica.Só mensagem de serviço chega a ela. Se for serviço mesmo, mande com tipo "transacional".
ia_pausada409A equipe assumiu essa conversa no painel.Aguarde ou fale com a recepção. Vale só para marketing.
fora_da_janela429Fora do horário de envio.A resposta traz janela e proxima_abertura. Reenvie a partir dali.
domingo429Domingo está desligado nas proteções de envio da clínica.Reenvie na segunda, ou ligue o domingo nas proteções.
teto_diario429A clínica bateu o teto do dia.A resposta traz limite_diario e enviadas_hoje. Reenvie amanhã.
opt_out_indisponivel503Não deu para ler a lista de descadastro, então nenhum marketing sai.Tente de novo em alguns minutos. Se persistir, fale com o suporte.
contagem_indisponivel503Não deu para contar os envios do dia, então o teto não pode ser respeitado.Tente de novo em alguns minutos. Se persistir, fale com o suporte.

Fora dessas, 502 send_failed quer dizer que o WhatsApp recusou o envio. Aí sim vale tentar de novo, com espaço entre as tentativas.

Webhooks

Em vez de ficar consultando a API, deixe o ClinPRO avisar você quando algo acontece. Cadastre uma URL (ex: um webhook do Zapier/Make/n8n) e escolha os eventos. Enviamos um POST assinado com HMAC-SHA256 no cabeçalho x-clinpro-signature.

lead.created· Lead criadolead.stage_changed· Lead mudou de estágioappointment.created· Agendamento criadoappointment.updated· Agendamento atualizadomessage.sent· Mensagem enviada
POST https://sua-url.com/webhook
x-clinpro-event: lead.created
x-clinpro-signature: <hmac-sha256 do corpo>

{
  "event": "lead.created",
  "created_at": "2026-07-11T18:00:00.000Z",
  "data": { "contact": { "id": "...", "name": "Maria Silva", "phone": "41999998888" } }
}

Integra com o quê?

A conexão acontece pela nossa API através do Zapier, Make ou n8n — não temos integração nativa de 1 clique. Qualquer ferramenta com conector nessas plataformas dá pra ligar. Exemplos:

A ponte (sem código)

ZapierMaken8n

Agendas

Google AgendaCalendlyGoogle Meet

CRM & Marketing

HubSpotPipedriveRD Station

Pagamentos

AsaasPIX

Google & comunicação

GmailGoogle SheetsNotionTelegramInstagram

Não achou o seu sistema? Se ele tem Zapier/Make/n8n ou aceita webhooks, dá pra conectar. Fale com a gente.

Pronto pra integrar?

Gere sua chave dentro da conta e comece em minutos.

Gerar minha chave de API