Create SOAP Note¶
Create a new SOAP note (context) for a patient. The note is created in an incomplete state; subsequent calls populate the assessment (ICD codes), planning section (CPT codes / treatment sheet), and finally mark the note complete.
Endpoint¶
Request Body¶
| Parameter | Type | Required | Description |
|---|---|---|---|
patient_id |
integer | Yes | ID of the patient |
type |
string | Yes | SOAP note type (see Note Types) |
appointment_id |
integer | No | Associated appointment ID. Omit or set to 0 for appointment-free notes |
category |
string | No | Clinical category (e.g. MSK, NEURO) |
spry_case_id |
string | No | Case to attach the note to. If omitted, resolved from the appointment |
attributes |
object | No | Note sub-type overrides (see Attributes) |
parent |
string | No | context_id of the parent note — required when type is ADDENDUM |
soap_without_appointment |
boolean | No | Set to true to create a note without an appointment (default: false) |
data_carry_forward_from |
string | No | context_id of a previous note whose form data should be pre-filled |
Attributes¶
The attributes object supports a subType key to override the effective note type:
attributes.subType |
Effective type stored |
|---|---|
"RE_EVALUATION" |
INITIAL_SOAP |
"simpleDischargeNote" |
DISCHARGE_NOTE |
Request¶
Standard appointment-based note¶
curl --location --request POST '{base_url}/apis/hep/v2/soap-context' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"patient_id": 1001,
"type": "INITIAL_SOAP",
"appointment_id": 9001,
"category": "MSK",
"spry_case_id": "SPRY_CASE_69cd0c97e7562d613ea89bc7",
"attributes": {}
}'
Appointment-free note¶
curl --location --request POST '{base_url}/apis/hep/v2/soap-context' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"patient_id": 1001,
"type": "FOLLOWUP_SOAP",
"category": "MSK",
"spry_case_id": "SPRY_CASE_69cd0c97e7562d613ea89bc7",
"soap_without_appointment": true,
"attributes": {}
}'
Addendum to an existing note¶
curl --location --request POST '{base_url}/apis/hep/v2/soap-context' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"patient_id": 1001,
"type": "ADDENDUM",
"appointment_id": 9001,
"category": "MSK",
"spry_case_id": "SPRY_CASE_69cd0c97e7562d613ea89bc7",
"parent": "abc123def456",
"attributes": {}
}'
Response¶
Success Response¶
Code: 200 OK
{
"code": 2000,
"data": {
"context_id": "abc123def456",
"patient_id": 1001,
"organisation_id": 638,
"clinic_id": 412,
"spry_case_id": "SPRY_CASE_69cd0c97e7562d613ea89bc7",
"case_title": "Stable Burst Fracture",
"appointment_id": 9001,
"type": "INITIAL_SOAP",
"category": "MSK",
"service_date_time": "2026-05-19T10:00:00",
"entry_date_time": "2026-05-19T10:00:00",
"status": "INCOMPLETED",
"completed": false,
"completed_at": null,
"rendering_physician": 50112,
"supervising_physician": 50100,
"subjective_submission_id": "sub_abc001",
"objective_submission_id": "obj_abc001",
"assessment_submission_id": "asm_abc001",
"treatment_sheet_id": 0,
"plan_of_care_id": null,
"submit_for_billing": false,
"summary_doc_url": null,
"short_summary_url": null,
"is_soap_note_editable": true,
"soap_without_appointment": false,
"parent": null,
"data_carry_forward_from": null,
"created_at": "2026-05-19T10:00:00",
"updated_at": "2026-05-19T10:00:00"
},
"message": "Success"
}
Key Response Fields¶
| Field | Type | Description |
|---|---|---|
context_id |
string | Unique ID of the new SOAP note — used in all subsequent calls |
status |
string | Initially INCOMPLETED |
assessment_submission_id |
string | Form submission ID for the Assessment section — pass as submissionId when patching ICD codes |
treatment_sheet_id |
integer | 0 until a treatment sheet is created for this note |
summary_doc_url |
string | null until the note is completed and the PDF generation job runs |
short_summary_url |
string | null until the note is completed and the PDF generation job runs |
See Get SOAP Note for the full field reference.
Error Responses¶
Code: 200 OK
SOAP Note Workflow¶
Creating the SOAP context is step 1. The full lifecycle to produce a completed note with a PDF involves these steps:
Step 1 — Create the SOAP context¶
POST /apis/hep/v2/soap-context (this endpoint). Save the returned context_id and assessment_submission_id for the steps below.
Step 2 — Populate ICD codes in the Assessment section¶
If ICD codes are already set on the patient's case they are auto-populated into the assessment form. No call needed.
If you need to search for or change ICD codes, use:
See Search ICD Codes for full details.
To write ICD codes into the assessment form, send a partial update using the assessment_submission_id from the SOAP context response:
curl --location '{base_url}/apis/v1/form-data/partial' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"submissionId": "asm_abc001",
"soapContextId": "abc123def456",
"partialResponse": {
"response.Assessment": {
"blank1633525952237": {
"medical_diagnosis": [
{
"uuid": "66b381652fa0546147a186d1",
"id": 2,
"code": "M25.511",
"description": "Pain in right shoulder",
"revision": "ICD10",
"billing_type": "BILLABLE",
"is_primary": null
}
],
"treating_diagnosis": "M25.511 - Pain in right shoulder",
"problem_list": []
}
}
},
"version": 1
}'
Request fields:
| Field | Type | Description |
|---|---|---|
submissionId |
string | assessment_submission_id from the SOAP context |
soapContextId |
string | context_id of the SOAP note |
partialResponse |
object | Dot-notation path → value map targeting the specific form field |
version |
integer | Current form version incremented by 1 |
Step 3 — Search and add CPT codes (Planning section)¶
Fetch available CPT codes for the appointment:
curl --location '{base_url}/apis/v1/treatment-catalog/latest?appointment_id=9001&speciality=MSK&icdCodes=M25.511&soap_note_type=INITIAL_SOAP&clinic_id=412' \
--header 'Authorization: Bearer JWT_TOKEN'
| Query Parameter | Type | Required | Description |
|---|---|---|---|
appointment_id |
integer | Yes | The appointment ID |
speciality |
string | Yes | Clinical specialty (e.g. MSK) |
icdCodes |
string | No | Comma-separated ICD codes to filter relevant CPTs |
soap_note_type |
string | No | Note type to filter CPTs (e.g. INITIAL_SOAP) |
clinic_id |
integer | No | Clinic ID |
payerType |
string | No | Payer type for payer-specific CPT filtering |
payerId |
string | No | Payer ID |
planType |
string | No | Insurance plan type |
Step 4 — Create or update the Treatment Sheet¶
If no treatment sheet exists for the note yet (treatment_sheet_id is 0), create one:
curl --location '{base_url}/apis/v1/treatment-sheet' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"patient_id": "1001",
"soap_context_id": "abc123def456",
"treatments": [
{
"treatment_class_id": 1078,
"duration": 8,
"units": 1,
"modifiers": [
{
"cpt_modifier_id": 2,
"cpt_modifier_code": "59",
"class_name": "Distinct Procedural Service",
"description": "Performed a service that was distinct and independent from all other services performed during the same session",
"filter": true
}
]
}
]
}'
The response includes the id of the new treatment sheet. To update an existing treatment sheet, use:
Send the same treatments array body as above.
Treatment object fields:
| Field | Type | Description |
|---|---|---|
treatment_class_id |
integer | ID of the CPT / treatment class |
duration |
integer | Duration in minutes |
units |
integer | Number of units billed |
modifiers |
array | List of billing modifier objects (see below) |
Modifier object fields:
| Field | Type | Description |
|---|---|---|
cpt_modifier_id |
integer | Internal modifier ID |
cpt_modifier_code |
string | Modifier code (e.g. "59", "GP") |
class_name |
string | Human-readable modifier name |
description |
string | Modifier description |
filter |
boolean | Whether this modifier is used for filtering |
Step 5 — Complete the SOAP note¶
When all sections are filled and signed, mark the note complete:
curl --location '{base_url}/apis/v1/soap-context/abc123def456' \
--header 'Authorization: Bearer JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"completed": true, "status": "COMPLETED", "completed_at": null}'
On completion, the system automatically:
- Triggers PDF generation for summary_doc_url and short_summary_url
- Submits the note for billing (if configured for auto-submission)
- Creates or updates the Plan of Care (for INITIAL_SOAP notes)
Notes¶
clinic_idandorganisation_idare resolved server-side from the authenticated user's session — do not include them in the request body.rendering_physicianandsupervising_physicianare also resolved automatically from the authenticated user's role. A doctor's user ID becomes the rendering physician; the supervising physician is derived from the doctor's profile.- If
spry_case_idis omitted andappointment_idis provided, the case is resolved from the appointment record. - A cancelled appointment will return a
4001error — check appointment status before creating a note. - The
versionfield in the form partial update must match the current version of the form submission incremented by 1. Fetch the current version fromGET /apis/v1/form-data/{assessment_submission_id}if needed.