Skip to content

Event Types & Sample Events

The events Spry can deliver to a webhook subscription, with sample payloads in the current 2026-06-11 minimized format. A single subscription can listen to any combination of these events.

event_type Fired when
patient.created A patient is registered
patient.updated A patient's profile is updated
patient.discharged A patient is discharged (their status becomes DISCHARGED). Fires instead of patient.updated for that change.
appointment.created An appointment is booked
appointment.updated An appointment is modified (status change, reschedule, check-in)
appointment.cancelled An appointment is cancelled
case.created A patient case (plan of care) is opened
case.updated A patient case is modified (insurance, referring physician, status, body parts, …) — excluding discharge, which fires case.discharged instead
case.discharged A patient case is discharged (its treatment status becomes DISCHARGED). Fires instead of case.updated for that change.
lead.created A lead is raised, which happens when a case is created for a patient
lead.updated A lead's status changes, or it moves between stages — excluding a move into a terminal stage, which fires lead.dropped / lead.converted instead
lead.dropped A lead is dropped — by Drop Lead, or automatically if still open 31 days after it was raised. Terminal — the case never gets another lead
lead.converted An appointment is booked against the lead's case. Terminal
soap.created A SOAP note is created for an appointment
soap.updated A SOAP note is edited after creation, while still in progress (before completion)
soap.completed A SOAP note is marked completed
soap.deleted A SOAP note is deleted

Each payload follows the common envelope. The minimized format carries only identifiers under data — no status and no PHI — look up the full record from the Spry API by id.

Patient Events

patient.created, patient.updated, and patient.discharged carry the patient identifier only.

patient.discharged vs patient.updated: a patient discharge fires only patient.discharged, never patient.updated. Subscribe to patient.discharged explicitly if you want to be notified of patient discharges.

data Fields

Field Type Description
organisation_id integer Owning organisation
patient_id integer Spry patient identifier — look the patient up via the Spry API

Sample — patient.updated

{
  "event_id": "evt_3d1fa7e8-1234-4567-89ab-cdef01234567",
  "event_type": "patient.updated",
  "api_version": "2026-06-11",
  "timestamp": 1776249887,
  "data": {
    "organisation_id": 74,
    "patient_id": 45741
  }
}

Sample — patient.discharged

Same shape as patient.updated — only event_type differs. Fetch the patient from the Spry API to confirm its (now DISCHARGED) status.

{
  "event_id": "evt_9a4c2e11-aaaa-bbbb-cccc-1234567890ab",
  "event_type": "patient.discharged",
  "api_version": "2026-06-11",
  "timestamp": 1783058137,
  "data": {
    "organisation_id": 74,
    "patient_id": 73265
  }
}

Appointment Events

appointment.created, appointment.updated, and appointment.cancelled carry the appointment and related identifiers.

data Fields

Field Type Description
organisation_id integer Owning organisation
appointment_id integer Spry appointment identifier — look the appointment up via the Spry API
patient_id integer Patient the appointment belongs to
spry_case_id string Linked plan-of-care case (SPRY_CASE_<id>)
clinic_id integer Clinic the appointment belongs to

Sample — appointment.updated

{
  "event_id": "evt_8f3a2b9c-1234-4567-89ab-cdef01234567",
  "event_type": "appointment.updated",
  "api_version": "2026-06-11",
  "timestamp": 1776246130,
  "data": {
    "organisation_id": 74,
    "appointment_id": 113191,
    "patient_id": 45675,
    "spry_case_id": "SPRY_CASE_69d778fa05e30511a1a2b282",
    "clinic_id": 44
  }
}

Fetch the appointment's current status from the Spry API using data.appointment_id. Appointment status values are: CONFIRMED, PATIENT_CHECKIN, IN_PROGRESS, COMPLETED, CANCELLED, NO_SHOW.

Case Events

A case is a patient's plan-of-care container — it ties a patient to a specialization, referring physician, insurance cards, ICD/CPT codes, and treatment status. case.created, case.updated, and case.discharged carry the case and patient identifiers.

case.discharged vs case.updated: a discharge fires only case.discharged, never case.updated — the same way a cancellation fires only appointment.cancelled. Subscribe to case.discharged explicitly if you want to be notified of discharges.

data Fields

Field Type Description
organisation_id integer Owning organisation
spry_case_id string Canonical Spry case identifier (SPRY_CASE_<id>) — look the case up via the Spry API
patient_id integer Patient the case belongs to

Sample — case.updated

{
  "event_id": "evt_2c9f1a7b-aaaa-bbbb-cccc-1234567890ab",
  "event_type": "case.updated",
  "api_version": "2026-06-11",
  "timestamp": 1781153619,
  "data": {
    "organisation_id": 74,
    "spry_case_id": "SPRY_CASE_6a2a3ee88546243488bdd2e1",
    "patient_id": 48998
  }
}

Sample — case.discharged

Same shape as case.updated — only event_type differs. Fetch the case from the Spry API to confirm its (now DISCHARGED) treatment status.

{
  "event_id": "evt_7b2e9d10-aaaa-bbbb-cccc-1234567890ab",
  "event_type": "case.discharged",
  "api_version": "2026-06-11",
  "timestamp": 1781696608,
  "data": {
    "organisation_id": 74,
    "spry_case_id": "SPRY_CASE_6a17ebbe7f9a807bc2fbce0a",
    "patient_id": 27227
  }
}

Lead Events

A lead is a prospective patient's journey from first contact to a booked appointment. A lead belongs to exactly one case and a case has exactly one lead, ever. lead.created, lead.updated, lead.dropped and lead.converted carry the lead, patient, case and clinic identifiers.

Terminal events fire instead of lead.updated: a lead being dropped or converted fires only lead.dropped or lead.converted, the same way a discharge fires only case.discharged. Subscribe to them explicitly.

Not every change to a lead is an event. Assignment, eligibility and authorization update the lead without emitting anything, and intake progress emits lead.updated only when it moves the lead out of NEW. lead.updated tracks the status and the stage only — read Get Lead if you need the rest.

data Fields

Field Type Description
organisation_id integer Owning organisation
lead_id string The lead (UUID)
patient_id integer or null The patient
spry_case_id string or null The lead's case. Null for a lead raised before cases owned leads, until one attaches
clinic_id integer or null Null when the case never named a clinic

Sample — lead.converted

{
  "event_id": "evt_bcf02f49-d4be-4219-9979-a7bfeb889150",
  "event_type": "lead.converted",
  "api_version": "2026-06-11",
  "timestamp": 1789984697,
  "data": {
    "organisation_id": 1376,
    "lead_id": "15d5e85a-d934-4791-9d48-4933311b1792",
    "patient_id": 185781,
    "spry_case_id": "SPRY_CASE_6aace0cf2e2a3b23cbb34ab4",
    "clinic_id": 1467
  }
}

Every lead event has this shape; only event_type differs. Read the lead from the Spry API with data.lead_id — the payload carries no status, so the record you fetch is always current.

SOAP Events

A SOAP context is the clinical-documentation record for an appointment — it tracks the subjective/objective/assessment/plan submissions, note type, completion and billing state, and the supervising/rendering/billing providers. soap.created, soap.updated, soap.completed, and soap.deleted all carry the same identifiers — only event_type differs.

data Fields

Field Type Description
organisation_id integer Owning organisation
soap_context_id string Canonical SOAP-context id — look this up via the Spry API for the full note
patient_id integer Patient the note is for
appointment_id integer Appointment the note documents
spry_case_id string Case (SPRY_CASE_<id>) the note belongs to
clinic_id integer Clinic the note belongs to

Sample — soap.created

{
  "event_id": "evt_3f1c8a2d-aaaa-bbbb-cccc-1234567890ab",
  "event_type": "soap.created",
  "api_version": "2026-06-11",
  "timestamp": 1782125075,
  "data": {
    "organisation_id": 1270,
    "soap_context_id": "6a391213c356060e8fe73159",
    "patient_id": 56751,
    "appointment_id": 124775,
    "spry_case_id": "SPRY_CASE_6a38fc1c4cedb3798667fa7a",
    "clinic_id": 1333
  }
}

No clinical content, status, or provider details leave Spry in a SOAP webhook payload. For soap.deleted, the ids describe the note that was removed — it will no longer resolve via the Spry API.

Test Webhook

A test webhook uses the same envelope but adds "test": true to the payload so you can ignore test deliveries in production code paths.