Event Notifications

What is a Notification?

Most interactions with the Particle Platform are synchronous. A user makes a request and we respond immediately. However, a subset of interactions with the Particle Platform are asynchronous. A user will submit a request and, after a variable length of time, Particle will complete the request and have a response for the user. This is prevalent in our patient query flows where the query completion status is pending and customers "poll" for the status of a query.

Notifications change this relationship. Instead of the user checking for status of an operation (e.g. FHIR query completion), Particle will send a proactive notification to the customer letting them know what the new status is (e.g. a FHIR query has finished processing).

Notifications are also a critical part of the new Patient Monitoring feature offered by Particle. Clients register a cohort of patients to be monitored on an ongoing basis for any net new data available on the networks and/or for critical admission events (i.e., ADTs) at any of care facility within Particle's network. A notification is delivered when new data is available and/or an ADT event occurs for the patient.

Registering to receive Notifications

If you are interested in utilizing the Particle notifications service, please reach out to your Particle Health representative and we're happy to get you set up!

The first step toward getting set up with Particle Notifications is to configure a web service that can receive a notification webhook. After we register this callback URL in our systems, Particle will generate a signature key that is used to sign the Notification payloads.

Notifications are currently used for query status alerts for (1) any queries initiated by a customer; and (2) any queries that Particle has initiated and retrieved net new data from, as part of Patient Monitoring. Notifications are also used for ADT alerts.

Query Status Notifications

When a query completes, the registered web service will receive a notification in the form of a JSON payload. You will receive the same query-complete notification payload whenever Particle has retrieved net new data for a patient that you've subscribed to Patient Monitoring. An example of this payload can be found below:

{
  "specversion":"1.0",
  id: "f834539f-a839-490b-80f9-b441cb9e435d",
  source: "api/notifications",
  "type":"com.particlehealth.api.v1.query",
  "datacontenttype":"application/json",
  "time":"2023-05-15T12:00:14.694292853Z",
  "data":{
    file_count: "2",
    patient_id: "9557a65e-55b7-4a3b-b0a1-f4dd2df5a2f8",
    person_id: "75c771c5-600e-4c4b-a4e9-f932fa2827aa",
    purpose: "TREATMENT",
    query_id: "50ee4bd4-bd87-4e66-bab1-7e0309a9a656",
    status: "COMPLETE"
  }
}

ADT Notifications

When a new ADT alert is available for a patient, the registered web service will receive a notification in the form of a JSON payload. An example of this payload can be found below:

{
  "specversion":"1.0",
  id: "b84def23-1a04-4ba8-91ac-ee6ed8940ab6",
  source: "api/notifications",
  "type":"com.particlehealth.api.v1.hl7v2",
  "datacontenttype":"application/json",
  "time":"2022-10-26T15:48:56.137897511Z",
  "data":{
    message_id: "4801fa0e-70c9-4f5c-94aa-c5eeea311a99",
    patient_id: "MER20022556611" 
  }
}

HTTP Headers

Notifications are sent as HTTP Post requests. These requests will contain the following key headers:

Accept:[*/*] 
Content-Type:[application/cloudevents+json] 
X-Ph-Signature-256:[t=1684152014,53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab]

Particle Health Notifications follow the Cloud Events spec and therefore set the content-type header value to application/cloudevents+json

Notification Signatures

Particle Health Notifications are signed with a signature key generated during notification callback URL registration. This helps Notification consumers determine the validity of requests sent to the callback URL.

Our webhook signature has the following schema and follows the HMAC SHA-256 algorithm:

HTTP Header = x-ph-signature-256

HTTP Header Values = t=nnn,signature1,signature2

t=nnn represents the timestamp when the notification was created and signature1 is the signature generated using an unexpired signature key (provided by Particle). Additional signatures may be present if a signature key has been recently rotated. This allows a grace period during which the notification receiver may make changes to accommodate for the updated signature key.

Signature Verification Process (example)

Signature Key = $ec0u3LdusDFkXRAaetAMUg$+3G9w4/u9qPfnmXrEFUnEcADabLozyhvrPn7xokxpOw

x-ph-signature-256

Header: t=1684152014,53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab

Query Complete Notification JSON Body:

{"specversion":"1.0","id":"f834539f-a839-490b-80f9-b441cb9e435d","source":"api/notifications","type":"com.particlehealth.api.v1.query","datacontenttype":"application/json","time":"2023-05-15T12:00:14.694292853Z","data":{"file_count":"2","patient_id":"9557a65e-55b7-4a3b-b0a1-f4dd2df5a2f8","person_id":"75c771c5-600e-4c4b-a4e9-f932fa2827aa","purpose":"TREATMENT","query_id":"50ee4bd4-bd87-4e66-bab1-7e0309a9a656","status":"COMPLETE"}}
  1. Extract the signature (53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab) from the x-ph-signature-256 header.

  2. Isolate the timestamp t=1684152014 from the x-ph-signature-256 header.

  3. Extract the JSON body of the notification message from the incoming Query Complete Notification

  4. Generate an HMAC signature string by joining the timestamp value ( 1684152014) extracted in step 2 with the notification body extracted in step 3, separated by a period (.). The string should follow the format unix_timestamp.notification_json_body

  5. Use your signature key ($ec0u3LdusDFkXRAaetAMUg$+3G9w4/u9qPfnmXrEFUnEcADabLozyhvrPn7xokxpOw) and the HMAC SHA-256 algorithm to generate the HMAC signature.

  6. Compare this generated signature with the signature value in the header (extracted in step 1 - 53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab)

  7. If the signatures match, the notification was sent by Particle Health and wasn’t altered during transmission.

Notifications samples

Signature Key

$ec0u3LdusDFkXRAaetAMUg$+3G9w4/u9qPfnmXrEFUnEcADabLozyhvrPn7xokxpOw

C-CDA Query Complete Notification

eyJzcGVjdmVyc2lvbiI6IjEuMCIsImlkIjoiZjgzNDUzOWYtYTgzOS00OTBiLTgwZjktYjQ0MWNiOWU0MzVkIiwic291cmNlIjoiYXBpL25vdGlmaWNhdGlvbnMiLCJ0eXBlIjoiY29tLnBhcnRpY2xlaGVhbHRoLmFwaS52MS5xdWVyeSIsImRhdGFjb250ZW50dHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0aW1lIjoiMjAyMy0wNS0xNVQxMjowMDoxNC42OTQyOTI4NTNaIiwiZGF0YSI6eyJmaWxlX2NvdW50IjoiMiIsInBhdGllbnRfaWQiOiI5NTU3YTY1ZS01NWI3LTRhM2ItYjBhMS1mNGRkMmRmNWEyZjgiLCJwZXJzb25faWQiOiI3NWM3NzFjNS02MDBlLTRjNGItYTRlOS1mOTMyZmEyODI3YWEiLCJwdXJwb3NlIjoiVFJFQVRNRU5UIiwicXVlcnlfaWQiOiI1MGVlNGJkNC1iZDg3LTRlNjYtYmFiMS03ZTAzMDlhOWE2NTYiLCJzdGF0dXMiOiJDT01QTEVURSJ9fQ

t=1684152014,53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab
{"specversion":"1.0","id":"f834539f-a839-490b-80f9-b441cb9e435d","source":"api/notifications","type":"com.particlehealth.api.v1.query","datacontenttype":"application/json","time":"2023-05-15T12:00:14.694292853Z","data":{"file_count":"2","patient_id":"","person_id":"","purpose":"TREATMENT","query_id":"50ee4bd4-bd87-4e66-bab1-7e0309a9a656","status":"COMPLETE"}}

FHIR Query Complete Notification

eyJzcGVjdmVyc2lvbiI6IjEuMCIsImlkIjoiZjgzNDUzOWYtYTgzOS00OTBiLTgwZjktYjQ0MWNiOWU0MzVkIiwic291cmNlIjoiYXBpL25vdGlmaWNhdGlvbnMiLCJ0eXBlIjoiY29tLnBhcnRpY2xlaGVhbHRoLmFwaS52MS5xdWVyeSIsImRhdGFjb250ZW50dHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0aW1lIjoiMjAyMy0wNS0xNVQxMjowMDoxNC42OTQyOTI4NTNaIiwiZGF0YSI6eyJmaWxlX2NvdW50IjoiMiIsInBhdGllbnRfaWQiOiI5NTU3YTY1ZS01NWI3LTRhM2ItYjBhMS1mNGRkMmRmNWEyZjgiLCJwZXJzb25faWQiOiI3NWM3NzFjNS02MDBlLTRjNGItYTRlOS1mOTMyZmEyODI3YWEiLCJwdXJwb3NlIjoiVFJFQVRNRU5UIiwicXVlcnlfaWQiOiI1MGVlNGJkNC1iZDg3LTRlNjYtYmFiMS03ZTAzMDlhOWE2NTYiLCJzdGF0dXMiOiJDT01QTEVURSJ9fQ
t=1684152014,53d96ec86a554bed6cc4be53189cc5a662d51853da3f8ba067e5b253d12594ab
{"specversion":"1.0","id":"f834539f-a839-490b-80f9-b441cb9e435d","source":"api/notifications","type":"com.particlehealth.api.v1.query","datacontenttype":"application/json","time":"2023-05-15T12:00:14.694292853Z","data":{"file_count":"2","patient_id":"9557a65e-55b7-4a3b-b0a1-f4dd2df5a2f8","person_id":"75c771c5-600e-4c4b-a4e9-f932fa2827aa","purpose":"TREATMENT","query_id":"50ee4bd4-bd87-4e66-bab1-7e0309a9a656","status":"COMPLETE"}}

ADT Message Notification

eyJzcGVjdmVyc2lvbiI6IjEuMCIsImlkIjoiYjg0ZGVmMjMtMWEwNC00YmE4LTkxYWMtZWU2ZWQ4OTQwYWI2Iiwic291cmNlIjoiYXBpL25vdGlmaWNhdGlvbnMiLCJ0eXBlIjoiY29tLnBhcnRpY2xlaGVhbHRoLmFwaS52MS5obDd2MiIsImRhdGFjb250ZW50dHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJ0aW1lIjoiMjAyMi0xMC0yNlQxNTo0ODo1Ni4xMzc4OTc1MTFaIiwiZGF0YSI6eyJtZXNzYWdlX2lkIjoiNDgwMWZhMGUtNzBjOS00ZjVjLTk0YWEtYzVlZWVhMzExYTk5IiwicGF0aWVudF9pZCI6Ik1FUjIwMDIyNTU2NjExIn19

t=1666799336,b1fcd064b1a163afb4defe2b80278c06005111aa81c82cc34fc5229dd08f00dc
{"specversion":"1.0","id":"b84def23-1a04-4ba8-91ac-ee6ed8940ab6","source":"api/notifications","type":"com.particlehealth.api.v1.hl7v2","datacontenttype":"application/json","time":"2022-10-26T15:48:56.137897511Z","data":{"message_id":"4801fa0e-70c9-4f5c-94aa-c5eeea311a99","patient_id":"MER20022556611"}}