Cobertura de saúde
Cobertura de saúde
O Coverage representa o vínculo do paciente com
um plano de saúde, convênio ou benefício — quem custeia o atendimento, com que carteirinha
e por quanto tempo. Um paciente pode ter várias coberturas ao mesmo tempo, e a ordem entre
elas diz qual usar primeiro.
A cobertura não vive sozinha: ela sempre aponta para um Patient já cadastrado, e o plano
que ela nomeia é um InsurancePlan do catálogo do seu care provider. Nenhum dos dois é
criado pela escrita da cobertura.
Campos
A coluna No NiloCare traz o rótulo com que o dado aparece para a equipe de cuidado. São rótulos, não caminhos de navegação: a tela pode ser reorganizada, o rótulo é o que permite conferir se o dado chegou onde você esperava.
1 payor é obrigatório na especificação FHIR R4 e um payload sem ele é recusado,
mas o valor enviado não é gravado: a leitura devolve sempre Operadora.
2 Nenhum destes três é obrigatório isoladamente, mas a cobertura precisa de um
plano ou uma carteirinha — os dois vazios recusam a escrita. Qual dos dois campos de
carteirinha usar depende do relationship; veja
Titular e dependente.
A URL completa da extensão está em Extensões — nesta página ela aparece só pelo nome final.
Relação com titular aparece como opcional no formulário do NiloCare, mas relationship é
obrigatório na API: sem ele a escrita é recusada. Se a sua carga não distingue titular de
dependente, envie self.
Campos do Coverage que a Nilo não usa
O Coverage canônico tem campos que esta integração não lê nem grava: type, subscriber,
network, contract, costToBeneficiary e subrogation. Eles ficam fora da referência de
propósito. Enviá-los não é erro — o valor é gravado no recurso FHIR e volta nas leituras
seguintes —, mas nada no NiloCare passa a exibi-los.
Cadastrar ou atualizar
Não há endpoint separado para criar e atualizar. O mesmo POST faz os dois, e quem decide é o
identifier: se já existir uma cobertura com aquele par system + value, ela é atualizada;
se não existir, é criada.
A resposta devolve o recurso como ficou gravado:
Guarde o id: é por ele que se faz a leitura direta da cobertura. A resposta traz também o
identificador Nilo da cobertura (…/NamingSystem/hippocrates-api--coverage) ao lado do seu —
os dois servem para buscar, e o seu continua sendo o único que você precisa guardar.
A atualização de cobertura substitui, não complementa. Diferente do Patient, um campo
omitido não preserva o valor atual — a API grava a cobertura com o que o payload traz, e
o que ficou de fora é enviado vazio. Para mudar só a vigência, reenvie o payload inteiro com
a vigência nova, não apenas o period.
Ao menos um identifier é obrigatório. Não havendo casamento por identificador, a API ainda
tenta encontrar a cobertura pela chave de negócio antes de criar uma nova — veja
Como a API evita duplicatas.
Titular e dependente
subscriberId e dependent trocam de sentido conforme o relationship. É a fonte de
erro mais comum neste recurso.
Ou seja: a carteirinha do paciente que você está cadastrando vai em subscriberId quando ele
é o titular e em dependent quando não é.
Trocar os dois campos de lugar não gera erro: a escrita passa e a carteirinha fica gravada no
campo errado. Confira o relationship antes de montar a carga.
Plano de saúde
O plano vai no primeiro item de class, com o id do plano em value. O name é
informativo: quem localiza o plano é o value.
A API lê class[0] — o primeiro item da lista, sem olhar o type. Se o seu payload mandar
outra classificação antes do plano, é o value dela que será tomado como id do plano. Envie o
plano como primeiro item, ou envie só ele.
Para descobrir os ids disponíveis, liste os planos do seu ambiente e use o value do
identificador Nilo (…/NamingSystem/care-api--insurance-v2) — veja
Plano de saúde:
Quem não quer carregar o id Nilo do plano pode usar a extensão insurance-plan, que aceita
qualquer identificador de um InsurancePlan já cadastrado — inclusive o do seu próprio
sistema:
Enviando as duas formas ao mesmo tempo, class vence e a extensão é ignorada. E a extensão
não volta na leitura: a resposta traz o plano em class[0]. Reenviar um recurso exatamente
como ele veio numa resposta funciona — mas pelo class, não pela extensão.
class[0].name é uma fotografia, não o nome atual do plano. Ele guarda o nome que o plano
tinha quando esta cobertura foi gravada pela última vez. Se o plano for renomeado depois, a
cobertura continua devolvendo o nome antigo até ser gravada de novo, por qualquer motivo.
Quem localiza o plano é o class[0].value, e esse continua correto. Para o nome atual, leia o
plano de saúde — não o name da cobertura.
Vigência
period.start e period.end são datas. Envie-as como data pura (YYYY-MM-DD): o NiloCare
guarda só a data, e uma data com hora é convertida para o fuso da Nilo antes de a data ser
extraída — o que pode deslocar o dia em um valor próximo da meia-noite.
Ordem
order é a prioridade de uso entre as coberturas do paciente e começa em 1: order: 1 é
a primeira cobertura, a que aparece como Cobertura de saúde 1 na ficha. order: 0 é
recusado pela validação FHIR, que exige um inteiro positivo.
Uma cobertura gravada sem order é lida como order: 1. Com mais de uma cobertura por
paciente, mande o order de todas explicitamente — do contrário todas voltam como primeira.
Buscar
A resposta é sempre um Bundle do tipo searchset, mesmo quando há um único resultado:
Busca sem resultados não é erro: volta 200 com um Bundle cujo entry é uma lista vazia.
Trate a ausência de resultados pela lista vazia, não esperando um 404.
Parâmetros de busca suportados
A busca do dia a dia é a lista de coberturas de um paciente. Com o modificador :identifier
ela usa a chave que você já tem no seu sistema, sem precisar guardar o id Nilo FHIR do
paciente:
Qual identificador do paciente o beneficiary carrega depende da sua implantação. Na
configuração que usa identificadores externos nas referências, é o identificador do seu
sistema — e o filtro acima funciona como está. Sem ela, o beneficiary traz o identificador
Nilo do paciente (…/NamingSystem/hippocrates-api--patient), e é esse system que você tem
de usar no filtro. Confira numa resposta de leitura qual dos dois está lá antes de montar a
busca em volume.
Dois parâmetros canônicos do Coverage existem mas praticamente não encontram nada aqui.
policy-holder casa por referência, e a Nilo grava o estipulante apenas como texto em
policyHolder.display. E o FHIR R4 não define parâmetro para subscriberId: a
carteirinha de um titular não é filtrável — só a de um dependente, por dependent.
Ler por ID
Diferente da busca, a leitura por ID devolve o recurso direto, sem envelope Bundle, e
responde 404 quando o id não existe.
Valores aceitos
relationship.coding[0].code usa o vocabulário
subscriber-relationship do
FHIR R4. Os sete códigos têm rótulo no NiloCare:
Só self tem efeito sobre o comportamento da API — é ele que decide qual campo carrega a
carteirinha do beneficiário. Os outros seis são equivalentes entre si nesse aspecto.
status usa os quatro códigos do FHIR R4:
Numa cobertura criada pela interface e nunca escrita por esta API o status pode estar vazio
do lado Nilo. Nesse caso a leitura o deriva da vigência: cancelled quando o fim de vigência
já passou, active nos outros casos. A escrita nunca deriva — o status que você manda é o
que fica gravado.
O catálogo de planos não é um vocabulário fixo: cada care provider tem os seus, cadastrados na
implantação. Liste-os com GET /fhir/resources/InsurancePlan, como mostrado em Plano de
saúde, acima.
Como a API evita duplicatas
O caminho normal é o identifier, e ele é obrigatório. Mas quando nenhum dos identificadores
enviados encontra uma cobertura, a API tenta uma segunda vez pela chave de negócio — a
combinação de:
- carteirinha do beneficiário (
subscriberIdnum titular,dependentnum dependente); - paciente (
beneficiary); - plano (
class[0].valueou a extensãoinsurance-plan).
Havendo cobertura com os três iguais, ela é atualizada e passa a carregar também o seu identificador. Do contrário, uma nova é criada.
Isso é o que torna seguro integrar coberturas que já existiam no NiloCare antes da integração: a primeira escrita reconhece a cobertura pela carteirinha em vez de duplicá-la. A chave só funciona com os três valores presentes — faltando qualquer um, a API cria uma cobertura nova.
Efeitos colaterais
A escrita de Coverage grava apenas a cobertura. Ela não cria nem altera o paciente, não
cadastra planos e não dispara mensagens.
Este endpoint não remove coberturas: a escrita nunca responde 204. A remoção acontece do
lado Nilo e é propagada para o store FHIR pela sincronização, não por esta API.
Erros
Recusa é sempre 400 com um OperationOutcome: issue[].expression aponta o campo culpado e
issue[].details.text explica o motivo.
O paciente do beneficiary precisa existir. Cadastre-o pelo
Patient antes — a cobertura não o cria:
relationship é obrigatório, e o código tem de estar em coding[0].code. Mandar o campo sem
coding, ou o coding sem code, dá o mesmo erro que omiti-lo:
Toda escrita precisa de ao menos um identifier:
E a cobertura precisa de um plano ou de uma carteirinha. Os dois vazios são recusados — a mesma regra que o formulário do NiloCare aplica ao exigir “o plano de saúde ou número da carteirinha”:
Esse último erro chega da camada de validação sem ser reformulado, e por isso o
details.text é técnico e o code é o genérico exception. Trate-o pela menção a
card_number e insurance_id na mensagem, não pelo texto exato — ele pode mudar.
payor e status são obrigatórios pela especificação FHIR R4, então um payload sem eles é
recusado antes de chegar às regras acima, com um OperationOutcome de código structure
apontando o campo que falta.
O que a integração não cobre
O plano de saúde do paciente não fica no Patient — é sempre um Coverage à parte, ligado a
ele por beneficiary. E o catálogo de planos em si não é criado por esta API: os planos são
cadastrados na implantação, e o que a integração faz com eles é ler e, quando preciso,
corrigir o nome — veja Plano de saúde.

