> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controleclinic.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar paciente

> Cria um paciente. Antes de gravar, compara com os cadastros da clínica — **inclusive arquivados** — por CPF, telefone e nome.

Achando parecido, devolve `409` com `existing.id` e o grau de certeza: `cpf` (quase certo), `phone` (provável) ou `name` (possível). Use o `existing.id` para seguir com o cadastro que já existe; reenvie com `force: true` **só** se tiver certeza de que é outra pessoa (homônimo).

`full_name` até 200 caracteres. Sem o escopo `sensitive:read`, a resposta mascara CPF, telefone, e-mail e data de nascimento.

Escopo: `scheduling:write`.



## OpenAPI

````yaml https://api.controleclinic.com.br/v1/openapi.json post /v1/scheduling/patients
openapi: 3.0.0
info:
  title: Controle Clinic API
  version: v1
  description: >-
    API de automações e integrações externas do Controle Clinic. Conecte n8n,
    CRMs, ERPs e chatbots à sua clínica.


    ## Comece aqui

    1. Crie a chave em **Configurações → Clínica → Integrações → Tokens de
    API**. Marque só os escopos de que precisa e defina uma validade.

    2. Envie a chave no cabeçalho `X-API-Key` em toda chamada. Para testar por
    aqui, cole a chave no cartão **Sua chave**.

    3. Limite: **60 chamadas por minuto** por chave (plano pro). Os cabeçalhos
    `X-RateLimit-Limit`, `X-RateLimit-Remaining` e `X-RateLimit-Reset` mostram o
    saldo; acima do limite a resposta é `429`.

    4. Toda chamada fica registrada em **Logs de Auditoria**, na mesma tela dos
    tokens.


    ## Integração contínua × migração

    Esta API serve para um sistema externo criar e atualizar pacientes e
    agendamentos **daqui para a frente**.

    Para trazer o **histórico** de outro sistema (pacientes, prontuário, agenda
    passada, financeiro), use a **Central de Migração**, com o time de
    implantação: ela tem prévia, de-para e desfazer, que a API não tem.


    ## Erros comuns a todas as rotas

    - `400` corpo ou parâmetro inválido (o corpo diz qual campo)

    - `401` chave ausente, inválida, revogada ou vencida

    - `403` escopo insuficiente ou clínica com acesso suspenso

    - `429` limite de chamadas

    - `500` erro interno — tente de novo mais tarde; se repetir, abra chamado
    informando o horário


    ⚠️ As rotas `POST`, `PATCH` e `DELETE` gravam **de verdade** na clínica dona
    da chave, inclusive pelo botão de teste desta página.
servers:
  - url: https://api.controleclinic.com.br
    description: Produção
security: []
tags:
  - name: Agendamentos
    description: >-
      **Para agendar um paciente:**

      1. `GET /v1/scheduling/professionals`, `/procedures`, `/rooms` e
      `/technologies` — pegue os `id` (eles não mudam; guarde no seu sistema).

      2. `POST /v1/scheduling/patients` com nome, CPF e telefone. Se voltar
      `409`, o paciente já existe: use `existing.id`.

      3. `POST /v1/scheduling/appointments` com `patient_id`, `professional_id`,
      `start_at` e `end_at`.

      4. Para confirmar, cancelar ou remarcar: `PATCH
      /v1/scheduling/appointments/{id}`.


      Datas em ISO 8601 **com fuso**: `2026-11-10T14:00:00-03:00`. Sem fuso, o
      horário é lido como UTC e aparece 3 horas adiantado na agenda.
  - name: Lookup
    description: >-
      Cadastros da clínica que um agendamento referencia: profissionais,
      procedimentos, salas e tecnologias. Só leitura; traz apenas os ativos.
  - name: Sistema
    description: >-
      Conferência da conexão (`/health`, sem chave) e da chave em uso (`/me`:
      escopos, validade e clínica).
  - name: Pacientes
    description: >-
      Cadastro de pacientes da clínica da chave. A API não apaga paciente. Sem
      `sensitive:read`, CPF, telefone, e-mail e nascimento saem mascarados.
  - name: Financeiro
    description: >-
      Leitura do financeiro da clínica dona da chave (escopo `financial:read`).
      **Nenhuma rota escreve.**


      Toda resposta traz `regime` (`competencia`, `caixa`, `vencimento` ou
      `saldo`): somar números de regimes diferentes dá um total sem sentido
      (ex.: entradas de caixa não são faturamento).


      Nome, CPF, `patient_id` e descrições só existem na resposta com o escopo
      `sensitive:read` (sem ele, o campo não vem, nem como `null`). O nome do
      fornecedor das despesas sai com `sensitive:read` ou `financial:suppliers`.


      Não há rotas de escrita no financeiro. Para trazer receitas e despesas de
      outro sistema, use a **Central de Migração** ou o importador de receitas,
      com o time de implantação.
paths:
  /v1/scheduling/patients:
    post:
      tags:
        - Pacientes
      summary: Criar paciente
      description: >-
        Cria um paciente. Antes de gravar, compara com os cadastros da clínica —
        **inclusive arquivados** — por CPF, telefone e nome.


        Achando parecido, devolve `409` com `existing.id` e o grau de certeza:
        `cpf` (quase certo), `phone` (provável) ou `name` (possível). Use o
        `existing.id` para seguir com o cadastro que já existe; reenvie com
        `force: true` **só** se tiver certeza de que é outra pessoa (homônimo).


        `full_name` até 200 caracteres. Sem o escopo `sensitive:read`, a
        resposta mascara CPF, telefone, e-mail e data de nascimento.


        Escopo: `scheduling:write`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                full_name:
                  type: string
                  minLength: 1
                  maxLength: 200
                cpf:
                  type: string
                birthdate:
                  type: string
                gender:
                  type: string
                phone:
                  type: string
                email:
                  type: string
                address_json:
                  type: object
                  additionalProperties:
                    nullable: true
                obs:
                  type: string
                force:
                  type: boolean
              required:
                - full_name
              example:
                full_name: Maria Souza
                cpf: '12345678909'
                phone: '11987654321'
                email: maria@exemplo.com
                birthdate: '1985-04-12'
                gender: F
      responses:
        '201':
          description: Paciente criado
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  clinic_id:
                    type: string
                    format: uuid
                  full_name:
                    type: string
                    nullable: true
                  cpf:
                    type: string
                    nullable: true
                  birthdate:
                    type: string
                    nullable: true
                  gender:
                    type: string
                    nullable: true
                  phone:
                    type: string
                    nullable: true
                  email:
                    type: string
                    nullable: true
                  address_json:
                    nullable: true
                  blood_type:
                    type: string
                    nullable: true
                  allergies:
                    type: string
                    nullable: true
                  obs:
                    type: string
                    nullable: true
                  active:
                    type: boolean
                  created_at:
                    type: string
                  updated_at:
                    type: string
                required:
                  - id
                  - clinic_id
                  - full_name
                  - cpf
                  - birthdate
                  - gender
                  - phone
                  - email
                  - blood_type
                  - allergies
                  - obs
        '400':
          description: Corpo ou parâmetro inválido (o corpo diz qual campo)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - false
                  error:
                    nullable: true
                required:
                  - success
        '401':
          description: Chave ausente, inválida, revogada ou vencida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
        '403':
          description: Escopo insuficiente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    enum:
                      - Insufficient scope
                required:
                  - error
        '409':
          description: >-
            Já existe paciente parecido na clínica (TS-387). Use `existing.id`,
            ou reenvie com `force: true` se for outra pessoa.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    enum:
                      - Duplicate patient
                  message:
                    type: string
                  confidence:
                    type: string
                    enum:
                      - cpf
                      - phone
                      - name
                  existing:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      full_name:
                        type: string
                        nullable: true
                      active:
                        type: boolean
                    required:
                      - id
                      - full_name
                      - active
                required:
                  - error
                  - message
                  - confidence
                  - existing
        '429':
          description: >-
            Limite de chamadas excedido (60/min por chave no plano pro) — veja
            os cabeçalhos X-RateLimit-*
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
        '500':
          description: Erro interno
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
      security:
        - ApiKeyAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Token de API no formato cc_live_<64 chars hex>. Obtido em Minha Clínica
        → Integrações.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.