Resumo de endpoints
Visão de pássaro das 30 operações da v1.0,
cobrindo pacientes (leitura + escrita),
exames (leitura + escrita),
laudos (leitura + ingestão de laudo assinado),
prontuários do paciente (leitura + escrita),
agenda (leitura + escrita) e
catálogos (procedimentos, convênios, médicos,
CIDs, unidades, complementos, grupos de laudo —
catalogos:read), além do health check
(GET+POST /v1/ping) e dos redirects
302 de PDF. Todos os POST/PATCH
exigem Idempotency-Key obrigatório; todas as
operações exigem autenticação
HMAC-SHA256 e o escopo apropriado. Para a especificação
completa em PT-BR, veja a
referência detalhada;
para experimentar interativamente, abra o
Swagger UI.
Escrita de paciente (POST +
PATCH /v1/pacientes +
POST /v1/pacientes/unificar), criação de exame
(POST /v1/exames com upload base64),
ingestão de laudo assinado
(POST /v1/exames/{id}/laudo) e
prontuários
(POST /v1/pacientes/{id}/prontuarios) integram-se
ao mesmo contrato de idempotência da agenda.
| Método | Path | Resumo | Escopo | Auto-filtro | Retorno | Ações |
|---|---|---|---|---|---|---|
| GET | /v1/ping |
Health check — valida credenciais sem chamar o backend | — | — | PingResponse |
Detalhes · Try it out |
| POST | /v1/ping |
Eco de body com PII redacted (debug de payload) | — | — | PingResponse + echo.body |
Detalhes · Try it out |
| GET | /v1/config |
Capacidades, enums (sexo, arquivo_tipo, status_laudo…) e defaults do tenant (o que pode ser omitido no POST /v1/exames; cache 300s) |
— | — | ConfigResponse |
Detalhes · Try it out |
| GET | /v1/pacientes |
Listar pacientes (paginado, filtros por CPF/nome/período) | pacientes:read |
N/A | Paciente[] |
Detalhes · Try it out |
| GET | /v1/pacientes/{id} |
Detalhe do paciente (endereço + convênio) | pacientes:read |
N/A | PacienteDetalhe |
Detalhes · Try it out |
| POST | /v1/pacientes |
Criar paciente (Idempotency-Key obrig.; numero_prontuario auto-gerado se ausente) |
pacientes:write |
N/A | 201 PacienteDetalhe + Location |
Detalhes · Try it out |
| PATCH | /v1/pacientes/{id} |
Atualizar parcial (RFC 7396 merge; sub-objeto endereco/convenio substitui inteiro) |
pacientes:write |
N/A | 200 PacienteDetalhe |
Detalhes · Try it out |
| POST | /v1/pacientes/unificar |
Unificar dois pacientes duplicados (Idempotency-Key obrig.; atômica e irreversível) |
pacientes:write |
N/A | 200 {status:"unificado"} |
Detalhes · Try it out |
| GET | /v1/exames |
Listar exames (paginado, com status_laudo derivado) |
exames:read |
SIMPLES | Exame[] |
Detalhes · Try it out |
| GET | /v1/exames/{id} |
Detalhe do exame (URLs de PDF se disponíveis) | exames:read |
SIMPLES | ExameDetalhe |
Detalhes · Try it out |
| GET | /v1/exames/{id}/arquivo |
PDF do exame ou laudo (302 → presigned S3, 300s) | exames:read |
SIMPLES | 302 Location S3 |
Detalhes · Try it out |
| POST | /v1/exames |
Criar exame (metadados + arquivos base64; Idempotency-Key obrigatório; aliases de negócio + defaults do tenant — 1.1.0) |
exames:write |
N/A | 201 ExameDetalhe + Location |
Detalhes · Try it out |
| GET | /v1/laudos |
Listar laudos (paginado, filtro por assinado) |
laudos:read |
AMPLIADO | Laudo[] |
Detalhes · Try it out |
| GET | /v1/laudos/{id} |
Detalhe do laudo (assinatura ICP se assinado) | laudos:read |
AMPLIADO | LaudoDetalhe |
Detalhes · Try it out |
| GET | /v1/laudos/{id}/arquivo |
PDF do laudo (302 → presigned S3, 300s) | laudos:read |
AMPLIADO | 302 Location S3 |
Detalhes · Try it out |
| POST | /v1/exames/{id}/laudo |
Ingerir laudo já assinado (PDF; Idempotency-Key obrigatório; imutável) |
laudos:write |
N/A | 201 LaudoDetalhe + Location |
Detalhes · Try it out |
| GET | /v1/agenda/agendamentos |
Agendamentos de um paciente (paciente_id obrigatório — anti-dump) |
agenda:read |
SIMPLES | Agendamento[] |
Detalhes · Try it out |
| GET | /v1/agenda/agendamentos/{id} |
Detalhe do agendamento + histórico de status | agenda:read |
SIMPLES | AgendamentoDetalhe |
Detalhes · Try it out |
| GET | /v1/agenda/slots |
Próximos slots livres por procedimento (procedimento_id obrig.) |
agenda:read |
SIMPLES | Slot[] |
Detalhes · Try it out |
| GET | /v1/agenda/configs |
Listar agendas configuradas (metadados, paginado) | agenda:read |
SIMPLES | AgendaConfig[] |
Detalhes · Try it out |
| POST | /v1/agenda/agendamentos |
Criar agendamento (Idempotency-Key obrig.; hora_fim inferida pelo backend) |
agenda:write |
SIMPLES | 201 Agendamento + Location |
Detalhes · Try it out |
| POST | /v1/agenda/agendamentos/{id}/cancelar |
Cancelar agendamento (motivo 3–500 chars) |
agenda:write |
SIMPLES | 200 Agendamento |
Detalhes · Try it out |
| POST | /v1/agenda/agendamentos/{id}/reagendar |
Reagendar (id preservado; histórico mantém apenas a versão atual) |
agenda:write |
SIMPLES | 200 Agendamento |
Detalhes · Try it out |
| POST | /v1/pacientes/{id}/prontuarios |
Criar prontuário (mensagem HTML e/ou anexos[]; Idempotency-Key obrig.) |
prontuarios:write |
N/A | 201 {prontuario_id, anexos[]} + Location |
Detalhes · Try it out |
| GET | /v1/pacientes/{id}/prontuarios |
Listar prontuários (mensagens) do paciente (paginado) | prontuarios:read |
N/A | Prontuario[] |
Detalhes · Try it out |
| GET | /v1/pacientes/{id}/prontuarios/anexos |
Metadados dos anexos (sem URL/chave S3) | prontuarios:read |
N/A | AnexoProntuarioMeta[] |
Detalhes · Try it out |
| GET | /v1/pacientes/{id}/prontuarios/anexos/{anexoId}/url |
URL do anexo (302 → presigned S3; anti-IDOR no backend) | prontuarios:read |
N/A | 302 Location S3 |
Detalhes · Try it out |
| GET | /v1/procedimentos |
Catálogo de procedimentos (filtro q, ativo) |
catalogos:read |
N/A | Procedimento[] |
Detalhes · Try it out |
| GET | /v1/convenios |
Convênios com planos aninhados (planos[]) |
catalogos:read |
N/A | ConvenioComPlanos[] |
Detalhes · Try it out |
| GET | /v1/medicos |
Médicos com filtro papel (EXAME/LAUDO/SOLICITANTE) |
catalogos:read |
N/A | Medico[] |
Detalhes · Try it out |
| GET | /v1/medicos/{id} |
Detalhe do médico (CPF/RG mascarados; sem senha) | catalogos:read |
N/A | MedicoDetalhe |
Detalhes · Try it out |
| POST | /v1/medicos |
Criar médico (usuario+senha obrig.; saudacao/grupo_permissao por texto ou id) |
medicos:write |
N/A | 201 MedicoDetalhe + Location |
Detalhes · Try it out |
| PATCH | /v1/medicos/{id} |
Atualizar parcial (GET-merge-PUT; papeis/conselho/endereco substituem inteiro) |
medicos:write |
N/A | 200 MedicoDetalhe |
Detalhes · Try it out |
| GET | /v1/cids |
Busca CID-10 (q obrigatório, mín. 2 chars) |
catalogos:read |
N/A | Cid[] |
Detalhes · Try it out |
| GET | /v1/unidades |
Catálogo de unidades/clínicas (fonte do alias unidade_nome) |
catalogos:read |
N/A | Unidade[] |
Detalhes · Try it out |
| GET | /v1/complementos |
Catálogo de complementos de exame (fonte de complementos_id) |
catalogos:read |
N/A | Complemento[] |
Detalhes · Try it out |
| GET | /v1/grupos-laudos |
Catálogo de grupos de médicos laudantes (fonte de grupos_laudos_id) |
catalogos:read |
N/A | GrupoLaudo[] |
Detalhes · Try it out |
Legenda
Escopo
Permissão exigida pelo handler, configurada na sua chave
pela Sivoe. Chave sem o escopo recebe
403 AUTH_INSUFFICIENT_SCOPE — nesse caso,
solicite o ajuste em
contato@roomtec.com.br.
pacientes:read— listar e detalhar pacientes.exames:read— listar/detalhar exames e baixar PDFs.exames:write— criar exame (POST) com metadados + arquivos inline em base64. Fase 6 — mesmo contrato de idempotência da agenda.laudos:read— listar/detalhar laudos e baixar o PDF do laudo.laudos:write— ingerir laudo já assinado (POST /v1/exames/{id}/laudo): a API apenas armazena o PDF e marca como assinado — não assina nem gera PDF. Fase 6 — laudo imutável (exame aceita 1 laudo).agenda:read— listar/detalhar agendamentos do paciente, listar slots e agendas configuradas.agenda:write— criar, cancelar e reagendar agendamentos. ExigeIdempotency-Keyobrigatório em todo POST (ver § Idempotência).pacientes:write— criar (POST), atualizar (PATCH) e unificar duplicados (POST /v1/pacientes/unificar) pacientes. Fase 3* — mesmo contrato de idempotência da agenda. Liberado em piloto em 2026-05-20.medicos:write— criar (POST) e atualizar (PATCH) médicos. O médico é um usuário do sistema:usuarioesenhasão obrigatórios na criação;saudacaoegrupo_permissaoaceitam texto (resolvido no gateway) ou id. O detalhe (GET /v1/medicos/{id}, escopocatalogos:read) mascaracpf/rg. Mesmo contrato de idempotência da agenda.prontuarios:read— listar prontuários (mensagens) do paciente e os metadados dos anexos; obter a URL (302 presigned) de um anexo. Fase 7 — a listagem de anexos nunca expõe URL/chave S3.prontuarios:write— criar prontuário (POST /v1/pacientes/{id}/prontuarios) commensagemHTML e/ouanexos[]em base64. Fase 7 — mesmo contrato de idempotência da agenda.- —
/v1/pingaceita qualquer chave válida.
Auto-filtro de médico
Quando a chave (api_chaves.medico_id) está
associada a um médico específico, o gateway injeta um
predicado SQL no payload enviado ao backend. Parâmetros
medico_*_id na query string são
ignorados silenciosamente (evita
enumeração). Recursos fora do filtro retornam
404 RES_NOT_FOUND — mesma mensagem de ID
inexistente, para não vazar existência.
- N/A — endpoint sem relação direta com médico (pacientes, prontuários do paciente).
- SIMPLES — para exames, o exame é visível quando o médico da chave é o médico do exame, o médico do laudo ou o solicitante. Para agenda, agendamentos cuja agenda está associada ao médico da chave; em POSTs (cancelar/reagendar), o gateway também bloqueia operações sobre agendamentos de outro médico.
- AMPLIADO — laudo é visível quando o médico-laudo bate com a chave, ou quando o exame vinculado satisfaz a regra SIMPLES.
- — — ping (não consulta dados clínicos).
Idempotência nos POST e PATCH
Os endpoints de escrita (3 de agenda, 3 de paciente —
criar, atualizar e unificar, criação
de exame, ingestão de laudo e criação de prontuário) exigem o
header
Idempotency-Key (1–64 chars, regex
^[A-Za-z0-9_-]+$; UUID v4 recomendado).
Contrato é o mesmo entre Agenda e Pacientes
— sem diferenças de comportamento. TTL de
24 horas. Replay com mesmo body devolve a
resposta original (status preservado: 201 replay = 201);
mesmo header com body diferente devolve
422 IDEMPOTENCY_CONFLICT; outra request em flight
devolve 409 CONCURRENT_REQUEST com
Retry-After: 2. Detalhes completos em
referência §
Idempotência.
Badges de método (cores semânticas)
Os badges GET (azul),
POST (verde) e
PATCH (laranja) seguem a
convenção semântica do Bootstrap / Postman / Insomnia —
não são branding do produto. O branding
Sivoe permanece azul (#015BB5) em hero, navegação
e títulos. Códigos de retorno: 201 Created com
header Location: nos endpoints de criar
(agendamento, paciente); 200 OK em cancelar,
reagendar e PATCH.
302 S3 (endpoints /arquivo)
Os endpoints de arquivo respondem com 302 Found
e header Location: apontando para uma URL
pré-assinada do S3 válida por 300 segundos (5 min).
A API não streama bytes — o cliente segue o
redirect direto para o S3.
- cURL: use
-Lpara seguir automaticamente. - Python
requests: segue por padrão. - Node
fetch: segue por padrão. - PHP cURL: mantenha
CURLOPT_FOLLOWLOCATION = falsepara inspecionar a URL antes; ao reusá-la, não reassine com seu HMAC — a presigned já autentica contra o S3 (ver FAQ Q12).
Resolução por identificadores de negócio (POST /v1/exames — 1.1.0)
Desde a release 1.1.0 (X-Api-Release: 1.1.0;
X-Api-Version continua v1), o
POST /v1/exames aceita 8 aliases
opcionais — paciente_cpf,
procedimento_codigo_tuss,
procedimento_abreviacao,
convenio_codigo_ans (só casa convênios com ANS
preenchido), convenio_nome,
medico_exame_crm, medico_laudo_crm e
unidade_nome — que o gateway resolve para o
*_id correspondente. São aditivos:
payloads legados com os *_id continuam válidos.
Precedência: o *_id vence (conflito com alias da
mesma FK → 422 PARAM_CONFLICT); sem id, o alias
resolve (0 exatos → 422 RESOLUTION_NOT_FOUND,
2+ → 422 RESOLUTION_AMBIGUOUS com
candidatos[]); CPF mal formado →
400 VAL_INVALID_PARAM. Campos
unidade_id, medico_exame_id,
medico_laudo_id e convenio_id são
omitíveis quando o tenant tem default — consulte
GET /v1/config para descobrir o que pode ser
omitido. A resposta 201 documenta a origem dos ids
em meta.resolvido (de alias) e
meta.defaults_aplicados (de default). Detalhes em
referência
§ Resolução.
Códigos de erro
Toda resposta de erro segue o envelope padrão
{ data: null, meta, error }. Para o catálogo
completo de error.code (HTTP, AUTH_*,
VAL_*, RES_*, BACKEND_*),
veja códigos de erro.