API Documentation

Explore the CareScribe Software Integration API (3.6.1)

Token Integration

Step 1: Get the specialty list and map it to the Patient

GET /software/speciality/list

Summary: Get all specialities

Description: Retrieves a list of all specialities.

Note: Fetch all specialties; these are used when creating patient and doctor specialties.

Responses:

  • 200: Successful operation
  • 500: Internal server error

Step 2: Create patient and interaction token

POST /software/patientIntraction

Summary: Create patient and interaction token

Description: Creates a new patient record if not found, or adds an interaction if the patient already exists.

Body


{
    "organization_id": 101,
    "speciality_id": 5,
    "patient_id": "HOSP-123",
    "interaction_date": "2025-08-13T09:30:00Z",
    "token_number": "T-101",
    "date_of_birth": "1985-06-15",
    "phone_number": "919876543210",
    "age": 40,
    "gender": "M",
    "address1": "123, Main Street, City",
    "first_name": "John",
    "last_name": "Doe",
    "hospital_id": "9"
}
    

Responses

  • 201: Patient and interaction successfully created (new or existing patient)
  • 400: Bad request or duplicate interaction
  • 500: Server error

Response (201) Example


{
    "message": "New patient and interaction created successfully.",
    "patient": {
        "patient_id": "ABC101-202508-00001",
        "organization_id": 101,
        "hospital_patient_id": "HOSP-123",
        "first_name": "John",
        "last_name": "Doe",
        "date_of_birth": "1985-06-15",
        "phone_number": "+91-9876543210",
        "age": 40,
        "gender": "Male",
        "address1": "123, Main Street, City",
        "patient_category": "Outpatient"
    },
    "interactions": {
        "patient_id": "ABC101-202508-00001",
        "doctor_id": null,
        "speciality_id": 5,
        "interaction_status": "99",
        "interaction_date": "2025-08-13T09:30:00Z",
        "organization_id": 101,
        "token_number": "T-101"
    }
}
    

Response (400) Example


{
    "status": false,
    "message": "hospital_patient_id HOSP-123 already has a token created today.",
    "interaction": {}
}
    

Response (500) Example


{
    "message": "Error Unexpected database failure"
}
    

Note: Use hospital_id that you used to create the organization, and speciality_id of the doctor.

Carescribe Session Link Integration

Step 1: Create a hospital

Call the CareScribe team to book an appointment: https://carescribe.health/

Step 2: Get the specialty list and map it to the doctor

GET /software/speciality/list

Summary: Get all specialities

Description: Retrieves a list of all specialities.

Note: Fetch all specialties; these are used when creating patient and doctor specialties.

Responses:

  • 200: Successful operation
  • 500: Internal server error

Step 3: Create a doctor

POST /software/doctor/create

Summary: Create a doctor

Description: Creates a new doctor.

Body


{
    "first_name": "Alex",
    "last_name": "Patel",
    "speciality_id": 1,
    "salutation": "Dr",
    "hospital_id": "carescribe-001",
    "license_no": "TN12345",
    "phone_number": "+918883761709",
    "email": "alex.patel@example.com",
    "practitioner_id": "carescribe-001-dr001"
}
    

Note:

  • hospital_id: Required — Must be in format "orgname-somenumber" (e.g., carescribe-001, carescribe-002). If you have multiple hospitals with the same organization, use sequential numbers like carescribe-001, carescribe-002, etc.
  • practitioner_id: Required and must be unique — Must be in format "hospital_id-drsomenumber" (e.g., carescribe-001-dr001, carescribe-001-dr002). Format: your hospital_id followed by "-dr" and a number.
  • first_name: Required
  • last_name: Required
  • speciality_id: Required — fetch from /software/speciality/list endpoint
  • license_no: Required — if not available, pass as an empty string (" ")

Responses:

  • 201: Doctor created successfully
  • 400: Invalid input
  • 409: Doctor with practitioner_id or email already exists
  • 500: Internal server error

Step 4: Create a patient and return the path URL

POST /patient/softwareintegration

Summary: Integrate patient software data

Description: Accepts patient, doctor, hospital, and vitals data for integration.

Body


{
    "hospital_id": "9",
    "doctor": {
        "practitioner_id": "DOC123"
    },
    "patient": {
        "patient_id": "PAT7485",
        "name": "John Doe",
        "age": 45,
        "gender": "Male",
        "language": "English",
        "past_history": [
            {"condition": "Hypertension"},
            {"condition": "Dyslipidemia"},
            {"condition": "Cardiac Diseases"},
            {"condition": "Hyperthyrodism"},
            {"condition": "Kidney Diseases"},
            {"condition": "Cancer"},
            {"condition": "Epilepsy"},
            {"condition": "Diabetes Mellitus"},
            {"condition": "Asthma"},
            {"condition": "Arthritis"},
            {"condition": "Allergy"},
            {"condition": "Hypothyroidism"}
        ]
    },
    "vitals": {
        "height_cm": 172,
        "weight_kg": 78,
        "bmi": 26.4,
        "pulse_rate": 92,
        "respiratory_rate": 20,
        "temperature_celsius": 99.1,
        "oxygen_saturation": 94,
        "blood_pressure": "140/90",
        "glucose_mg_dl": 160,
        "abnormal_conditions": [
            {"condition": "Pulse high"},
            {"condition": "Oxygen low"}
        ]
    }
}
    

Note:

  • Hospital ID: 9
  • Doctor Practitioner ID: DOC123
  • Patient ID: PAT7485
  • Past History: Refers to comorbid conditions

Responses:

  • 200: Patient created or already exists and vitals uploaded
  • 400: The following required field(s) are missing: ${missing.join(", ")}. Please check and try again.
  • 404: Organization or doctor not found
  • 500: Internal server error

Step 5: Create a patient and return the path URL

POST Client endpoint URL used to send POST OPD data

Summary: Save Patient and Medical Data

Description: This endpoint saves patient, diagnosis, medication, and vitals data. The patient's outpatient data is sent to the client's system using the URL specified in the organization.api_url field. The data transmission includes both the initial and final payloads as part of the client response.

Initial payload


{
    "status": "complete",
    "data": {
        "SessionId": "GEN9-202508-00050",
        "patientId": "GEN9-202508-00050",
        "hospitalId": "9",
        "OpId": "",
        "IpId": "",
        "PractitionerId": "100",
        "response": "**Diagnosis:** **Costochondritis**",
        "vitals": [
            {
                "id": 0,
                "pulse": "55",
                "height": "139",
                "weight": "62",
                "systolicBP": "72",
                "diastolicBP": "58",
                "oxygenSaturation": "57",
                "temperature": "95",
                "respRate": "70",
                "bloodSugar": "87",
                "bmi": "32.09",
                "cancer": true,
                "epilepsy": "",
                "arthritis": true,
                "abnormalPulse": "",
                "abnormalOxygen": true,
                "hyperthyrodism": true,
                "kidneyDiseases": true,
                "cardiacDiseases": true,
                "diabetesMellitus": true,
                "asthma": "",
                "hypertension": "",
                "hypothyroidism": true,
                "abnormalSystolic": true,
                "dyslipidemia": "",
                "allergy": true
            }
        ],
        "assessment": [
            {
                "templateName": "",
                "tests": ["FibroScan"]
            }
        ],
        "medication_templates": [
            {
                "brand_name": "add tears 40mg tablet",
                "generic_name": null,
                "strength": "40mg",
                "uom": "mg",
                "frequency_morning": 1,
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": "40",
                "prn": "before food",
                "route": "Oral",
                "drug_type": "tablet",
                "instructions": "take before food"
                "medication_name": "add tears 40mg tablet"
                "medicine_type": "existing"
            },
            {
                "brand_name": "lactifiber powder",
                "generic_name": "lactitol (10gm) + ispaghula (3.5gm)",
                "strength": "1 spoon",
                "uom": "g",
                "frequency_morning": "0",
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": 10,
                "prn": "",
                "route": "Oral",
                "drug_type": "powder",
                "instructions": "mix in a glass of water and drink at night"
                "medication_name": "lactitol (10gm) + ispaghula (3.5gm) lactifiber powder"
                "medicine_type": "existing"
            }
        ],
        "additional_response": "**Chief Complaints:** - **Pain in the right costal margin area.**\n\n**History of Presenting Illness:** Patient reports persistent pain in the right costal margin area. The pain is continuous but mild, with episodes of severe, sharp pain. The pain is relieved by taking the tablet ultraplus h 162.5 mg tablets, which provides approximately 80% recovery. Patient takes this medication occasionally, about once every 4-5 days or once a week, when the pain becomes severe. Patient denies any history of heavy lifting or strenuous activity. The pain is more prominent in the evening.\n\n**Past Medical History:** - **Fatty liver**\n- **Hypertriglyceridemia**\n- **Hypertension**\n- **Diabetes mellitus**\n- **Hypothyroidism**\n- **Hyperthyroidism**\n- **Kidney diseases**\n- **Allergy**\n- **Arthritis**\n- **Cancer**\n\n**Personal History:** - No night shift work.\n\n**Examination Findings:** - On examination, there is a point of tenderness in the right costal margin area.\n\n**Investigations:** - **LFT reviewed:** All enzymes are within normal limits, except for elevated triglycerides.\n- **Nerve conduction study reviewed:** Within normal limits.\n\n**Recommendations:** - Continue regular walking.\n- Stretching exercises may help relieve stiffness.\n\n**Follow-up:** - Follow up after 3 days to assess response to treatment and decide on further management, such as a nerve block injection.",
        "opd_data":{
          "chief_complaints": "Patient presents with a **burning sensation in the feet**.",
          "history_of_presenting_illness": "Patient reports a **burning sensation in the feet for the past 5 months**. The sensation has remained the same without significant increase or decrease. Patient also mentions associated knee pain. Patient experiences difficulty wearing slippers, stating they have to be consciously placed on the feet. There is a loss of sensation, causing the slippers to fall off without the patient noticing, especially when riding as a pillion on a two-wheeler. Patient confirms that wounds heal normally.",
          "patient_history": "**Diabetes Mellitus** for 2 years.",
          "Past_Medications": "Patient was taking medications from GH for diabetes, which were recently changed.",
          "examination_findings": "On examination, there is a **loss of sensation in the feet**.",
          "investigations": "Random blood sugar was **282 mg/dL** two days ago, measured in the afternoon.",
          "recommendations": "Patient is advised to finish the previously prescribed medications before starting the new ones.",
          "follow_up": "Patient is advised to follow up after one month.",
          "plan": "Medical management advised.",
          "diagnosis": "**Diabetic Neuropathy**"
      }
        "status": "initial payload"
    }
}
    

End payload


{
    "status": "complete",
    "data": {
        "SessionId": "GEN9-202508-00050",
        "patientId": "GEN9-202508-00050",
        "hospitalId": "9",
        "OpId": "",
        "IpId": "",
        "PractitionerId": "100",
        "response": "**Diagnosis:** **Costochondritistest**\n\n",
        "additional_response": "**Chief Complaints:**\n\n- **Pain in the right costal margin area.**\n\n\n\n**History of Presenting Illness:** Patient reports persistent pain in the right costal margin area. The pain is continuous but mild, with episodes of severe, sharp pain. The pain is relieved by taking the tablet ultraplus h 162.5 mg tablets, which provides approximately 80% recovery. Patient takes this medication occasionally, about once every 4-5 days or once a week, when the pain becomes severe. Patient denies any history of heavy lifting or strenuous activity. The pain is more prominent in the evening.\n\n**Past Medical History:**\n\n- **Fatty liver**\n- **Hypertriglyceridemia**\n- **Hypertension**\n- **Diabetes mellitus**\n- **Hypothyroidism**\n- **Hyperthyroidism**\n- **Kidney diseases**\n- **Allergy**\n- **Arthritis**\n- **Cancer**\n\n\n\n**Personal History:**\n\n- No night shift work.\n\n\n\n**Examination Findings:**\n\n- On examination, there is a point of tenderness in the right costal margin area.\n\n\n\n**Investigations:**\n\n- **LFT reviewed:** All enzymes are within normal limits, except for elevated triglycerides.\n- **Nerve conduction study reviewed:** Within normal limits.\n\n\n\n**Recommendations:**\n\n- Continue regular walking.\n- Stretching exercises may help relieve stiffness.\n\n\n\n**Follow-up:**\n\n- Follow up after 3 days to assess response to treatment and decide on further management, such as a nerve block injection.**test**\n\n\n\n",
        "medication_templates": [
            {
                "brand_name": "add tears 40mg tablet",
                "generic_name": null,
                "strength": "40mg",
                "uom": "mg",
                "frequency_morning": 1,
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": "40",
                "prn": "before food",
                "route": "Oral",
                "drug_type": "tablet",
                "instructions": "take before food"
                "medication_name": "add tears 40mg tablet"
                "medicine_type": "existing"
            },
            {
                "brand_name": "lactifiber powder",
                "generic_name": "lactitol (10gm) + ispaghula (3.5gm)",
                "strength": "1 spoon",
                "uom": "g",
                "frequency_morning": "0",
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": 10,
                "prn": "",
                "route": "Oral",
                "drug_type": "powder",
                "instructions": "mix in a glass of water and drink at night"
                "medication_name": "lactitol (10gm) + ispaghula (3.5gm) lactifiber powder"
                "medicine_type": "existing"
            }
        ],
        "vitals": [
            {
                "id": 0,
                "pulse": "55",
                "height": "139",
                "weight": "62",
                "systolicBP": "72",
                "diastolicBP": "58",
                "oxygenSaturation": "57",
                "temperature": "95",
                "respRate": "70",
                "bloodSugar": "87",
                "bmi": "32.09",
                "cancer": true,
                "epilepsy": "",
                "arthritis": true,
                "abnormalPulse": "",
                "abnormalOxygen": true,
                "hyperthyrodism": true,
                "kidneyDiseases": true,
                "cardiacDiseases": true,
                "diabetesMellitus": true,
                "asthma": "",
                "hypertension": "",
                "hypothyroidism": true,
                "abnormalSystolic": true,
                "dyslipidemia": "",
                "allergy": true
            }
        ],
        "assessment": [
            {
                "template_tests": "FibroScan"
            }
        ],
        "opd_data":{
          "chief_complaints": "Patient presents with a **burning sensation in the feet**.",
          "history_of_presenting_illness": "Patient reports a **burning sensation in the feet for the past 5 months**. The sensation has remained the same without significant increase or decrease. Patient also mentions associated knee pain. Patient experiences difficulty wearing slippers, stating they have to be consciously placed on the feet. There is a loss of sensation, causing the slippers to fall off without the patient noticing, especially when riding as a pillion on a two-wheeler. Patient confirms that wounds heal normally.",
          "patient_history": "**Diabetes Mellitus** for 2 years.",
          "Past_Medications": "Patient was taking medications from GH for diabetes, which were recently changed.",
          "examination_findings": "On examination, there is a **loss of sensation in the feet**.",
          "investigations": "Random blood sugar was **282 mg/dL** two days ago, measured in the afternoon.",
          "recommendations": "Patient is advised to finish the previously prescribed medications before starting the new ones.",
          "follow_up": "Patient is advised to follow up after one month.",
          "plan": "Medical management advised.",
          "diagnosis": "**Diabetic Neuropathy**"
      }
        "status": "end payload"
    }
}
    

Responses:

  • 200: Data posted successfully with initial payload
  • 201: Data posted successfully with end payload

Get Patient Visit by ID

GET /software/patient-visit-by-id

Summary: Retrieves the latest visit details for a patient.

Authentication: Send the API key in the X-API-Key header.

Query Parameters:

  • hospital_id (required): Unique hospital identifier used to resolve the organization.
  • patient_id (required): Hospital patient identifier (patient_id).
  • limit (optional): Number of latest visits to return (minimum 1, maximum 3; default 1).

Example Request:

curl --request GET \
  --url 'https://carescribe-app-api-8to2squd.wl.gateway.dev/software/patient-visit-by-id?hospital_id=9&patient_id=GEN9-202602-00133&limit=1' \
  --header 'X-API-Key: YOUR_API_KEY'

Example Response:

{
    "status": "complete",
    "data": {
        "SessionId": "GEN9-202508-00050",
        "patientId": "GEN9-202508-00050",
        "hospitalId": "9",
        "OpId": "",
        "IpId": "",
        "PractitionerId": "100",
        "response": "**Diagnosis:** **Costochondritistest**\n\n",
        "additional_response": "**Chief Complaints:**\n\n- **Pain in the right costal margin area.**\n\n\n\n**History of Presenting Illness:** Patient reports persistent pain in the right costal margin area. The pain is continuous but mild, with episodes of severe, sharp pain. The pain is relieved by taking the tablet ultraplus h 162.5 mg tablets, which provides approximately 80% recovery. Patient takes this medication occasionally, about once every 4-5 days or once a week, when the pain becomes severe. Patient denies any history of heavy lifting or strenuous activity. The pain is more prominent in the evening.\n\n**Past Medical History:**\n\n- **Fatty liver**\n- **Hypertriglyceridemia**\n- **Hypertension**\n- **Diabetes mellitus**\n- **Hypothyroidism**\n- **Hyperthyroidism**\n- **Kidney diseases**\n- **Allergy**\n- **Arthritis**\n- **Cancer**\n\n\n\n**Personal History:**\n\n- No night shift work.\n\n\n\n**Examination Findings:**\n\n- On examination, there is a point of tenderness in the right costal margin area.\n\n\n\n**Investigations:**\n\n- **LFT reviewed:** All enzymes are within normal limits, except for elevated triglycerides.\n- **Nerve conduction study reviewed:** Within normal limits.\n\n\n\n**Recommendations:**\n\n- Continue regular walking.\n- Stretching exercises may help relieve stiffness.\n\n\n\n**Follow-up:**\n\n- Follow up after 3 days to assess response to treatment and decide on further management, such as a nerve block injection.**test**\n\n\n\n",
        "medication_templates": [
            {
                "brand_name": "add tears 40mg tablet",
                "generic_name": null,
                "strength": "40mg",
                "uom": "mg",
                "frequency_morning": 1,
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": "40",
                "prn": "before food",
                "route": "Oral",
                "drug_type": "tablet",
                "instructions": "take before food",
                "medication_name": "add tears 40mg tablet",
                "medicine_type": "existing"
            },
            {
                "brand_name": "lactifiber powder",
                "generic_name": "lactitol (10gm) + ispaghula (3.5gm)",
                "strength": "1 spoon",
                "uom": "g",
                "frequency_morning": "0",
                "frequency_afternoon": "0",
                "frequency_evening": "0",
                "frequency_night": 1,
                "days": "3 days",
                "dosage_value": 10,
                "prn": "",
                "route": "Oral",
                "drug_type": "powder",
                "instructions": "mix in a glass of water and drink at night",
                "medication_name": "lactitol (10gm) + ispaghula (3.5gm) lactifiber powder",
                "medicine_type": "existing"
            }
        ],
        "vitals": [
            {
                "id": 0,
                "pulse": "55",
                "height": "139",
                "weight": "62",
                "systolicBP": "72",
                "diastolicBP": "58",
                "oxygenSaturation": "57",
                "temperature": "95",
                "respRate": "70",
                "bloodSugar": "87",
                "bmi": "32.09",
                "cancer": true,
                "epilepsy": "",
                "arthritis": true,
                "abnormalPulse": "",
                "abnormalOxygen": true,
                "hyperthyrodism": true,
                "kidneyDiseases": true,
                "cardiacDiseases": true,
                "diabetesMellitus": true,
                "asthma": "",
                "hypertension": "",
                "hypothyroidism": true,
                "abnormalSystolic": true,
                "dyslipidemia": "",
                "allergy": true
            }
        ],
        "assessment": [
            {
                "template_tests": "FibroScan"
            }
        ],
        "opd_data":{
          "chief_complaints": "Patient presents with a **burning sensation in the feet**.",
          "history_of_presenting_illness": "Patient reports a **burning sensation in the feet for the past 5 months**. The sensation has remained the same without significant increase or decrease. Patient also mentions associated knee pain. Patient experiences difficulty wearing slippers, stating they have to be consciously placed on the feet. There is a loss of sensation, causing the slippers to fall off without the patient noticing, especially when riding as a pillion on a two-wheeler. Patient confirms that wounds heal normally.",
          "patient_history": "**Diabetes Mellitus** for 2 years.",
          "Past_Medications": "Patient was taking medications from GH for diabetes, which were recently changed.",
          "examination_findings": "On examination, there is a **loss of sensation in the feet**.",
          "investigations": "Random blood sugar was **282 mg/dL** two days ago, measured in the afternoon.",
          "recommendations": "Patient is advised to finish the previously prescribed medications before starting the new ones.",
          "follow_up": "Patient is advised to follow up after one month.",
          "plan": "Medical management advised.",
          "diagnosis": "**Diabetic Neuropathy**"
      }
        "status": "end payload"
    }
}

Pending data response:

{
    "count": 0,
    "data": [],
    "message": "Data not generated yet. Please try again after 30 seconds.",
    "code": "DATA_NOT_GENERATED",
    "retry_after_seconds": 30
}

Responses:

  • 200: Patient visit data retrieved successfully, or data generation is pending.
  • 400: A required query parameter is missing.
  • 404: Organization or patient not found.
  • 500: Internal server error.

Carescribe websocket Integration

Step 1: Create a hospital

Call the CareScribe team to book an appointment: https://carescribe.health/

Step 2: Get the specialty list and map it to the doctor

GET /software/speciality/list

Summary: Get all specialities

Description: Retrieves a list of all specialities.

Note: Fetch all specialties; these are used when creating patient and doctor specialties.

Responses:

  • 200: Successful operation
  • 500: Internal server error

Step 3: Create a doctor

POST /software/doctor/create

Summary: Create a doctor

Description: Creates a new doctor.

Body


{
    "first_name": "Alex",
    "last_name": "Patel",
    "speciality_id": 1,
    "salutation": "Dr",
    "hospital_id": "carescribe-001",
    "license_no": "TN12345",
    "phone_number": "+918883761709",
    "email": "alex.patel@example.com",
    "practitioner_id": "carescribe-001-dr001"
}
    

Note:

  • hospital_id: Required — Must be in format "orgname-somenumber" (e.g., carescribe-001, carescribe-002). If you have multiple hospitals with the same organization, use sequential numbers like carescribe-001, carescribe-002, etc.
  • practitioner_id: Required and must be unique — Must be in format "hospital_id-drsomenumber" (e.g., carescribe-001-dr001, carescribe-001-dr002). Format: your hospital_id followed by "-dr" and a number.
  • first_name: Required
  • last_name: Required
  • speciality_id: Required — fetch from /software/speciality/list endpoint
  • license_no: Required — if not available, pass as an empty string (" ")

Responses:

  • 201: Doctor created successfully
  • 400: Invalid input
  • 409: Doctor with practitioner_id or email already exists
  • 500: Internal server error

Step 4: connect websocket

Summary: Stream real-time audio from client to server via WebSocket.

Description: - Establishes a WebSocket connection for audio streaming.
- Sends an initial JSON payload with patient and interaction details.
- Streams audio chunks (WebM/Opus format) at 30-second intervals.
- Receives processed results from the server (diagnosis, notes, medications).
- Finalizes the stream by sending a stop command and last audio blob.

⚠️ Two Types of WebSocket Connections Available

You can choose between two different WebSocket endpoints based on your audio transmission format:

BINARY Binary Audio Chunks

Endpoint:

wss://app.carescribe.health/wsaudio

Format:

  • Uses socket.binaryType = "arraybuffer"
  • Sends raw binary data (ArrayBuffer)
  • More efficient (smaller payload)
  • Direct binary transmission

BASE64 Base64 Audio Chunks

Endpoint:

wss://app.carescribe.health/wsaudiobase64

Format:

  • No special binaryType config needed
  • Sends JSON with audio_base64 string
  • Text-based (easier to debug)
  • ~33% larger payload size
  • ⚠️ Replace this for security purpose const token = "Api_Key" in the code with your actual API key.
  • Init Payload (Sent on Connection)

    {
          "hospital_patient_id": "9004",
          "hospital_id": "9",
          "practitioner_id": "100",
          "first_name": "ragul",
          "last_name": "P",
          "date_of_birth": null,
          "gender": "M",
          "age": 10,
          "interaction_detail_type": "Audio url",
          "attenderName": null,
          "attenderRelationship": null,
        }

    Audio Stream

    Audio chunks are sent every 30s using MediaRecorder with format audio/webm;codecs=opus at 32 kbps.

    Stop Payload

    {
          "type": "stop"
        }

    Server Response Example

    {
          "status": "processed",
          "allData": {
            "interaction_id": "76571",
            "attachment_url": "gs://medscribe-dev/webm_files/get-opd/record-notes-9_GEN9-202509-00438_58bab159-071d-4cf6-beea-b113c0b18e3c.txt",
            "processedText": "{\"chief_complaints\": \"Persistent pain in the chest area.\", \"history_of_presenting_illness\": \"Patient reports a persistent pain issue. The pain is continuous and sometimes becomes severe, feeling like a wound. Patient mentions that taking the tablet ultra p tablets provides some relief, reducing the pain by about 80%. Patient takes this medication intermittently, once every four, five, or seven days, not daily. Patient avoids heavy lifting. The pain is localized to a specific point and is described as nerve pain or fascial pain, not bone pain. The pain has been continuous, with periods of increased severity.\", \"past_medical_history\": \"Hypercholesterolemia Fatty liver disease\", \"personal_history\": \"Patient does not work night shifts.\", \"examination_findings\": \" On examination, the pain is localized to a specific point.\", \"investigations\": \"Blood tests reviewed: LFT and other enzyme levels are within normal limits, except for elevated triglycerides.\", \"diagnosis\": \"Costochondritis\", \"recommendations\": \"Patient is advised to continue walking and stretching exercises as they provide relief from stiffness. Patient is advised to use ultraplus h 162.5 mg tablets for 5 days.\", \"follow_up\": \"Patient is advised to follow up after 3 days to assess response to treatment and decide on further management, such as a nerve block injection\", \"plan\": \" A FibroScan is planned to further evaluate the liver. The procedure will be scheduled for the upcoming Saturday.\", \"assessment\": [{\"assessment_template\": \"General Health Assessment\", \"template_tests\": \"Blood Test, X-Ray\", \"template_id\": 22}], \"medication_templates\": [{\"medication_name\": \"Ibuprofen\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Calpol\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Cetirizine\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Nexpro DSR\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}], \"additional_response\": \"\", \"vitals\": [], \"lab_data\": {\"lab_abnormal_data\": \"\"}}"
          }
        }

    Notes

    • Use wss:// in production for secure communication.
    • ⚠️ Replace const token = "Api_Key" in the code with your actual API key.
    • initPayload
    • interaction_detail_type can be either "Audio url" or "Counselling".
    • If interaction_detail_type = "Counselling", provide the following data:
      • attenderName: e.g., "Ragul"
      • attenderRelationship: e.g., "Father"
    • "gender": "M" or "F" or "O"

    Example code for websocket with binary audio chunk

    
            <!DOCTYPE html>
            <html lang="en">
            <head>
              <meta charset="UTF-8">
              <title>Audio Streaming with WebSocket</title>
              <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
              <style>
                body {
                  font-family: Arial, sans-serif;
                  margin: 20px;
                  background: #f9f9f9;
                }
                h1 {
                  text-align: center;
                }
                #controls {
                  text-align: center;
                  margin-bottom: 20px;
                }
                button {
                  padding: 10px 20px;
                  margin: 0 10px;
                  border: none;
                  border-radius: 6px;
                  cursor: pointer;
                  font-size: 16px;
                }
                #startBtn { background-color: #4CAF50; color: white; }
                #stopBtn { background-color: #f44336; color: white; }
                #output {
                  background: #fff;
                  padding: 15px;
                  border-radius: 8px;
                  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
                  margin-top: 20px;
                }
                #loading {
                  text-align: center;
                  font-size: 16px;
                  font-weight: bold;
                  color: #555;
                  display: none;
                  margin-top: 10px;
                }
                table {
                  border-collapse: collapse;
                  width: 100%;
                  margin-top: 15px;
                }
                th, td {
                  border: 1px solid #ccc;
                  padding: 8px;
                  text-align: left;
                }
                th {
                  background: #f2f2f2;
                }
                h3 {
                  margin-top: 15px;
                  color: #333;
                }
                pre {
                  background: #f7f7f7;
                  padding: 10px;
                  border-radius: 6px;
                  overflow-x: auto;
                }
              </style>
            </head>
            <body>
              <h1>Audio Streaming</h1>
              <div id="controls">
                <button id="startBtn">Start Streaming</button>
                <button id="stopBtn" disabled>Stop Streaming</button>
              </div>
            
              <div id="loading">⏳ Processing...</div>
            
              <div id="output">
                <h2>Processed Data</h2>
                <div id="result"></div>
              </div>
            
              <script>
                let socket;
                let mediaRecorder;
                let recordedChunks = [];
            
                const initPayload = {
                  hospital_patient_id: "9004",
                  hospital_id: "carescribe001",
                  practitioner_id: "carescribe001-dr001",
                  first_name: "Ragul",
                  last_name: "P",
                  date_of_birth: "2015-04-12",
                  gender: "M",
                  age: 10,
                  interaction_detail_type: "Audio url",
                  attenderName: null,
                  attenderRelationship: null
                };
            
                const sampleResponse = {allData:{
                  "interaction_id": "76571",
                  "attachment_url": "gs://medscribe-dev/webm_files/get-opd/record-notes-9_GEN9-202509-00438_58bab159-071d-4cf6-beea-b113c0b18e3c.txt",
                  "processedText": "{\"chief_complaints\": \"Persistent pain in the chest area.\", \"history_of_presenting_illness\": \"Patient reports a persistent pain issue. The pain is continuous and sometimes becomes severe, feeling like a wound. Patient mentions that taking the tablet ultra p tablets provides some relief, reducing the pain by about 80%. Patient takes this medication intermittently, once every four, five, or seven days, not daily. Patient avoids heavy lifting. The pain is localized to a specific point and is described as nerve pain or fascial pain, not bone pain. The pain has been continuous, with periods of increased severity.\", \"past_medical_history\": \"Hypercholesterolemia Fatty liver disease\", \"personal_history\": \"Patient does not work night shifts.\", \"examination_findings\": \" On examination, the pain is localized to a specific point.\", \"investigations\": \"Blood tests reviewed: LFT and other enzyme levels are within normal limits, except for elevated triglycerides.\", \"diagnosis\": \"Costochondritis\", \"recommendations\": \"Patient is advised to continue walking and stretching exercises as they provide relief from stiffness. Patient is advised to use ultraplus h 162.5 mg tablets for 5 days.\", \"follow_up\": \"Patient is advised to follow up after 3 days to assess response to treatment and decide on further management, such as a nerve block injection\", \"plan\": \" A FibroScan is planned to further evaluate the liver. The procedure will be scheduled for the upcoming Saturday.\", \"assessment\": [{\"assessment_template\": \"General Health Assessment\", \"template_tests\": \"Blood Test, X-Ray\", \"template_id\": 22}], \"medication_templates\": [{\"medication_name\": \"Ibuprofen\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Calpol\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Cetirizine\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}, {\"medication_name\": \"Nexpro DSR\", \"medication_type\": \"tablet\", \"dosage\": null, \"route\": \"Oral\", \"frequency_morning\": \"1\", \"frequency_afternoon\": \"0\", \"frequency_evening\": \"1\", \"frequency_night\": null, \"duration\": \"3 days\", \"instructions\": null, \"auto_correct\": false}], \"additional_response\": \"\", \"vitals\": [], \"lab_data\": {\"lab_abnormal_data\": \"\"}}"
                }};
            
                const resultDiv = document.getElementById("result");
                const startBtn = document.getElementById("startBtn");
                const stopBtn = document.getElementById("stopBtn");
                const loadingDiv = document.getElementById("loading");
            
                startBtn.addEventListener("click", startStreaming);
                stopBtn.addEventListener("click", stopStreaming);
            
                async function startStreaming() {
                  try {
                    const token = "Api_Key";
                    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                    socket = new WebSocket("wss://app.carescribe.health/wsaudio",token);
                    socket.binaryType = "arraybuffer";
            
                    startBtn.disabled = true;
                    stopBtn.disabled = false;
                    resultDiv.innerHTML = "";
                    loadingDiv.style.display = "none";
            
                    socket.onopen = () => {
                      console.log("✅ WebSocket connected");
                      socket.send(JSON.stringify(initPayload));
            
                      mediaRecorder = new MediaRecorder(stream, {
                        mimeType: "audio/webm;codecs=opus",
                        audioBitsPerSecond: 32000
                      });
            
                      mediaRecorder.ondataavailable = async (event) => {
                        if (event.data.size > 0 && socket.readyState === WebSocket.OPEN) {
                          const buffer = await event.data.arrayBuffer();
                          socket.send(buffer);
                          recordedChunks.push(event.data);
                          console.log("📤 Sent audio chunk:", buffer.byteLength);
                        }
                      };
            
                      mediaRecorder.start(1000);
                    };
            
                    socket.onmessage = (event) => {
                      try {
                        const parsedData = JSON.parse(event.data);
                        if (parsedData?.status === "processed") {
                          loadProcessedData(parsedData);
                        }
                      } catch (err) {
                        console.error("❌ Invalid server data:", event.data, err);
                      }
                    };
            
                    socket.onerror = (err) => console.error("❌ WebSocket error:", err);
                    socket.onclose = () => {
                      console.log("🔒 WebSocket closed");
                      if (mediaRecorder && mediaRecorder.state !== "inactive") mediaRecorder.stop();
                    };
                  } catch (error) {
                    console.error("❌ Error accessing mic:", error);
                  }
                }
            
                async function stopStreaming() {
                  stopBtn.disabled = true; 
                  loadingDiv.style.display = "block";
            
                  if (mediaRecorder && mediaRecorder.state !== "inactive") {
                    await new Promise(resolve => {
                      mediaRecorder.onstop = async () => {
                        const blob = new Blob(recordedChunks, { type: "audio/webm;codecs=opus" });
                        if (socket?.readyState === WebSocket.OPEN) {
                          const buffer = await blob.arrayBuffer();
                          socket.send(buffer);
                          socket.send(JSON.stringify({ type: "stop" }));
                          console.log("📤 Sent final audio blob and stop command");
                        }
                        recordedChunks = [];
                        resolve();
                      };
                      mediaRecorder.stop();
                    });
                  }
                }
            
                // 🔹 Function to render processedText dynamically
                function loadProcessedData(parsedData) {
                  loadingDiv.style.display = "none";
                  startBtn.disabled = false;
                  stopBtn.disabled = true;
            
                  let processedObj;
                  try {
                    processedObj = JSON.parse(parsedData.allData.processedText);
                  } catch {
                    processedObj = { response: parsedData.allData.processedText };
                  }
            
                  let htmlOutput = "";
                  for (const [key, value] of Object.entries(processedObj)) {
                    if (key === "medication_templates") continue;
            
                    let displayValue;
                    if (Array.isArray(value) || (typeof value === "object" && value !== null)) {
                      displayValue = `<pre>${JSON.stringify(value, null, 2)}</pre>`;
                    } else {
                      displayValue = value || "-";
                    }
            
                    htmlOutput += `
                      <h3>📌 ${key.replace(/_/g, " ")}</h3>
                      <div>${displayValue}</div>
                      <hr/>
                    `;
                  }
            
                  let medsTable = "";
                  if (processedObj?.medication_templates?.length) {
                    medsTable = `
                    <h3>💊 Prescribed Medications</h3>
                    <table>
                      <thead>
                        <tr>
                          <th>Name</th>
                          <th>Type</th>
                          <th>Dosage</th>
                          <th>Route</th>
                          <th>Frequency</th>
                          <th>Duration</th>
                          <th>Instructions</th>
                        </tr>
                      </thead>
                      <tbody>
                        ${processedObj.medication_templates.map(med => `
                          <tr>
                            <td>${med.medication_name || "-"}</td>
                            <td>${med.medication_type || "-"}</td>
                            <td>${med.dosage || "-"}</td>
                            <td>${med.route || "-"}</td>
                            <td>
                              M:${med.frequency_morning || "-"}, 
                              A:${med.frequency_afternoon || "-"}, 
                              E:${med.frequency_evening || "-"}, 
                              N:${med.frequency_night || "-"}
                            </td>
                            <td>${med.duration || "-"}</td>
                            <td>${med.instructions || "-"}</td>
                          </tr>
                        `).join("")}
                      </tbody>
                    </table>`;
                  }
            
                  resultDiv.innerHTML = htmlOutput + medsTable;
                }
              </script>
            </body>
            </html>
            
          
          

    Example code for websocket with base64 audio chunk

    
           <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <title>Audio Streaming with WebSocket (base64)</title>
      <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
      <style>
        body { font-family: Arial, sans-serif; margin: 20px; background: #f9f9f9; }
        h1 { text-align: center; }
        #controls { text-align: center; margin-bottom: 20px; }
        button { padding: 10px 20px; margin: 0 10px; border: none; border-radius: 6px; cursor: pointer; font-size: 16px; }
        #startBtn { background-color: #4CAF50; color: white; }
        #stopBtn { background-color: #f44336; color: white; }
        #output { background: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); margin-top: 20px; }
        #loading { text-align: center; font-size: 16px; font-weight: bold; color: #555; display: none; margin-top: 10px; }
        table { border-collapse: collapse; width: 100%; margin-top: 15px; }
        th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
        th { background: #f2f2f2; }
        h3 { margin-top: 15px; color: #333; }
        pre { background: #f7f7f7; padding: 10px; border-radius: 6px; overflow-x: auto; }
      </style>
    </head>
    <body>
      <h1>Audio Streaming</h1>
      <div id="controls">
        <button id="startBtn">Start Streaming</button>
        <button id="stopBtn" disabled>Stop Streaming</button>
      </div>
    
      <div id="loading">⏳ Processing...</div>
    
      <div id="output">
        <h2>Processed Data</h2>
        <div id="result"></div>
      </div>
    
      <script>
        let socket;
        let mediaRecorder;
        let recordedChunks = [];
    
        const initPayload = {
          hospital_patient_id: "Gen-9090",
          hospital_id: "9",
          practitioner_id: "100",
          first_name: "Ragul",
          last_name: "P",
          date_of_birth: "2015-04-12",
          gender: "M",
          age: 10,
          interaction_detail_type: "Audio url",
          attenderName: null,
          attenderRelationship: null
        };
    
        const resultDiv = document.getElementById("result");
        const startBtn = document.getElementById("startBtn");
        const stopBtn = document.getElementById("stopBtn");
        const loadingDiv = document.getElementById("loading");
    
        startBtn.addEventListener("click", startStreaming);
        stopBtn.addEventListener("click", stopStreaming);
    
        // Convert a Blob to base64 using FileReader (safe for Opus/WebM chunks)
        function blobToBase64(blob) {
          return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onloadend = () => {
              try {
                const dataUrl = reader.result; // "data:audio/webm;codecs=opus;base64,AAAA..."
                const base64 = (dataUrl || "").toString().split(",")[1] || "";
                resolve(base64);
              } catch (e) { reject(e); }
            };
            reader.onerror = reject;
            reader.readAsDataURL(blob);
          });
        }
    
        // Light back-pressure: wait while bufferedAmount is high
        async function waitForDrain(ws, threshold = 512 * 1024) {
          while (ws.readyState === WebSocket.OPEN && ws.bufferedAmount > threshold) {
            await new Promise(r => setTimeout(r, 20));
          }
        }
    
        async function startStreaming() {
          try {
            const token = "Api_Key"; // optional subprotocol
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    
            // Pass token as subprotocol so server can read it from 'sec-websocket-protocol'
            socket = new WebSocket("wss://app.carescribe.health/wsaudiobase64", [token]);
    
            // We are sending ONLY JSON text (no binary)
            startBtn.disabled = true;
            stopBtn.disabled = false;
            resultDiv.innerHTML = "";
            loadingDiv.style.display = "none";
    
            socket.onopen = () => {
              console.log("✅ WebSocket connected");
              // 1) Send init JSON first
              socket.send(JSON.stringify(initPayload));
    
              // 2) Start MediaRecorder and send base64 JSON per chunk
              mediaRecorder = new MediaRecorder(stream, {
                mimeType: "audio/webm;codecs=opus",
                audioBitsPerSecond: 32000
              });
    
              mediaRecorder.ondataavailable = async (event) => {
                if (event.data && event.data.size > 0 && socket.readyState === WebSocket.OPEN) {
                  try {
                    const base64 = await blobToBase64(event.data);
                    await waitForDrain(socket);
                    socket.send(JSON.stringify({ audio: base64 }));
                    recordedChunks.push(event.data);
                    console.log("📤 Sent base64 chunk:", (base64.length / 1024).toFixed(1), "KB");
                  } catch (err) {
                    console.error("❌ Failed to convert/send chunk:", err);
                  }
                }
              };
    
              // Send a chunk roughly every second
              mediaRecorder.start(1000);
            };
    
            socket.onmessage = (event) => {
              // Expecting JSON messages from server (e.g., processed result or ack)
              try {
                const parsed = JSON.parse(event.data);
                if (parsed?.status === "processed") {
                  loadProcessedData(parsed);
                } else {
                  // You can log/handle other statuses here
                  // console.log("Server message:", parsed);
                }
              } catch (err) {
                console.error("❌ Invalid server data:", event.data, err);
              }
            };
    
            socket.onerror = (err) => console.error("❌ WebSocket error:", err);
            socket.onclose = () => {
              console.log("🔒 WebSocket closed");
              if (mediaRecorder && mediaRecorder.state !== "inactive") {
                mediaRecorder.stop();
              }
            };
          } catch (error) {
            console.error("❌ Error accessing mic:", error);
            startBtn.disabled = false;
            stopBtn.disabled = true;
          }
        }
    
        async function stopStreaming() {
          stopBtn.disabled = true;
          loadingDiv.style.display = "block";
    
          // Gracefully stop recorder, flush last chunks, then tell server to stop
          if (mediaRecorder && mediaRecorder.state !== "inactive") {
            await new Promise(resolve => {
              mediaRecorder.onstop = async () => {
                try {
                  if (socket?.readyState === WebSocket.OPEN) {
                    await waitForDrain(socket);
                    socket.send(JSON.stringify({ type: "stop" }));
                    console.log("📤 Sent stop command");
                  }
                } finally {
                  recordedChunks = [];
                  resolve();
                }
              };
              mediaRecorder.stop();
            });
          }
        }
    
        // Render processed data helper
        function loadProcessedData(parsedData) {
          loadingDiv.style.display = "none";
          startBtn.disabled = false;
          stopBtn.disabled = true;
    
          let processedObj;
          try {
            processedObj = JSON.parse(parsedData.allData?.processedText || "{}");
          } catch {
            processedObj = { response: parsedData.allData?.processedText || "" };
          }
    
          let htmlOutput = "";
          for (const [key, value] of Object.entries(processedObj)) {
            if (key === "medication_templates") continue;
    
            let displayValue;
            if (Array.isArray(value) || (typeof value === "object" && value !== null)) {
              displayValue = `<pre>${JSON.stringify(value, null, 2)}</pre>`;
            } else {
              displayValue = value || "-";
            }
    
            htmlOutput += `
              <h3>📌 ${key.replace(/_/g, " ")}</h3>
              <div>${displayValue}</div>
              <hr/>
            `;
          }
    
          let medsTable = "";
          if (processedObj?.medication_templates?.length) {
            medsTable = `
            <h3>💊 Prescribed Medications</h3>
            <table>
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Type</th>
                  <th>Dosage</th>
                  <th>Route</th>
                  <th>Frequency</th>
                  <th>Duration</th>
                  <th>Instructions</th>
                </tr>
              </thead>
              <tbody>
                ${processedObj.medication_templates.map(med => `
                  <tr>
                    <td>${med.medication_name || "-"}</td>
                    <td>${med.medication_type || "-"}</td>
                    <td>${med.dosage || "-"}</td>
                    <td>${med.route || "-"}</td>
                    <td>
                      M:${med.frequency_morning || "-"},
                      A:${med.frequency_afternoon || "-"},
                      E:${med.frequency_evening || "-"},
                      N:${med.frequency_night || "-"}
                    </td>
                    <td>${med.duration || "-"}</td>
                    <td>${med.instructions || "-"}</td>
                  </tr>
                `).join("")}
              </tbody>
            </table>`;
          }
    
          resultDiv.innerHTML = htmlOutput + medsTable;
        }
      </script>
    </body>
    </html>
    
            
          

    Errors

    • Mic Error: "❌ Error accessing mic"
    • WebSocket Error: "❌ WebSocket error"
    • Invalid Data: Logs "Invalid server data"

    Step 5:Edit OPD data

    POST /software/updateopd

    URL: {{baseUrl}}/software/updateopd

    Summary: Update interaction detail with edited OPD data

    Description: Stores edited OPD data for an interaction and triggers ingestion

    Request Body:

    {
      "interaction_id": 75294,
      "hospital_id": "9",
      "data": {
        "response": "**Diagnosis:** **Costochondritis ragul**",
        "vitals": [
          {
            "pulse": "90",
            "height": "133",
            "weight": "102",
            "temperature": "99",
            "respRate": "69",
            "systolicBP": "81",
            "diastolicBP": "35",
            "oxygenSaturation": "1"
          }
        ],
        "assessment": [
          {
            "template_tests": "FibroScan"
          }
        ],
        "medication_templates": [
          {
            "medication_name": "(GABAWIN NT TABLET)",
            "medication_type": "tablet",
            "route": "Oral",
            "duration": "3 days",
            "brand_name": "gabawin nt tablet"
          }
        ],
        "additional_response": "**Chief Complaints:** - **Persistent pain**",
        "phonetic_uri": "gs://medscribe-dev/9/Endocrinology/217/medication_autocorrect.csv",
        "lab_data": {
          "lab_abnormal_data": ""
        }
      }
    }

    Responses:

    • 200: Edited OPD details saved and ingested
      {
        "status": true,
        "message": "Edited opd interaction details created and ingested successfully",
        "interaction_id": 75294,
        "uploadedUrls": "gs://medscribe-dev/editedOpd/75294_xxxx.txt"
      }
    • 400: Invalid request or missing data
      {
        "status": false,
        "message": "No relevant interaction detail found for ingestion"
      }
    • 404: Interaction not found
      {
        "status": false,
        "message": "Interaction with ID 75294 not found"
      }
    • 500: Internal server error during ingestion
      {
        "status": false,
        "message": "Failed to ingest Edited opd data"
      }

    GET /software/organization

    URL: {{baseUrl}}/software/organization?hospital_id=string

    Summary: Get organization by hospital ID

    Description: Retrieves an organization by its hospital ID.

    Parameters:

    hospital_id: string

    Responses:

    • 200: Successful operation
    • 400: Missing hospital_id
    • 404: Organization not found
    • 500: Internal server error

    PUT /software/organization/update

    URL: {{baseUrl}}/software/organization?hospital_id=string

    Summary: Update an organization

    Description: Updates an existing organization.

    Body

    
    {
        "hospital_id": "9",
        "name": "General Hospital",
        "type": "Hospital",
        "state": "California",
        "city": "Medcity",
        "country": "USA",
        "pin_code": "90210",
        "phone_number": "+1122334455",
        "email": "info@generalhospital.com",
        "website": "https://www.generalhospital.com",
        "fax_no": "+1122334466",
        "tax_id_no": "TAX-123456789",
        "address1": "789 Health St, Medcity",
        "description": "A leading hospital providing a wide range of medical services.",
        "time_zone": "America/Los_Angeles",
        "api_url": "https://api.generalhospital.com"
    }
        

    Note:

    • hospital_id: Must be unique — Must be in format "orgname-somenumber" (e.g., carescribe-001, carescribe-002). If you have multiple hospitals with the same organization, use sequential numbers like carescribe-001, carescribe-002, etc.
    • type: Can be either "Hospital" or "General Practitioner"
    • time_zone: Example: Asia/Kolkata
    • api_url: Client endpoint URL used to send POST OPD data

    Responses:

    • 200: Organization updated successfully
    • 400: Invalid input
    • 404: Organization not found
    • 500: Internal server error

    POST /software/createpatient

    Summary: Create a new patient

    Description: Creates a new patient record.

    Body

    
    {
        "hospital_id": "ORG123",
        "practitioner_id": "DOC456",
        "speciality_id": "SPEC789",
        "patient_id": "HOSPAT001",
        "first_name": "Jane",
        "last_name": "Doe",
        "date_of_birth": "1990-05-20",
        "phone_number": "+1987654321",
        "age": 34,
        "gender": "Female",
        "interaction_status": "99",
        "interaction_date": "2024-07-29",
        "token_number": "TKN456",
        "address1": "456 Oak Ave, Othertown, USA"
    }
        

    Note:

    • hospital_id: Example: ORG123
    • practitioner_id: Example: DOC456
    • speciality_id: The ID of the doctor's specialty (required when creating a token)
    • patient_id: Must be unique
    • first_name: Required
    • last_name: Required
    • date_of_birth: Format: YYYY-MM-DD (e.g., 1990-05-20)
    • phone_number: Include country code (e.g., +91)
    • interaction_date: Must always be in UTC format; it will be converted to the organization's time zone as needed

    Responses:

    • 201: Patient created successfully
    • 400: Invalid input
    • 409: Patient with hospital_patient_id already exists
    • 500: Internal server error

    GET /software/doctor/get

    Summary: Get doctor by practitioner ID

    Description: Retrieves a doctor by their practitioner ID.

    Parameters:

    practitioner_id: string
    hospital_id: string

    Responses:

    • 200: Successful operation
    • 400: Missing practitioner_id
    • 404: Doctor not found
    • 500: Internal server error

    PUT /software/doctor/update

    Summary: Update a doctor

    Description: Updates an existing doctor.

    Body

    
    {
        "first_name": "Alex",
        "last_name": "Patel",
        "speciality_id": 1,
        "salutation": "Dr",
        "hospital_id": "carescribe-001",
        "license_no": "TN12345",
        "phone_number": "+918883761709",
        "email": "alex.patel@example.com",
        "practitioner_id": "carescribe-001-dr001"
    }
        

    Note:

    • hospital_id: Required
    • practitioner_id: Required and must be unique
    • email: Required and must be unique
    • first_name: Required
    • last_name: Required
    • speciality_id: Required — fetch from /software/speciality/list endpoint
    • license_no: Required — if not available, pass as an empty string (" ")

    Responses:

    • 200: Doctor updated successfully
    • 400: Invalid input
    • 404: Doctor not found
    • 500: Internal server error

    PUT /software/doctor/settings

    Summary: Update doctor settings

    Description: Updates a doctor's opdassessment, opdsheet, and advanced_settings based on provided practitioner_id.

    Body

    
    {
        "practitioner_id": "PRAC-001",
        "hospital_id": "9",
        "plan": true,
        "follow_up": false,
        "investigations": true,
        "patient_history": false,
        "recommendations": true,
        "chief_complaints": true,
        "personal_history": false,
        "examination_findings": true,
        "history_of_presenting_illness": false,
        "vital": true,
        "medicine": false,
        "diagnosis": true,
        "assessment": false,
        "investigation": true,
        "brand": true,
        "generic": false,
        "TNMCRegNo": true,
        "genericFront": false,
        "FrequencyEvng": true,
        "preferredLang": "English",
        "prioritize_accuracy": true
    }
        

    Responses

    • 200: Doctor settings updated successfully
    • 404: Doctor not found
    • 500: Internal server error

    Response (200) Example

    
    {
        "message": "Doctor settings updated successfully",
        "doctor": {
            "doctor_id": 1,
            "practitioner_id": "PRAC-001",
            "opdassessment": {
                "plan": true,
                "follow_up": false,
                "investigations": true,
                "patient_history": false,
                "recommendations": true,
                "chief_complaints": true,
                "personal_history": false,
                "examination_findings": true,
                "history_of_presenting_illness": false
            },
            "opdsheet": {
                "sign": false,
                "vital": true,
                "summary": false,
                "medicine": false,
                "diagnosis": true,
                "drawImage": false,
                "assessment": false,
                "investigation": true,
                "datasheetimage": false
            },
            "advanced_settings": {
                "brand": true,
                "generic": false,
                "TNMCRegNo": true,
                "genericFront": false,
                "FrequencyEvng": true,
                "preferredLang": "English",
                "prioritize_accuracy": true
            }
        }
    }
        

    GET /software/get

    URL: {{baseUrl}}/software/get?patient_id=string&hospital_id=string

    Summary: Get patient by hospital ID

    Description: Fetches a patient's record using their hospital-specific ID and organization ID.

    Parameters:

    
    patient_id: string
    hospital_id: string
        

    Responses:

    • 200: Patient fetch successful
    • 400: Invalid input
    • 404: Patient not found
    • 500: Internal server error

    GET /software/getpatient

    URL: {{baseUrl}}/software/getpatient?id=string

    Summary: Get patient by ID

    Description: Retrieves patient details, including inpatient status, by their primary ID.

    Parameters:

    id: string

    Responses:

    • 200: Patient fetched successfully
    • 400: Missing id
    • 404: Patient not found
    • 500: Internal server error

    GET /software/getvital/list

    URL: {{baseUrl}}/software/getvital/list?patient_id=string&hospital_id=string

    Summary: Get vitals by patient ID

    Description: Retrieves all vital sign details for a specific patient.

    Parameters:

    
    patient_id: string
    hospital_id: string
        

    Responses:

    • 200: Successful operation
    • 400: Invalid input
    • 404: Patient or interactions not found
    • 500: Internal server error

    GET /software/language

    URL: {{baseUrl}}/software/language

    Summary: Get all languages

    Description: Retrieves a list of all available languages.

    Responses:

    • 200: Successful operation
    • 404: No languages found
    • 500: Internal server error

    GET /software/opdform

    URL: {{baseUrl}}/software/opdform?hospital_id=string

    Summary: Get OPD form by hospital ID

    Description: Retrieves the OPD form configuration by hospital ID.

    Parameters:

    hospital_id: string

    Responses:

    • 200: Successful operation
    • 400: Missing hospital_id
    • 404: Organization not found
    • 500: Internal server error
    POST /software/updateopd

    Summary: Update interaction details with edited OPD data.

    Description: Accepts JSON data, saves it as a text file in GCS, creates an InteractionDetail record, and triggers ingestion.

    Body

    {
          "interaction_id": 75294,
          "data": {
            "response": "**Diagnosis:** **Costochondritis **",
            "vitals": [ { "pulse": "90", "height": "133", "weight": "102" } ],
            "assessment": [ { "template_tests": "FibroScan" } ],
            "medication_templates": [ { "medication_name": "(GABAWIN NT TABLET)" } ],
            "additional_response": "**Chief Complaints:**...",
            "phonetic_uri": "gs://***********/***/Endocrinology/****/medication_autocorrect.csv",
            "lab_data": { "lab_abnormal_data": "" }
          }
        }
    Note:
    • interaction_id: Required — must exist in Interaction table
    • data: Required — JSON object, will be stringified before saving

    Responses

    • 200: Edited opd interaction details created and ingested successfully
    • {
              "status": true,
              "message": "Edited opd interaction details created and ingested successfully",
              "interaction_id": 75294,
              "uploadedUrls": "gs://********/********/75294_6c9f6ccf-3625-433b-9e60-bcf29ca9872e.txt",
              "pdfingestIntraction": {
                  "patient_id": "GEN9-202509-00288",
                  "interaction_date": "2025-09-15T15:19:04.000Z",
                  "interaction_status": "0",
                  "inpatient_id": null,
                  "interaction_id": 75294,
                  "nurse_id": null,
                  "doctor_id": 217,
                  "speciality_id": 2,
                  "interaction_type": null,
                  "interaction_notes": null,
                  "location": null,
                  "organization_id": "9",
                  "token_number": null,
                  "remote_id": null,
                  "created_at": "2025-09-15T15:19:05.000Z",
                  "updated_at": "2025-09-15T15:19:26.000Z",
                  "InteractionDetails": [
                      {
                          "interaction_id": 75294,
                          "interaction_detail_type": "Edited opd",
                          "attachment_url": "gs://********/*********/75294_6c9f6ccf-3625-433b-9e60-bcf29ca9872e.txt",
                          "vitals": null,
                          "detail_id": 40101,
                          "detail_notes": null,
                          "prescriptions": null,
                          "created_at": "2025-09-15T15:35:06.814Z",
                          "updated_at": "2025-09-15T15:35:06.814Z",
                          "processedFileContent": "{\n  \"response\": \"**Diagnosis:** **Costochondritis **\",\n  \"vitals\": [\n    {\n      \"pulse\": \"90\",\n      \"height\": \"133\",\n      \"weight\": \"102\",\n      \"temperature\": \"99\",\n      \"respRate\": \"69\",\n      \"bloodSugar\": \"84\",\n      \"systolicBP\": \"81\",\n      \"diastolicBP\": \"35\",\n      \"position\": \"Sitting\",\n      \"oxygenSaturation\": \"1\",\n      \"cancer\": false,\n      \"epilepsy\": false,\n      \"arthritis\": true,\n      \"abnormalPulse\": false,\n      \"abnormalOxygen\": false,\n      \"hyperthyrodism\": true,\n      \"kidneyDiseases\": true,\n      \"cardiacDiseases\": true,\n      \"diabetesMellitus\": true,\n      \"asthma\": false,\n      \"hypertension\": true,\n      \"hypothyroidism\": true,\n      \"abnormalSystolic\": false,\n      \"bmi\": \"57.66\"\n    }\n  ],\n  \"assessment\": [\n    {\n      \"template_tests\": \"FibroScan\"\n    }\n  ],\n  \"medication_templates\": [\n    {\n      \"medication_name\": \"(GABAWIN NT TABLET)\",\n      \"medication_type\": \"tablet\",\n      \"dosage\": null,\n      \"route\": \"Oral\",\n      \"frequency_morning\": \"0\",\n      \"frequency_afternoon\": \"0\",\n      \"frequency_evening\": \"0\",\n      \"frequency_night\": \"1\",\n      \"duration\": \"3 days\",\n      \"instructions\": null,\n      \"auto_correct\": false,\n      \"actual_medication_name\": \"Gabawin NT\",\n      \"brand_name\": \"gabawin nt tablet\",\n      \"generic_name\": \"\",\n      \"med_from_llm\": true\n    },\n    {\n      \"medication_name\": \"(3374 TABLET )\",\n      \"medication_type\": \"tablet\",\n      \"dosage\": null,\n      \"route\": \"Topical\",\n      \"frequency_morning\": null,\n      \"frequency_afternoon\": null,\n      \"frequency_evening\": null,\n      \"frequency_night\": null,\n      \"duration\": \"5 days\",\n      \"instructions\": \"Use as needed.\",\n      \"actual_medication_name\": \"Ultracet\",\n      \"auto_correct\": true,\n      \"brand_name\": \"3374 tablet\",\n      \"generic_name\": \"\",\n      \"med_from_llm\": true\n    }\n  ],\n  \"additional_response\": \"**Chief Complaints:**\\n- **Persistent pain in a specific area **.\\n\\n\\n\\n**History of Presenting Illness:**\\nPatient reports **persistent pain** in a specific area. The pain is continuous, with occasional flare-ups of increased intensity. Patient mentions that the pain feels like a wound. Patient mentions that the pain feels like a wound. Patient has been taking 3374 tablet for pain relief, which provides approximately 80% relief when taken. Patient takes it intermittently, every four to five days or once a week, when the pain is severe. Patient notes that lifting weights aggravates the pain. Patient also mentions that a gel prescribed previously was not effective.\\n\\n\\n\\n**Past Medical History:**\\n- **Dyslipidemia**\\n- **Non-alcoholic fatty liver disease**\\n\\n\\n\\n**Personal History:** \\n\\n**Examination Findings:** \\n\\n**Investigations:**\\n- **Nerve conduction studies reviewed**: Normal findings.\\n- **Blood tests reviewed**: Normal findings.\\n- **LFT reviewed**: Normal enzymes.\\n\\n\\n\\n**Recommendations:**\\n- **Continue walking**, as stretching helps reduce stiffness.\\n- Avoid lifting heavy weights.\\n\\n\\n\\n**Reported Medications:** \\n\\n**Follow-up:**\\n- **Follow up after 5 days**.\\n\\n\\n\\n**Plan:**\\n- Patient is advised to continue current medications and use a topical agent for 5 days.\\n- A nerve block may be considered if pain persists.\\n- A FibroScan is recommended to further evaluate the liver, which can be done on Saturday.\\n\\n\",\n  \"phonetic_uri\": \"gs://***********/*******/**********/****/medication_autocorrect.csv\",\n  \"lab_data\": {\n    \"lab_abnormal_data\": \"\"\n  }\n}",
                          "processedFileContentImage": null
                      }
                  ]
              }
          }
    • 400: No relevant interaction detail found / invalid payload
    • 404: Interaction not found
    • 500: Server or ingestion error
    PATCH /software/upadte-opd-order

    Summary: Update OPD order for a hospital.

    Description: Updates the opd_order JSON object stored in the Organization table for the specified hospital.

    Body

    {
          "hospital_id": 9,
          "opd_order": {
            "diagnosis": 1,
            "medicine": 2,
            "investigation": 3,
            "vital": 4,
            "assessment": 5,
            "summary": 6,
            "datasheet": 7,
            "signature": 8
          }
        }
    Note:
    • hospital_id: Required — must exist in Organization table
    • opd_order: Required — JSON object defining order of OPD sections

    Responses

    • 200: OPD order updated
      {
              "message": "✅ OPD order updated",
              "opd_order": {
                  "diagnosis": 1,
                  "medicine": 2,
                  "investigation": 3,
                  "vital": 4,
                  "assessment": 5,
                  "summary": 6,
                  "datasheet": 7,
                  "signature": 8
              }
          }
    • 400: Invalid input
    • 404: Organization not found
    • 500: Server error

    PUT /software/opdform/update

    URL: {{baseUrl}}/software/opdform/update

    Summary: Update OPD form

    Description: Updates the OPD form configuration for a hospital using multipart/form-data, including optional logo image uploads.

    Body (multipart/form-data)

    
    hospital_id: string (required)
    unit: string
    footer: string
    contact: string
    marginTop: string
    marginLeft: string
    marginRight: string
    marginBottom: string
    show_footer: string ("true" | "false")
    show_header: string ("true" | "false")
    hospital_name: string
    outpatient_title: string
    patientDetailsshow: string ("true" | "false")
    left_image: file (optional)
    right_image: file (optional)
        

    Responses:

    • 200: OPD form updated successfully
    • 400: Invalid input
    • 404: Organization not found
    • 500: Internal server error

    POST /software/post-medication

    URL: {{baseUrl}}/software/post-medication

    Summary: Post medication data

    Description: Uploads medication data for an organization.

    Body

    
    {
        "hospital_id": "ORG123",
        "medications": [
            {
                "BRAND NAME": "Tylenol",
                "GENERIC NAME": "Acetaminophen"
            }
        ]
    }
        

    Required fields: hospital_id, a non-empty medications array, BRAND NAME, and GENERIC NAME.

    Optional medication fields: BRAND ID, UOM CODE, UOM DESCRIPTION, ACTIVE FROM, ACTIVE TO, and MEDICATION TYPE. UOM DESCRIPTION requires UOM CODE; active dates use DD/MM/YYYY.

    Responses:

    • 200: Medication data uploaded successfully
    • 400: Invalid input
    • 404: Organization not found
    • 500: Internal server error

    POST /software/saveVitals

    Summary: Save vitals data

    Description: Saves vital signs for a patient and associates them with an interaction.

    Body

    
    {
        "patient_id": "e53aed9a",
        "hospital_id": "9",
        "first_name": "ragul",
        "last_name": "R",
        "date_of_birth": null,
        "gender": "M",
        "age": 9,
        "interaction_date": "2024-01-02T10:00:00Z",
        "vitalsData": {
            "position": "Sitting",
            "height": "165",
            "weight": "34",
            "temperature": "59",
            "respRate": "74",
            "bloodSugar": "82",
            "systolicBP": "8",
            "abnormalSystolic": true,
            "diastolicBP": "26",
            "pulse": "9",
            "abnormalPulse": true,
            "oxygenSaturation": "76",
            "abnormalOxygen": true,
            "cardiacDiseases": true,
            "hypothyroidism": true,
            "hyperthyrodism": true,
            "kidneyDiseases": true,
            "asthma": true,
            "allergy": true,
            "cancer": true,
            "arthritis": true,
            "epilepsy": true,
            "hypertension": true,
            "dyslipidemia": true
        }
    }
        

    Vitals Section (vitalsData):

    • position (string): Patient's posture during measurement (e.g., Sitting, Lying).
    • height (string): Height in centimeters.
    • weight (string): Weight in kilograms.
    • temperature (string): Body temperature (Fahrenheit or Celsius, as per hospital standard).
    • respRate (string): Respiratory rate (breaths per minute).
    • bloodSugar (string): Blood sugar level (mg/dL).
    • systolicBP, diastolicBP (string): Blood pressure values.
    • abnormalSystolic (boolean): Indicates abnormal systolic BP.
    • pulse (string): Pulse rate (beats per minute).
    • abnormalPulse (boolean): Indicates abnormal pulse.
    • oxygenSaturation (string): Oxygen saturation percentage.
    • abnormalOxygen (boolean): Indicates abnormal oxygen levels.

    Comorbidities / Medical History (All boolean values):

    • cardiacDiseases
    • hypothyroidism
    • hyperthyroidism
    • kidneyDiseases
    • asthma
    • allergy
    • cancer
    • arthritis
    • epilepsy
    • hypertension
    • dyslipidemia

    Notes

    "first_name": "ragul" or null, "last_name": "R" or null, "date_of_birth": null, "gender": "M", "age": 9,

    Responses:

    • 200: Vitals ingested successfully
    • 400: Invalid input
    • 404: Patient or organization not found
    • 500: Internal server error

    GET /software/search-patient

    URL: {{baseUrl}}/software/search-patient?hospital_id=string&query=string

    Summary: Search for patients

    Description: Searches for patients by name, phone number, or patient ID within an organization.

    Parameters:

    
    hospital_id: string
    query: string
        

    Responses:

    • 200: Successful operation
    • 400: Invalid input
    • 404: No matching patients found
    • 500: Internal server error

    POST /software/speciality/create

    URL: {{baseUrl}}/software/speciality/create

    Summary: Create a speciality

    Description: Creates a new speciality.

    Body

    
    {
        "specialty_name": "Cardiology",
        "description": "Specializes in diagnosing and treating heart conditions.",
        "short_prompt_id": 1,
        "long_prompt_id": 1
    }
        

    Note:

    • specialty_name (required)
    • description (required)
    • short_prompt_id (optional) or 1
    • long_prompt_id (optional) or 1

    Responses:

    • 201: Speciality created successfully
    • 400: Invalid input
    • 409: Speciality already exists
    • 500: Internal server error

    GET /software/speciality

    URL: {{baseUrl}}/software/speciality

    Summary: Get speciality by ID

    Description: Retrieves a single speciality by its ID.

    Parameters:

    id: integer

    Note: Get speciality data

    Responses:

    • 200: Speciality retrieved successfully
    • 400: Missing id
    • 404: Speciality not found
    • 500: Internal server error

    PUT /software/speciality/update

    URL: {{baseUrl}}/software/speciality/update

    Summary: Update a speciality

    Description: Updates an existing speciality.

    Body

    
    {
        "id": integer,
        "specialty_name": string,
        "description": string,
        "short_prompt_id": integer,
        "long_prompt_id": integer
    }
        

    Responses:

    • 200: Speciality updated successfully
    • 400: Invalid input
    • 404: Speciality not found
    • 500: Internal server error

    Section A — Assessment Templates

    POST /software/assessment/create

    Summary: Create a new assessment template

    Description: Creates a template for the given practitioner.

    Body

    
    {
        "practitioner_id": "PRAC-123",
        "hospital_id": "9",
        "assessment_template": "General Health Checkup",
        "template_tests": "Blood Test, X-Ray"
    }
        

    Responses

    • 201: Created — returns assessment object (IDs, template, tests, timestamps)
    • 404: Doctor not found
    • 409: Duplicate template name
    • 500: Internal error
    GET /software/assessment/check-name

    Summary: Check if template name exists for the doctor

    Query String

    practitioner_id=PRAC-123&hospital_id=9&assessment_template=General%20Health%20Checkup

    Responses

    • 200: { "exists": true|false, "message": "..." }
    • 404: Doctor not found
    • 500: Internal error
    GET /software/assessment/list

    Summary: List all assessment templates for a doctor

    Query String

    practitioner_id=PRAC-123

    Response (200) Example

    
    {
        "status": "success",
        "assessments": [
            {
                "assessment_id": 101,
                "assessment_template": "General Physical Exam",
                "template_tests": "BP, SPO2, BMI"
            }
        ]
    }
        

    Other Responses

    • 404: No assessments or doctor not found
    • 500: Internal error
    PUT /software/assessment/update

    Summary: Update an assessment by assessment_id for a practitioner

    Body

    
    {
        "assessment_id": "ASMT-12345",
        "practitioner_id": "PRAC-123",
        "hospital_id": "9",
        "assessment_template": "General Health Checkup",
        "template_tests": "Blood Test, ECG"
    }
        

    Responses

    • 200: Returns updated assessment object
    • 404: Doctor or assessment not found
    • 500: Internal error
    DELETE /software/assessment/delete

    Summary: Delete an assessment by assessment_id for a practitioner

    Query String

    assessment_id=101&practitioner_id=PRAC-123&hospital_id=9

    Responses

    • 200: { "message": "Assessment deleted successfully.", "assessment": 101 }
    • 404: Doctor or assessment not found
    • 500: Internal error

    Section B — Medication Templates

    POST /software/medicationtemplate/create

    Summary: Create medication template

    Body

    
    {
        "template_name": "Hypertension A",
        "practitioner_id": "PRAC-123",
        "hospital_id": "9"
    }
        

    Responses

    • 201: Created — returns data with IDs and name
    • 400: Validation / duplicate name
    • 404: Doctor not found
    • 500: Internal error
    PUT /software/medicationtemplate/update

    Summary: Update medication template by template_id

    Body

    
    {
        "template_id": 9001,
        "template_name": "Hypertension A (v2)",
        "practitioner_id": "PRAC-123",
        "hospital_id": "9"
    }
        

    Responses

    • 200: Updated — returns data with IDs and name
    • 400: Validation error
    • 404: Doctor or template not found
    • 500: Internal error
    GET /software/medicationtemplate/by-doctor

    Summary: List medication templates by practitioner

    Query String

    practitioner_id=PRAC-123

    Response (200) Example

    
    {
        "data": [
            {
                "template_id": 9001,
                "organization_id": "ORG-001",
                "template_name": "Hypertension A",
                "doctor_id": 55
            }
        ]
    }
        

    Responses

    • 400: practitioner_id missing
    • 404: Doctor not found or no templates
    • 500: Internal error
    GET /software/medicationtemplate/by-id

    Summary: Get medication template by ID & practitioner

    Query String

    template_id=9001&practitioner_id=PRAC-123&hospital_id=9

    Response (200) Example

    
    {
        "data": {
            "template_id": 9001,
            "organization_id": "ORG-001",
            "template_name": "Hypertension A",
            "doctor_id": 55
        }
    }
        
    • 400: Missing template_id or practitioner_id
    • 404: Template or doctor not found
    • 500: Internal error

    Section C — Medications

    POST /software/medication/create

    Summary: Create a new medication entry for a template

    Body

    
    {
        "template_id": "temp-001",
        "brand_id" : 1,
        "medication_name": "Amlodipine",
        "medication_type": "Tablet",
        "dosage": "5 mg",
        "frequency_morning": 1,
        "frequency_afternoon": 0,
        "frequency_evening": 1,
        "frequency_night": 0,
        "route": "Oral",
        "duration": "30 days",
        "instructions": "Take after breakfast",
        "hospital_id": "9",
        "practitioner_id": "PRAC-123"
    }
        

    Responses

    • 201: Medication successfully created
    • 400: Missing required fields
    • 500: Internal error
    PUT /software/medication/update

    Summary: Update medication by medication_id

    Body

    
    {
        "medication_id": 7001,
        "template_id": 9001,
        "brand_id" :  1,
        "medication_name": "Amlodipine",
        "medication_type": "Tablet",
        "dosage": "10 mg",
        "frequency_morning": 1,
        "frequency_afternoon": 0,
        "frequency_evening": 0,
        "frequency_night": 1,
        "route": "Oral",
        "duration": "15 days",
        "instructions": "After dinner",
        "hospital_id": "9",
        "practitioner_id": "PRAC-123"
    }
        

    Responses

    • 200: Updated — returns data with the medication
    • 400: Medication ID is required
    • 404: Not found
    • 500: Internal error
    DELETE /software/medication/delete

    Summary: Delete medication by ID & practitioner

    Query String

    medication_id=7001&practitioner_id=PRAC-123&hospital_id=9

    Responses

    • 200: Medication successfully deleted
    • 400: Medication ID is required
    • 404: Medication not found
    • 500: Internal error
    POST /software/uploadMedicationCsv

    URL: {{baseUrl}}/software/uploadMedicationCsv

    Summary: Upload a medication CSV file

    Description: Upload a CSV file containing medication data for an organization, identified by hospital_id. The file is stored in Google Cloud Storage, and any existing file is deleted.

    Note: BRAND NAME and GENERIC NAME are required. BRAND ID, UOM CODE, UOM DESCRIPTION, ACTIVE FROM, ACTIVE TO, and MEDICATION TYPE are optional and must remain in that order. Active dates use DD/MM/YYYY.

    BRAND NAME GENERIC NAME
    Paracetamol Acetaminophen

    BRAND ID BRAND NAME GENERIC NAME
    101 Augmentin Amoxicillin + Clavulanic Acid

    Parameters

    • Query: hospital_id (string, required) – The ID of the hospital associated with the organization.
    • FormData: csvFile (binary, required) – The CSV file containing medication data.

    Responses

    • 200: CSV uploaded and saved successfully
      {
        "message": "CSV uploaded and saved",
        "data": "https://storage.googleapis.com/bucket/csv_uploads/org123_2025_09_02_13_30_45.csv",
        "invalid": [
              {
                  "BRAND ID": "",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID is empty"
              },
              {
                  "BRAND ID": "287526",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID already exists"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "Missing required fields (BRAND NAME)"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal salin",
                  "GENERIC NAME": "",
                  "error": "Missing required fields (GENERIC NAME)"
              }
          ]
      }
      
    • 400: Invalid request
    • 404: Organization not found
    • 500: Internal server error
    POST /software/updateMedicationCsvList

    URL: {{baseUrl}}/software/updateMedicationCsvList

    Summary: update a medication CSV file

    Description: update a CSV file containing medication data for an organization, identified by hospital_id. The file is stored in Google Cloud Storage, and any existing file is deleted.

    Note: BRAND NAME and GENERIC NAME are required. BRAND ID, UOM CODE, UOM DESCRIPTION, ACTIVE FROM, ACTIVE TO, and MEDICATION TYPE are optional and must remain in that order. Follow the BRAND ID presence used by the existing CSV, and use DD/MM/YYYY for active dates.

    BRAND NAME GENERIC NAME
    Paracetamol Acetaminophen

    BRAND ID BRAND NAME GENERIC NAME
    101 Augmentin Amoxicillin + Clavulanic Acid

    Parameters

    • Query: hospital_id (string, required) – The ID of the hospital associated with the organization.
    • FormData: csvFile (binary, required) – The CSV file containing medication data.

    Responses

    • 200: CSV updateed and saved successfully
      {
        "message": "CSV updateed and saved",
        "data": "https://storage.googleapis.com/bucket/csv_uploads/org123_2025_09_02_13_30_45.csv",
        "invalid": [
              {
                  "BRAND ID": "",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID is empty"
              },
              {
                  "BRAND ID": "287526",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID already exists"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "Missing required fields (BRAND NAME)"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal salin",
                  "GENERIC NAME": "",
                  "error": "Missing required fields (GENERIC NAME)"
              }
          ]
      }
      
    • 400: Invalid request
    • 404: Organization not found
    • 500: Internal server error
    POST /software/removeMedicationCsv

    URL: {{baseUrl}}/software/removeMedicationCsv

    Summary: Remove a medication CSV file

    Description: Remove the medication CSV file associated with an organization, identified by hospital_id, from Google Cloud Storage.

    Parameters

    • Query: hospital_id (string, required) – The ID of the hospital associated with the organization.

    Responses

    • 200: Medication CSV removed successfully
      {
        "message": "Medication CSV removed successfully"
      }
    • 400: Invalid request
    • 404: Organization not found
    • 500: Internal server error
    PUT /software/updateMedicationCsv

    URL: {{baseUrl}}/software/updateMedicationCsv

    Summary: Update medication CSV data

    Description: Update the medication CSV file for an organization by merging new medication data with existing data, removing duplicates, and storing the updated file in Google Cloud Storage.

    Body

    {
      "hospital_id": "hosp-123",
      "medications": [
        {
          "BRAND ID": "1",
          "BRAND NAME": "Norvasc",
          "GENERIC NAME": "Amlodipine"
        }
      ]
    }

    Required row fields: BRAND NAME, GENERIC NAME.

    Optional row fields: BRAND ID, UOM CODE, UOM DESCRIPTION, ACTIVE FROM, ACTIVE TO, and MEDICATION TYPE. Active dates use DD/MM/YYYY.

    Responses

    • 200: Medication data updated successfully
      {
        "message": "Medication data updated successfully (duplicates removed, old file deleted)",
        "data": "https://storage.googleapis.com/bucket/csv_uploads/org123_2025_09_02_13_30_45.csv",
        "invalid": [
              {
                  "BRAND ID": "",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID is empty"
              },
              {
                  "BRAND ID": "287526",
                  "BRAND NAME": "DOLODART 60ML SYRUP",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "BRAND ID already exists"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "",
                  "GENERIC NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal saline",
                  "error": "Missing required fields (BRAND NAME)"
              },
              {
                  "BRAND ID": "1",
                  "BRAND NAME": "Alprazolam, Interferon Alfa, Testosterone, 0.45% normal salin",
                  "GENERIC NAME": "",
                  "error": "Missing required fields (GENERIC NAME)"
              }
          ]
      }
      
    • 400: Invalid request body
    • 404: Organization not found
    • 500: Internal server error
    GET /software/medication/template

    Summary: Get medications by template

    Query String

    template_id=9001&practitioner_id=PRAC-123

    Response (200) Example

    
    {
        "data": [
            {
                "medication_id": 7001,
                "medication_name": "Amlodipine",
                "dosage": "5 mg",
                "frequency_morning": 1,
                "frequency_afternoon": 0,
                "frequency_evening": 1,
                "frequency_night": 0,
                "route": "Oral",
                "duration": "30 days",
                "instructions": "Take after breakfast"
            }
        ]
    }
        
    • 400: Template ID is required
    • 500: Internal error
    GET /software/medication/getById

    Summary: Get medication by ID

    Query String

    medication_id=7001&practitioner_id=PRAC-123&hospital_id=9

    Response (200) Example

    
    {
        "message": "Medication",
        "data": {
            "medication_id": 7001,
            "medication_name": "Amlodipine",
            "dosage": "5 mg",
            "frequency_morning": 1,
            "frequency_afternoon": 0,
            "frequency_evening": 1,
            "frequency_night": 0,
            "route": "Oral",
            "duration": "30 days",
            "instructions": "Take after breakfast"
        }
    }
        
    • 400: Medication ID is required
    • 404: Medication not found
    • 500: Internal error

    Access CareScribe Software Integration API (3.6.1): https://swagger-api2.carescribe.health/