Pular para o conteúdo principal

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.

Versão Alpha

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

  1. Visão Geral
  2. Autenticação
  3. Endpoints de Paciente
  4. Endpoints de Observação
  5. Endpoints de Condição
  6. Endpoints de MedicationRequest
  7. Endpoints de Agendamento
  8. Endpoints de Profissional
  9. Endpoints de RelatedPerson
  10. Operações em Lote
  11. 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âmetroDescriçãoExemplo
identifierID Nacional ou MRN9001015009087
nameCorrespondência parcial de nomeSmith
telecomNúmero de telefone+27821234567
_countMá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 Created se novo paciente for criado
  • Retorna 200 OK se 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âmetroDescriçãoExemplo
patientReferência do paciente (obrigatório)Patient/patient-123
codeCódigos LOINC/SNOMED (separados por vírgula)8310-5,9279-1
categoryCategoria da observaçãovital-signs
_sortOrdem de classificação-_lastUpdated
_countMáximo de resultados50

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âmetroDescriçãoExemplo
patientReferência do paciente (obrigatório)Patient/patient-123
clinical-statusFiltrar por statusactive
_sortOrdem 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âmetroDescriçãoExemplo
patientReferência do paciente (obrigatório)Patient/patient-123
statusStatus da prescriçãoactive
_sortOrdem 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âmetroDescriçãoExemplo
patientReferência do pacientePatient/patient-123
actorQualquer participante (paciente, profissional, local)Practitioner/prac-456
statusStatus do agendamentobooked
dateFiltro de data (suporta ge, le, gt, lt)ge2024-01-01
_sortOrdem 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âmetroDescriçãoExemplo
name:containsCorrespondência parcial de nomeSmith
specialty:textBusca por texto de especialidadeCardiology
_countMáximo de resultados10
_sortOrdem de classificaçãoname

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:

  1. Obter ID do Paciente do contato: contact.fhir_patient_id
  2. 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 HTTPSignificado
200Sucesso (leitura/busca/criação condicional correspondeu)
201Criado
400Requisição inválida (recurso inválido)
401Não autorizado
404Recurso não encontrado
422Entidade não processável (validação falhou)

Referência Rápida

OperaçãoEndpointMétodo
Buscar pacientes/Patient?{params}GET
Ler paciente/Patient/{id}GET
Criar paciente/PatientPOST
Atualizar paciente/Patient/{id}PUT
Buscar observações/Observation?patient=Patient/{id}GET
Criar observação/ObservationPOST
Buscar condições/Condition?patient=Patient/{id}GET
Criar condição/ConditionPOST
Buscar medicamentos/MedicationRequest?patient=Patient/{id}GET
Criar medicamento/MedicationRequestPOST
Buscar agendamentos/Appointment?patient=Patient/{id}GET
Criar agendamento/AppointmentPOST
Atualizar agendamento/Appointment/{id}PUT
Buscar profissionais/Practitioner?name:contains={nome}GET
Encontrar filhos/RelatedPerson?patient=Patient/{id}&relationship=CHILDGET
Encontrar responsável/RelatedPerson?patient=Patient/{id}&relationship=PRNGET
Lote/Transação/POST