https://app.clinplus.com.br/api/pub/v1 REST · JSON · v1

API de Integração

API REST pública pra conectar sistemas parceiros — bots de WhatsApp, CRMs e afins — à sua clínica.

Base URL
https://app.clinplus.com.br/api/pub/v1
Autenticação

Toda chamada precisa do header Authorization: Bearer <token>. O token é criado pela clínica em Configurações → API / Integrações, com os escopos (módulos) que ele pode acessar.

curl https://app.clinplus.com.br/api/pub/v1/ping \
  -H "Authorization: Bearer SEU_TOKEN"
Escopos disponíveis
agendamentos:ler— Consultar agendamentos e horários disponíveis
agendamentos:criar— Criar agendamentos
agendamentos:cancelar— Cancelar agendamentos
pacientes:ler— Buscar e consultar pacientes
pacientes:criar— Cadastrar pacientes
lembretes:ler— Listar agendamentos pendentes de lembrete
lembretes:enviar— Disparar lembretes por WhatsApp
catalogos:ler— Ler catálogos (médicos, especialidades, convênios, unidades)

Feito pra IA / Agentes

Conecte seu bot/assistente em minutos: os endpoints são orientados a intenção e a API é auto-descritível.

Artefatos prontos
GET /tools.json— esquemas de function-calling (Anthropic/OpenAI) — cole no seu agente
GET /openapi.json— spec OpenAPI 3.0 (gera SDK/tools automático)
GET /postman.json— coleção Postman (importe e teste)
Atalhos semânticos (o jeito que a IA pensa)
GET /disponibilidade/proximo— próximo horário livre por especialidade
POST /agendamentos/rapido— resolve/cria paciente por telefone + agenda em 1 chamada
GET /pacientes/por-telefone— o bot já tem o número do paciente
Conector nativo (MCP)
POST /mcp— Servidor Model Context Protocol (JSON-RPC): plugue Claude/ChatGPT/agents direto. Auth: mesmo Bearer token.
Webhooks (nós → você)

Cadastre uma URL em Configurações → API e receba POST assinado quando um agendamento muda (agendamento.criado, .confirmado, .cancelado, .concluido). Valide com X-ClinPlus-Signature: sha256=<hmac>.

Retry sem duplicar

Mande o header Idempotency-Key: <único> nos POST — se o agente repetir a chamada, devolvemos o mesmo resultado (não cria dois agendamentos). Em conflito de horário, o erro já traz os proximos_horarios livres.

Catálogos

GET /catalogos/profissionais?especialidade=cardiologia escopo catalogos:ler

Lista os médicos/profissionais ativos (filtra por especialidade).

Resposta 200
{
  "data": [
    { "id": 36, "nome": "Dr. Roberto Lima", "especialidade": "cardiologia", "crm": "41023 SP" }
  ],
  "meta": { "request_id": "…", "version": "v1" }
}
GET /catalogos/especialidades escopo catalogos:ler

Lista as especialidades.

Resposta 200
{
  "data": [ { "id": 4, "titulo": "Cardiologia", "cbo": "2251-21" } ],
  "meta": { "request_id": "…", "version": "v1" }
}
GET /catalogos/convenios escopo catalogos:ler

Lista os convênios.

Resposta 200
{
  "data": [ { "id": 29, "titulo": "Bradesco Saúde", "registro_ans": "005711" } ],
  "meta": { "request_id": "…", "version": "v1" }
}
GET /catalogos/procedimentos?q=ultra&tipo=exame escopo catalogos:ler

Catálogo de procedimentos (serviços/exames) com preparo e valor particular. Filtre por nome/TUSS (q=) e por tipo (servico|exame). Também em /catalogos/procedimentos/pesquisa?q=.

Resposta 200
{
  "data": [
    {
      "id": 181, "nome": "Ultrassom Abdominal", "tipo": "exame",
      "tuss_codigo": "40901114", "tuss_tabela": "22",
      "preparo": "Jejum de 8 horas. Beber 1L de água 1h antes.",
      "valor_particular": 150.00, "duracao_min": 30, "descricao": null
    }
  ],
  "meta": { "request_id": "…", "version": "v1" }
}
POST /catalogos/convenios/validar escopo catalogos:ler

Diz se um convênio/plano cobre um procedimento (há tabela de preço cadastrada). convenio aceita id ou nome; procedimento aceita código TUSS ou nome.

Corpo (request)
{"convenio":"Bradesco Saúde","plano":"Top Nacional","procedimento":"Consulta"}
Resposta 200
{
  "data": {
    "aceito": true,
    "motivo": "Procedimento coberto — há tabela de preço cadastrada para este convênio/plano.",
    "convenio": { "id": 29, "titulo": "Bradesco Saúde" },
    "plano": "Top Nacional",
    "procedimento": "Consulta em consultório",
    "tuss": "10101012",
    "valor": 120.00
  },
  "meta": { "request_id": "…", "version": "v1" }
}
// aceito=false quando não há tabela de preço; motivo explica (convênio inativo, sem tabela, etc.).
GET /catalogos/unidades escopo catalogos:ler

Lista as unidades/clínicas.

Resposta 200
{
  "data": [ { "id": 1, "nome": "Clínica Viver Bem — Matriz", "sigla": "MATRIZ", "cidade": null, "uf": null } ],
  "meta": { "request_id": "…", "version": "v1" }
}

Agendamentos

GET /agendamentos?data=YYYY-MM-DD&profissional_id=&status= escopo agendamentos:ler

Agendamentos de um dia.

Resposta 200
{
  "data": {
    "data": "2026-08-28",
    "agendamentos": [
      {
        "id": 917,
        "inicio": "2026-08-28T09:15:00-03:00",
        "fim": "2026-08-28T09:45:00-03:00",
        "status": "concluido",
        "titulo": "Consulta cardiológica",
        "descricao": null,
        "paciente": {
          "id": 2056, "nome": "Maria Silva", "telefone": "11900000001",
          "cpf": null, "nascimento": null, "email": "maria@ex.com", "sexo": "feminino"
        },
        "profissional": {
          "id": 36, "nome": "Dr. Roberto Lima", "conselho": "41023/SP", "especialidade": "cardiologia"
        },
        "convenio": { "id": 29, "nome": "Bradesco Saúde" },
        "procedimentos": [
          {
            "item_id": 181, "nome": "Ultrassom Abdominal", "tipo": "exame",
            "tuss_codigo": "40901114", "tuss_tabela": "22", "quantidade": 1,
            "preparo": "Jejum de 8 horas. Beber 1L de água 1h antes."
          }
        ],
        "preparo": "Jejum de 8 horas. Beber 1L de água 1h antes."
      }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /disponibilidade?profissional_id=36&data=YYYY-MM-DD escopo agendamentos:ler

Horários livres de um profissional num dia.

Resposta 200
{
  "data": {
    "data": "2026-09-01",
    "slots": [
      { "hora": "07:00", "disponivel": true, "motivo": null },
      { "hora": "07:45", "disponivel": false, "motivo": "ocupado" }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /disponibilidade/dias?profissional_id=36&limite=14 escopo agendamentos:ler

Próximos dias com vaga.

Resposta 200
{
  "data": {
    "dias": [
      { "data": "2026-08-29", "dia_semana": 6, "disponiveis": 16 },
      { "data": "2026-08-30", "dia_semana": 0, "disponiveis": 16 }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /disponibilidade/proximo?especialidade=cardiologia&dias=14 escopo agendamentos:ler

PRÓXIMO horário livre — varre os profissionais (por especialidade ou todos). Ideal pra IA.

Resposta 200
{
  "data": {
    "disponivel": true,
    "proximo": {
      "data": "2026-08-28", "hora": "17:30", "inicio": "2026-08-28T17:30:00-03:00",
      "profissional": { "id": 36, "nome": "Dr. Roberto Lima" }
    }
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /disponibilidade/busca-elastica?especialidades=cardiologia,endocrinologia&dias_semana=4,5&turno=manha&dias=14&limite=20 escopo agendamentos:ler

Busca horários por vários critérios de uma vez: especialidades (csv), dias_semana (0=dom…6=sáb, csv), turno (manha|tarde|noite), de e dias. Reduz o nº de chamadas.

Resposta 200
{
  "data": {
    "total": 2,
    "resultados": [
      {
        "data": "2026-09-02", "hora": "07:00", "inicio": "2026-09-02T07:00:00-03:00",
        "profissional": { "id": 36, "nome": "Dr. Roberto Lima", "especialidade": "cardiologia" }
      },
      {
        "data": "2026-09-02", "hora": "07:45", "inicio": "2026-09-02T07:45:00-03:00",
        "profissional": { "id": 36, "nome": "Dr. Roberto Lima", "especialidade": "cardiologia" }
      }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /agendamentos/{id} escopo agendamentos:ler

Detalhe de um agendamento.

Resposta 200
{
  "data": {
    "id": 917,
    "inicio": "2026-08-28T09:15:00-03:00",
    "fim": "2026-08-28T09:45:00-03:00",
    "status": "concluido",
    "titulo": "Consulta cardiológica",
    "descricao": null,
    "paciente": { "id": 2056, "nome": "Maria Silva", "telefone": "11900000001", "cpf": null, "nascimento": null, "email": null, "sexo": "feminino" },
    "profissional": { "id": 36, "nome": "Dr. Roberto Lima", "conselho": "41023/SP", "especialidade": "cardiologia" },
    "convenio": { "id": 29, "nome": "Bradesco Saúde" },
    "procedimentos": [ { "item_id": 181, "nome": "Ultrassom Abdominal", "tipo": "exame", "tuss_codigo": "40901114", "tuss_tabela": "22", "quantidade": 1, "preparo": "Jejum de 8 horas." } ],
    "preparo": "Jejum de 8 horas."
  },
  "meta": { "request_id": "…", "version": "v1" }
}
POST /agendamentos escopo agendamentos:criar

Cria um agendamento. convenio_id ausente/null = PARTICULAR. tipo_atendimento = consulta|retorno. procedimentos = ids do catálogo (ou {item_id,qtd}).

Corpo (request)
{"cliente_id":193,"profissional_id":36,"titulo":"Consulta","inicio":"2026-08-28T14:00:00","fim":null,"tipo_atendimento":"consulta","convenio_id":null,"procedimentos":[181],"descricao":null,"notificar":true}
Resposta 200
{
  "data": {
    "id": 940, "status": "agendado", "inicio": "2026-08-28T14:00:00-03:00", "fim": "2026-08-28T15:00:00-03:00",
    "paciente": { "id": 193, "nome": "Maria Silva" }, "profissional": { "id": 36, "nome": "Dr. Roberto Lima" }
  },
  "meta": { "request_id": "…", "version": "v1" }
}
// HTTP 201. Em conflito de horário: HTTP 409 com error.details.proximos_horarios[].
POST /agendamentos/rapido escopo agendamentos:criar

RESOLVE-ou-CRIA o paciente (telefone/CPF) e agenda numa tacada. Ideal pra bot de WhatsApp.

Corpo (request)
{"telefone":"11999998888","nome":"Maria Silva","profissional_id":36,"titulo":"Consulta","inicio":"2026-08-28T14:00:00"}
Resposta 200
{
  "data": {
    "id": 941, "status": "agendado", "inicio": "2026-08-28T14:00:00-03:00",
    "paciente": { "id": 2058, "nome": "Maria Silva", "ja_existia": false }
  },
  "meta": { "request_id": "…", "version": "v1" }
}
// HTTP 201. Resolve-ou-cria o paciente pelo telefone/CPF e agenda.
POST /agendamentos/{id}/reagendar escopo agendamentos:criar

Reagendamento ATÔMICO: move a mesma reserva para outro horário; só muda se a nova vaga estiver livre (senão 409 e o original fica intacto). fim é opcional (mantém a duração).

Corpo (request)
{"inicio":"2026-08-29T15:00:00","fim":null}
Resposta 200
{
  "data": {
    "id": 917, "status": "agendado",
    "inicio": "2026-08-29T15:00:00-03:00", "fim": "2026-08-29T16:00:00-03:00",
    "tipo_atendimento": "retorno",
    "paciente": { "id": 2056, "nome": "Maria Silva" },
    "profissional": { "id": 36, "nome": "Dr. Roberto Lima" }
  },
  "meta": { "request_id": "…", "version": "v1" }
}
// HTTP 409 se a nova vaga estiver ocupada (o agendamento original permanece intacto).
POST /agendamentos/{id}/cancelar escopo agendamentos:cancelar

Cancela um agendamento.

Corpo (request)
{"motivo":"Paciente remarcou"}
Resposta 200
{
  "data": { "id": 917, "status": "cancelado" },
  "meta": { "request_id": "…", "version": "v1" }
}

Pacientes

GET /pacientes?q=maria&limit=20 escopo pacientes:ler

Busca pacientes por nome, telefone ou CPF.

Resposta 200
{
  "data": [
    { "id": 2056, "nome": "Maria Silva", "telefone": "11900000001", "cpf": null, "nascimento": null, "sexo": "feminino", "email": null, "pre_cadastro": false }
  ],
  "meta": { "request_id": "…", "version": "v1" }
}
GET /pacientes/por-telefone?telefone=11999998888 escopo pacientes:ler

Acha o paciente pelo telefone (o bot já tem o número).

Resposta 200
{
  "data": { "id": 2057, "nome": "Maria Silva", "telefone": "11900000002", "cpf": null, "nascimento": null, "sexo": "feminino", "email": "maria@ex.com", "pre_cadastro": false },
  "meta": { "request_id": "…", "version": "v1" }
}
// HTTP 404 quando não encontra.
GET /pacientes/por-cpf?cpf=12345678900 escopo pacientes:ler

Acha o paciente pelo CPF.

Resposta 200
{
  "data": { "id": 2057, "nome": "Maria Silva", "telefone": "11900000002", "cpf": "12345678900", "nascimento": "1985-10-01", "sexo": "feminino", "email": null, "pre_cadastro": false },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /pacientes/contexto?telefone=11999998888 escopo pacientes:ler

Paciente + próximos agendamentos numa única chamada (por telefone). Economiza 2 requisições.

Resposta 200
{
  "data": {
    "paciente": { "id": 2057, "nome": "Maria Silva", "telefone": "11999998888", "cpf": null, "nascimento": null, "sexo": "feminino", "email": null, "pre_cadastro": false },
    "proximos_agendamentos": [
      { "id": 918, "inicio": "2026-08-29T09:00:00-03:00", "fim": "2026-08-29T09:30:00-03:00", "status": "agendado", "titulo": "Retorno", "tipo_atendimento": "retorno", "profissional": "Dr. Roberto Lima" }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /pacientes/{id} escopo pacientes:ler

Detalhe de um paciente.

Resposta 200
{
  "data": { "id": 2057, "nome": "Maria Silva", "telefone": "11900000002", "cpf": null, "nascimento": null, "sexo": "feminino", "email": null, "pre_cadastro": false },
  "meta": { "request_id": "…", "version": "v1" }
}
GET /pacientes/{id}/agendamentos escopo pacientes:ler

Agendamentos de um paciente.

Resposta 200
{
  "data": {
    "agendamentos": [
      { "id": 918, "inicio": "2026-08-28T09:20:00-03:00", "fim": "2026-08-28T09:50:00-03:00", "status": "concluido", "titulo": "Retorno", "profissional": "Dr. Roberto Lima" }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
POST /pacientes escopo pacientes:criar

Cadastra um paciente.

Corpo (request)
{"nome":"Maria Silva","telefone":"11999998888","cpf":null,"nascimento":null,"sexo":"feminino","whatsapp":true}
Resposta 200
{
  "data": { "id": 2058, "nome": "Maria Silva", "telefone": "11955554444", "cpf": null, "nascimento": null, "sexo": "feminino", "email": null, "pre_cadastro": true, "ja_existia": false },
  "meta": { "request_id": "…", "version": "v1" }
}
// ja_existia=true quando o telefone/CPF já era de um paciente (não duplica).

Lembretes

GET /lembretes/pendentes?horas=24 escopo lembretes:ler

Agendamentos que ainda precisam de lembrete.

Resposta 200
{
  "data": {
    "janela_horas": 24,
    "total": 1,
    "pendentes": [
      { "agendamento_id": 918, "paciente": "Maria Silva", "telefone": "11900000002", "inicio": "2026-08-29T09:00:00-03:00", "profissional": "Dr. Roberto Lima" }
    ]
  },
  "meta": { "request_id": "…", "version": "v1" }
}
POST /lembretes/{id}/enviar escopo lembretes:enviar

Dispara o lembrete por WhatsApp.

Resposta 200
{
  "data": { "agendamento_id": 918, "enviado": true, "canal": "whatsapp" },
  "meta": { "request_id": "…", "version": "v1" }
}

Utilitário

GET /ping escopo (qualquer)

Testa o token e devolve os escopos dele.

Resposta 200
{
  "data": {
    "ok": true,
    "clinica": "Clínica Viver Bem",
    "token": "Bot WhatsApp",
    "escopos": ["agendamentos:ler", "pacientes:ler", "lembretes:enviar"],
    "agora": "2026-08-28T17:12:34-03:00"
  }
}
Playground