Skip to navigation

Mensagem enviada

Uma mensagem enviada é o que a equipe e o paciente trocaram na conversa: o texto, o anexo, quando saiu e quando chegou.

No FHIR o recurso é a Communication.

Este recurso é somente leitura. Não existe POST /fhir/resources/Communication — não há como enviar mensagem a um paciente por esta API.

Campos

Todos os campos são de resposta — nenhum deles é enviado por você.

CampoSempre presenteO que significa
resourceTypesimConstante Communication
identifiersimIdentificador Nilo da mensagem
statussimSituação de entrega — veja abaixo
medium[0]simConstante REMOTE, com display e text iguais a remote presence
sentquase sempreQuando a mensagem foi enviada
receivednãoQuando foi entregue
senderquase sempreQuem enviou: um Practitioner nas mensagens da equipe, um Patient nas do paciente. Ausente quando a mensagem da equipe não registrou autor
recipient[]nãoOs pacientes da conversa — só nas mensagens da equipe
payload[]nãoO texto e o anexo
id · metasimIdentificador Nilo FHIR do recurso e metadados da gravação

status é entrega, não leitura

ValorO que aconteceu
preparationA mensagem está na fila
in-progressEstá saindo
completedFoi enviada, entregue ou lida
not-doneFalhou

completed junta três coisas diferentes. Enviada, entregue e lida colapsam no mesmo valor: não há como saber, por este campo, se o paciente leu a mensagem.

O que dá alguma pista é o received, que só aparece quando a entrega foi confirmada — mas leitura não tem campo nenhum.

Quem enviou e quem recebeu

Mensagem do paciente vem sem destinatário. Só as mensagens enviadas pela equipe trazem recipient[]. Numa mensagem recebida, o campo simplesmente não vem — a plataforma não registra para quem, dentro da equipe, ela foi.

E uma mensagem da equipe também pode vir sem recipient: quando a conversa não resolve nenhum paciente, a lista sai vazia e some da resposta. Ausência de recipient não distingue, sozinha, quem enviou — para isso, olhe o type do sender.

Numa mensagem do paciente, o sender é o primeiro paciente da conversa, não necessariamente quem escreveu. Numa conversa com mais de um paciente — o que acontece em conversas familiares —, isso pode apontar para a pessoa errada.

Não use o sender de uma mensagem recebida para atribuir autoria.

Uma conversa resolve no máximo 50 pacientes. Acima disso, os destinatários excedentes são omitidos em silêncio do recipient[]. Numa conversa grande, a lista que você recebe é incompleta e não há sinal disso na resposta.

O conteúdo

payload[] traz até dois itens: um com contentString, para o texto, e outro com contentAttachment, para o anexo.

Uma mensagem só com anexo vem com um item só; uma mensagem sem texto e sem anexo vem sem payload. E o anexo é uma referência ao arquivo, não o conteúdo dele.

Campos que a Nilo não usa

A Communication canônica traz muito mais: basedOn, partOf, inResponseTo, category, priority, subject, topic, about, encounter, reasonCode, reasonReference e note. Nenhum deles é lido.

Repare em inResponseTo e em partOf: não há como reconstruir a thread da conversa por esta API. As mensagens vêm soltas, e a única forma de agrupá-las é pelo par de participantes e pela ordem de sent.

E repare em subject: numa mensagem da equipe, o paciente está em recipient; numa do paciente, em sender. Não há um campo único que diga “de quem é esta conversa”.

Buscar

GET
/fhir/resources/Communication
curl -G https://landing-zone-api.nilo.services/fhir/resources/Communication \
-H "x-api-key: <apiKey>" \
-d _count=50 \
-d _lastUpdated=eq2013-01-14 \
--data-urlencode identifier=https://landing-zone-api.nilo.services/fhir/resources/NamingSystem/parrot-api--whats-app-message|9911204 \
-d received=ge2026-07-01 \
--data-urlencode recipient=Patient/ba200cfa-dae0-46cf-81a0-008e3f7414b4 \
--data-urlencode recipient:identifier=https://www.acmesaude.com.br/integracao/paciente/|507823709 \
--data-urlencode sender=Practitioner/1f30c8b7-45ad-4e62-9c81-73b0e5f24a19 \
--data-urlencode sender:identifier=https://www.acmesaude.com.br/integracao/profissional/|5032932 \
-d sent=ge2026-07-01 \
-d status=completed

A resposta é sempre um Bundle do tipo searchset:

Response
{
"resourceType": "Bundle",
"type": "searchset",
"entry": [
{
"fullUrl": "https://landing-zone-api.nilo.services/fhir/resources/Communication/a3f802d6-71b4-4e59-9c07-52d148ba3e91",
"resource": {
"resourceType": "Communication",
"identifier": [
{
"system": "https://landing-zone-api.nilo.services/fhir/resources/NamingSystem/parrot-api--whats-app-message",
"value": "9911204",
"use": "usual"
}
],
"status": "completed",
"id": "a3f802d6-71b4-4e59-9c07-52d148ba3e91",
"meta": {
"lastUpdated": "2026-07-02T14:31:13.004000Z",
"versionId": "MTc4NjAyMTQ1MjkwNTAwMDM2Nw"
},
"medium": [
{
"coding": [
{
"code": "REMOTE",
"display": "remote presence",
"system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationMode"
}
],
"text": "remote presence"
}
],
"sent": "2026-07-02T14:31:08+00:00",
"received": "2026-07-02T14:31:12+00:00",
"sender": {
"identifier": {
"system": "https://www.acmesaude.com.br/integracao/profissional/",
"value": "5032932",
"use": "usual"
},
"type": "Practitioner",
"reference": "Practitioner/1f30c8b7-45ad-4e62-9c81-73b0e5f24a19"
},
"recipient": [
{
"identifier": {
"system": "https://www.acmesaude.com.br/integracao/paciente/",
"value": "507823709",
"use": "usual"
},
"type": "Patient",
"reference": "Patient/ba200cfa-dae0-46cf-81a0-008e3f7414b4"
}
],
"payload": [
{
"contentString": "Bom dia! Sua consulta é amanhã às 14h."
}
]
},
"search": {
"mode": "match"
}
},
{
"fullUrl": "https://landing-zone-api.nilo.services/fhir/resources/Communication/7e40b915-c2d8-4a63-81f7-06e93a2c5478",
"resource": {
"resourceType": "Communication",
"identifier": [
{
"system": "https://landing-zone-api.nilo.services/fhir/resources/NamingSystem/parrot-api--whats-app-message",
"value": "9911207",
"use": "usual"
}
],
"status": "completed",
"id": "7e40b915-c2d8-4a63-81f7-06e93a2c5478",
"meta": {
"lastUpdated": "2026-07-02T14:40:55.318000Z",
"versionId": "MTc4NjAyMTQ1MjkwNTAwMDQwMg"
},
"medium": [
{
"coding": [
{
"code": "REMOTE",
"display": "remote presence",
"system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationMode"
}
],
"text": "remote presence"
}
],
"sent": "2026-07-02T14:40:51+00:00",
"sender": {
"identifier": {
"system": "https://www.acmesaude.com.br/integracao/paciente/",
"value": "507823709",
"use": "usual"
},
"type": "Patient",
"reference": "Patient/ba200cfa-dae0-46cf-81a0-008e3f7414b4"
},
"payload": [
{
"contentString": "Confirmado, obrigada!"
}
]
},
"search": {
"mode": "match"
}
}
],
"link": []
}

Busca sem resultados não é erro: volta 200 com um Bundle cujo entry é uma lista vazia.

Response
{
"resourceType": "Bundle",
"type": "searchset",
"entry": [],
"link": []
}

Parâmetros de busca suportados

NomeTipoDescriçãoExpressão
identifiertokenIdentificador da mensagem, em system|valueCommunication.identifier
sender · sender:identifierreferenceQuem enviouCommunication.sender
recipient · recipient:identifierreferenceQuem recebeuCommunication.recipient
statustokenSituação de entregaCommunication.status
sentdateData de envio, com os prefixos eq, ge, leCommunication.sent
receiveddateData de entrega, com os mesmos prefixosCommunication.received
mediumtokenAceito, e inútil: toda mensagem é REMOTECommunication.medium
_lastUpdateddateData da última gravação no store, com os mesmos prefixos—

Para listar as mensagens de um paciente, você precisa das duas buscas. As que ele recebeu estão em recipient; as que ele enviou, em sender. Não há um parâmetro que cubra os dois.

Os demais parâmetros canônicos da Communication existem e não encontram nada, porque a plataforma não preenche o campo correspondente: based-on, category, encounter, instantiates-canonical, instantiates-uri, part-of, patient e subject.

Repare em patient: o parâmetro canônico procura em Communication.subject, que a Nilo não preenche — use recipient e sender.

Qual identificador as referências de sender e recipient carregam depende da sua implantação. Na configuração que usa identificadores externos, cada referência sai com o identificador do seu sistema; sem ela, vem o identificador Nilo. Confira numa resposta de leitura antes de montar a busca em volume.

A paginação é por _count e _page_token; havendo página seguinte, o Bundle traz a URL pronta em link.

Ler por ID

GET
/fhir/resources/Communication/:id
curl https://landing-zone-api.nilo.services/fhir/resources/Communication/id \
-H "x-api-key: <apiKey>"

Diferente da busca, esta leitura não devolve um Bundle — mas também não devolve o recurso nu. A resposta é um envelope com fullUrl, search e resource, e a mensagem está em resource.

Response
{
"fullUrl": "https://landing-zone-api.nilo.services/fhir/resources/Communication/a3f802d6-71b4-4e59-9c07-52d148ba3e91",
"resource": {
"resourceType": "Communication",
"identifier": [
{
"system": "https://landing-zone-api.nilo.services/fhir/resources/NamingSystem/parrot-api--whats-app-message",
"value": "9911204",
"use": "usual"
}
],
"status": "completed",
"id": "a3f802d6-71b4-4e59-9c07-52d148ba3e91",
"meta": {
"lastUpdated": "2026-07-02T14:31:13.004000Z",
"versionId": "MTc4NjAyMTQ1MjkwNTAwMDM2Nw"
},
"medium": [
{
"coding": [
{
"code": "REMOTE",
"display": "remote presence",
"system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationMode"
}
],
"text": "remote presence"
}
],
"sent": "2026-07-02T14:31:08+00:00",
"received": "2026-07-02T14:31:12+00:00",
"sender": {
"identifier": {
"system": "https://www.acmesaude.com.br/integracao/profissional/",
"value": "5032932",
"use": "usual"
},
"type": "Practitioner",
"reference": "Practitioner/1f30c8b7-45ad-4e62-9c81-73b0e5f24a19"
},
"payload": [
{
"contentString": "Bom dia! Sua consulta é amanhã às 14h."
}
]
},
"search": {
"mode": "match"
}
}

Cadastrar ou atualizar

Não existe. Este recurso não tem caminho de escrita nesta API.

Um POST /fhir/resources/Communication não é uma operação suportada e não devolve um erro de validação tratável: a chamada falha com erro inesperado do servidor (500). Não escreva tratamento em cima desse comportamento — ele não é contrato, e nada é gravado.

O que a integração não cobre

  • enviar mensagem a um paciente;
  • a thread da conversa — não há inResponseTo nem partOf;
  • se o paciente leu a mensagem;
  • o destinatário de uma mensagem recebida;
  • os pacientes além do quinquagésimo numa conversa grande;
  • o conteúdo do anexo — só a referência a ele.

Para as mensagens que a plataforma vai enviar, veja Mensagem programada.