Guia da API FHIR do HealthPass (Alpha)
Este documento descreve os endpoints da API FHIR R4 necessários para integração com o HealthPass. Para esquemas de recursos detalhados e modelos de dados, consulte fhirdata.md.
Esta API ainda está em fase alpha e sujeita a alterações. Funcionalidades, endpoints e estruturas de dados podem ser modificados ou removidos em versões futuras.
Índice
- Visão Geral
- Autenticação
- Endpoints de Paciente
- Endpoints de Observação
- Endpoints de Condição
- Endpoints de MedicationRequest
- Endpoints de Agendamento
- Endpoints de Profissional
- Endpoints de RelatedPerson
- Operações em Lote
- Padrões Comuns
Visão Geral
URL Base
https://{seu-servidor-fhir}/fhir/R4
Tipo de Conteúdo
Todas as requisições e respostas utilizam:
Content-Type: application/fhir+json
Formato de Resposta
Operações de busca retornam um Bundle FHIR:
{
"resourceType": "Bundle",
"type": "searchset",
"total": 42,
"entry": [
{
"fullUrl": "https://server/fhir/R4/Patient/patient-123",
"resource": { ... },
"search": { "mode": "match" }
}
]
}
Autenticação
A API suporta dois métodos de autenticação:
Bearer Token
Authorization: Bearer <access_token>
OAuth 2.0 Client Credentials
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<id>&client_secret=<secret>
Endpoints de Paciente
Buscar Pacientes
Encontre pacientes por identificador, nome ou número de telefone.
GET /Patient?identifier={valor}
GET /Patient?name={valor}
GET /Patient?telecom={numero_telefone}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
identifier | ID Nacional ou MRN | 9001015009087 |
name | Correspondência parcial de nome | Smith |
telecom | Número de telefone | +27821234567 |
_count | Máximo de resultados (padrão 50) | 20 |
Exemplo:
curl -X GET "https://server/fhir/R4/Patient?telecom=+27821234567" \
-H "Authorization: Bearer <token>" \
-H "Accept: application/fhir+json"
Ler Paciente por ID
GET /Patient/{id}
Exemplo:
curl -X GET "https://server/fhir/R4/Patient/patient-123" \
-H "Authorization: Bearer <token>"
Criar Paciente
POST /Patient
Criação Condicional (Deduplicação):
Use o header If-None-Exist para evitar pacientes duplicados:
POST /Patient
If-None-Exist: telecom=+27821234567
- Retorna
201 Createdse novo paciente for criado - Retorna
200 OKse paciente existente for encontrado
Exemplo:
curl -X POST "https://server/fhir/R4/Patient" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-H "If-None-Exist: telecom=+27821234567" \
-d '{
"resourceType": "Patient",
"active": true,
"name": [{"family": "Smith", "given": ["John"]}],
"telecom": [{"system": "phone", "value": "+27821234567", "use": "mobile"}],
"gender": "male",
"birthDate": "1990-01-01"
}'
Atualizar Paciente
PUT /Patient/{id}
Endpoints de Observação
Buscar Observações
Encontre observações de um paciente, opcionalmente filtradas por código.
GET /Observation?patient=Patient/{id}
GET /Observation?patient=Patient/{id}&code={codigos_loinc}
GET /Observation?patient=Patient/{id}&category={categoria}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
patient | Referência do paciente (obrigatório) | Patient/patient-123 |
code | Códigos LOINC/SNOMED (separados por vírgula) | 8310-5,9279-1 |
category | Categoria da observação | vital-signs |
_sort | Ordem de classificação | -_lastUpdated |
_count | Máximo de resultados | 50 |
Exemplo - Obter sinais vitais:
curl -X GET "https://server/fhir/R4/Observation?patient=Patient/patient-123&category=vital-signs&_sort=-_lastUpdated" \
-H "Authorization: Bearer <token>"
Exemplo - Obter observações específicas:
# Obter temperatura e frequência respiratória
curl -X GET "https://server/fhir/R4/Observation?patient=Patient/patient-123&code=8310-5,9279-1" \
-H "Authorization: Bearer <token>"
Criar Observação
POST /Observation
Exemplo - Registrar temperatura:
curl -X POST "https://server/fhir/R4/Observation" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Observation",
"status": "final",
"category": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs"
}]
}],
"code": {
"coding": [{
"system": "http://loinc.org",
"code": "8310-5",
"display": "Body temperature"
}]
},
"subject": {"reference": "Patient/patient-123"},
"effectiveDateTime": "2024-01-15T10:30:00Z",
"valueQuantity": {
"value": 37.2,
"unit": "Cel",
"system": "http://unitsofmeasure.org",
"code": "Cel"
}
}'
Endpoints de Condição
Buscar Condições
GET /Condition?patient=Patient/{id}
GET /Condition?patient=Patient/{id}&clinical-status={status}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
patient | Referência do paciente (obrigatório) | Patient/patient-123 |
clinical-status | Filtrar por status | active |
_sort | Ordem de classificação | -recordedDate |
Exemplo:
curl -X GET "https://server/fhir/R4/Condition?patient=Patient/patient-123&clinical-status=active" \
-H "Authorization: Bearer <token>"
Criar Condição
POST /Condition
Exemplo - Registrar diagnóstico de pneumonia:
curl -X POST "https://server/fhir/R4/Condition" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Condition",
"clinicalStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}]
},
"verificationStatus": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}]
},
"code": {
"coding": [
{"system": "http://snomed.info/sct", "code": "233604007", "display": "Pneumonia"},
{"system": "http://hl7.org/fhir/sid/icd-10-cm", "code": "J18.9"}
]
},
"subject": {"reference": "Patient/patient-123"},
"recordedDate": "2024-01-15T10:30:00Z"
}'
Endpoints de MedicationRequest
Buscar MedicationRequests
GET /MedicationRequest?patient=Patient/{id}
GET /MedicationRequest?patient=Patient/{id}&status={status}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
patient | Referência do paciente (obrigatório) | Patient/patient-123 |
status | Status da prescrição | active |
_sort | Ordem de classificação | -authoredOn |
Criar MedicationRequest
POST /MedicationRequest
Exemplo - Prescrever amoxicilina:
curl -X POST "https://server/fhir/R4/MedicationRequest" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "MedicationRequest",
"status": "active",
"intent": "order",
"medicationCodeableConcept": {
"coding": [{
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": "308182",
"display": "Amoxicillin 500 MG Oral Capsule"
}]
},
"subject": {"reference": "Patient/patient-123"},
"authoredOn": "2024-01-15T10:30:00Z",
"requester": {"reference": "Practitioner/practitioner-456"},
"dosageInstruction": [{
"sequence": 1,
"text": "Tomar 1 cápsula (500mg) por via oral três vezes ao dia durante 7 dias"
}]
}'
Endpoints de Agendamento
Buscar Agendamentos
GET /Appointment?patient=Patient/{id}
GET /Appointment?patient=Patient/{id}&status={status}
GET /Appointment?patient=Patient/{id}&date=ge{data}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
patient | Referência do paciente | Patient/patient-123 |
actor | Qualquer participante (paciente, profissional, local) | Practitioner/prac-456 |
status | Status do agendamento | booked |
date | Filtro de data (suporta ge, le, gt, lt) | ge2024-01-01 |
_sort | Ordem de classificação | -start |
Exemplo - Obter próximos agendamentos:
curl -X GET "https://server/fhir/R4/Appointment?patient=Patient/patient-123&status=booked&date=ge2024-01-15&_sort=start" \
-H "Authorization: Bearer <token>"
Criar Agendamento
POST /Appointment
Exemplo:
curl -X POST "https://server/fhir/R4/Appointment" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Appointment",
"status": "booked",
"appointmentType": {
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v2-0276",
"code": "CONSULT"
}]
},
"description": "Consulta de acompanhamento",
"start": "2024-01-20T09:00:00Z",
"end": "2024-01-20T09:30:00Z",
"participant": [
{"actor": {"reference": "Patient/patient-123"}, "status": "accepted"},
{"actor": {"reference": "Practitioner/practitioner-456"}, "status": "accepted"},
{"actor": {"reference": "Location/location-city-center"}, "status": "accepted"}
]
}'
Atualizar Status do Agendamento
PUT /Appointment/{id}
Usado para cancelamento, check-in ou reagendamento.
Endpoints de Profissional
Buscar Profissionais
GET /Practitioner?name:contains={nome}
GET /Practitioner?specialty:text={especialidade}
Parâmetros:
| Parâmetro | Descrição | Exemplo |
|---|---|---|
name:contains | Correspondência parcial de nome | Smith |
specialty:text | Busca por texto de especialidade | Cardiology |
_count | Máximo de resultados | 10 |
_sort | Ordem de classificação | name |
Buscar por Local (via PractitionerRole)
GET /PractitionerRole?location=Location/{id}&_include=PractitionerRole:practitioner
Exemplo:
curl -X GET "https://server/fhir/R4/PractitionerRole?location=Location/location-city-center&_include=PractitionerRole:practitioner&_count=10" \
-H "Authorization: Bearer <token>"
Endpoints de RelatedPerson
O HealthPass utiliza vinculação bidirecional de RelatedPerson. Consulte fhirdata.md para o padrão completo.
Encontrar Filhos de um Responsável
GET /RelatedPerson?patient=Patient/{id_responsavel}&relationship=CHILD
O campo identifier em cada resultado contém o ID do Paciente filho.
Encontrar Responsável de um Filho
GET /RelatedPerson?patient=Patient/{id_filho}&relationship=PRN
O campo identifier no resultado contém o ID do Paciente responsável.
Criar Relacionamento Bidirecional
Para um relacionamento responsável-filho, crie dois recursos RelatedPerson:
1. Vinculado ao Responsável (permite "encontrar meus filhos"):
curl -X POST "https://server/fhir/R4/RelatedPerson" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "RelatedPerson",
"patient": {"reference": "Patient/parent-123"},
"relationship": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
"code": "CHILD"
}]
}],
"name": [{"family": "Smith", "given": ["Junior"]}],
"identifier": [{
"system": "http://example.org/fhir/related-person-patient",
"value": "child-456"
}]
}'
2. Vinculado ao Filho (permite "encontrar meu responsável"):
curl -X POST "https://server/fhir/R4/RelatedPerson" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "RelatedPerson",
"patient": {"reference": "Patient/child-456"},
"relationship": [{
"coding": [{
"system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
"code": "PRN"
}]
}],
"name": [{"family": "Smith", "given": ["John"]}],
"identifier": [{
"system": "http://example.org/fhir/related-person-patient",
"value": "parent-123"
}]
}'
Operações em Lote
Crie múltiplos recursos atomicamente usando um Bundle de transação.
POST /
Content-Type: application/fhir+json
Exemplo - Criar múltiplas observações:
curl -X POST "https://server/fhir/R4/" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Observation",
"status": "final",
"code": {"coding": [{"system": "http://loinc.org", "code": "8310-5"}]},
"subject": {"reference": "Patient/patient-123"},
"effectiveDateTime": "2024-01-15T10:30:00Z",
"valueQuantity": {"value": 37.2, "unit": "Cel"}
},
"request": {"method": "POST", "url": "Observation"}
},
{
"resource": {
"resourceType": "Observation",
"status": "final",
"code": {"coding": [{"system": "http://loinc.org", "code": "9279-1"}]},
"subject": {"reference": "Patient/patient-123"},
"effectiveDateTime": "2024-01-15T10:30:00Z",
"valueQuantity": {"value": 18, "unit": "/min"}
},
"request": {"method": "POST", "url": "Observation"}
}
]
}'
Padrões Comuns
Fluxo de Busca de ID do Paciente
O HealthPass armazena o ID do Paciente FHIR nos campos de contato. Ao fazer chamadas de API:
- Obter ID do Paciente do contato:
contact.fhir_patient_id - Usar nas chamadas de API:
patient=Patient/{fhir_patient_id}
Deduplicação
Recursos de Paciente são criados com criação condicional para evitar duplicatas:
POST /Patient
If-None-Exist: telecom=+27821234567
Registro Mais Recente
Para observações, condições e medicamentos, use ordenação para obter o mais recente:
GET /Observation?patient=Patient/{id}&_sort=-_lastUpdated&_count=1
Paginação
Use _count e _offset para paginação:
GET /Patient?name=Smith&_count=20&_offset=40
A resposta do Bundle inclui total para a contagem completa.
Tratamento de Erros
Erros retornam um recurso OperationOutcome:
{
"resourceType": "OperationOutcome",
"issue": [
{
"severity": "error",
"code": "not-found",
"diagnostics": "Patient/invalid-id not found"
}
]
}
| Status HTTP | Significado |
|---|---|
| 200 | Sucesso (leitura/busca/criação condicional correspondeu) |
| 201 | Criado |
| 400 | Requisição inválida (recurso inválido) |
| 401 | Não autorizado |
| 404 | Recurso não encontrado |
| 422 | Entidade não processável (validação falhou) |
Referência Rápida
| Operação | Endpoint | Método |
|---|---|---|
| Buscar pacientes | /Patient?{params} | GET |
| Ler paciente | /Patient/{id} | GET |
| Criar paciente | /Patient | POST |
| Atualizar paciente | /Patient/{id} | PUT |
| Buscar observações | /Observation?patient=Patient/{id} | GET |
| Criar observação | /Observation | POST |
| Buscar condições | /Condition?patient=Patient/{id} | GET |
| Criar condição | /Condition | POST |
| Buscar medicamentos | /MedicationRequest?patient=Patient/{id} | GET |
| Criar medicamento | /MedicationRequest | POST |
| Buscar agendamentos | /Appointment?patient=Patient/{id} | GET |
| Criar agendamento | /Appointment | POST |
| Atualizar agendamento | /Appointment/{id} | PUT |
| Buscar profissionais | /Practitioner?name:contains={nome} | GET |
| Encontrar filhos | /RelatedPerson?patient=Patient/{id}&relationship=CHILD | GET |
| Encontrar responsável | /RelatedPerson?patient=Patient/{id}&relationship=PRN | GET |
| Lote/Transação | / | POST |