top of page

Code Examples

In this section, we'll provide practical code examples to guide developers through their initial integration with our APIs, offering clear and concise implementations to accelerate the onboarding process and simplify API adoption.

Introduction

Welcome to the WaveLight API integration guide.

Our documentation provides a simple code example in javascript (js), designed to facilitate integration with the WaveLight API. We provide detailed implementations to meet the diverse needs of developers.

​​

Our goal is to simplify API implementation in different environments, ensuring flexibility and compatibility. Our guides provide clear instructions and practical examples for efficient integration.

​​

This document will help you understand how to:

  1. Create a Service Request (request for analysis)

  2. Upload a video for processing

  3. Receive real-time results via SSE (Server-Sent Events)

Overview

 

The integration flow has three main steps:

[1] Service Request  ---> returns requestId + uploadUrl
          |
          v
[2] Video Upload     ---> sends the video to uploadUrl
          |
          v
[3] SSE Results      ---> connects using requestId and receives results in real time

1. Service Request Response

The Service Request is the starting point.

Here you tell the API which services you want to run:

  • Pulse →  wc_pr-avg_sk_beta 

  • Oxygen Saturation →  wc_o2-avg_sk_beta 

  • Blood Pressure →  wc_bp-neural_sk_beta 

 

Important notes:

  • If you request blood pressure, you must provide patient data (age, sex, height, weight).

  • For other services, these values can be omitted.

Example Request:

POST https://api.wavelighthealth.com/gateway/service-request
Headers:
  Content-Type: application/json
  x-api-key: YOUR_API_KEY

Body:
{
  "serviceList": ["wc_pr-avg_sk_beta", "wc_o2-avg_sk_beta"],
  "WPG_Object": {
    "header": { "content-type": "", "version": "", "hash": "", "secure": true },
    "study": { "created": "2025-09-16T13:36:28.872Z" },
    "patient": {
      "anonymous": [
        { "label": "age", "unit": "years" },
        { "label": "sex", "unit": "enum", "value": "UNDEFINED" },
        { "label": "height", "unit": "cm" },
        { "label": "weight", "unit": "kg" }
      ]
    }
  }
}

Example Response:

{
  "requestId": "12345-abcde",
  "uploadVideoUrl": "https://upload-url-provided-by-api.com/xyz",
  "status": "PENDING"
}

2. Video Upload Status

After the Service Request, you must upload your video to the URL returned  (uploadVideoUrl).

Example Upload (JavaScript):

await fetch(uploadUrl, {
  method: "PUT",
  headers: { "Content-Type": "application/octet-stream" },
  body: selectedVideoFile
});

Expected Response:

{
  "status": 200,
  "statusText": "OK",
  "videoSize": "12.5 MB",
  "uploadUrl": "https://upload-url-provided-by-api.com/xyz",
  "timestamp": "2025-09-16T14:00:00.000Z"
}

3. Real-time Results (SSE)

The API delivers results in real-time using SSE (Server-Sent Events).

 

How it works:

  • Connect to endpoint:   /gateway/sse-request-track/{requestId} 

  • The API streams events until processing is finished.

 

Event Types:

  •  PARTIAL_PROGRESS  → partial results

  •  SUCCESS  → final results

Example Final Result:

{
  "event": "status",
  "data": "SUCCESS",
  "results": [
    { "name": "HEART BEATS", "return": "[{\"label\": \"PR-AVG\", \"value\": [72]}]" },
    { "name": "OXIMETRY", "return": "[{\"label\": \"Oximetry\", \"value\": [98]}]" }
  ]
}

Full Example (Fixed Data)

This example includes Pulse, Oxygen Saturation, and Blood Pressure.

Patient data is hardcoded in the request body for demonstration purposes:

  • Age = 45

  • Sex = Male

  • Height = 172 cm

  • Weight = 85 kg

Warning: In production, these values must come from the actual patient (form or medical system).

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>WaveLight API Test</title>
  <script src="https://unpkg.com/event-source-polyfill@1.0.31/src/eventsource.min.js"></script>
</head>
<body>
  <h1>WaveLight API Demo</h1>

  <!-- Control buttons -->
  <input type="file" id="videoInput" accept="video/*" style="display: none;" />
  <button onclick="document.getElementById('videoInput').click()">Select Video</button>
  <button id="startButton" onclick="runFullProcess()">Start</button>

  <!-- Result areas -->
  <h3>1. Service Request Response</h3>
  <pre id="serviceResponse">Waiting...</pre>

  <h3>2. Video Upload Status</h3>
  <pre id="uploadStatus">Waiting...</pre>

  <h3>3. Real-time Results (SSE)</h3>
  <pre id="sseResults">Waiting...</pre>

  <script>
    // API configuration
    const API_URL = "https://api.wavelighthealth.com";
    const API_KEY = "YOUR_API_KEY_HERE"; // replace with your real key

    let eventSource = null;
    let selectedVideoFile = null;

    // File selection
    document.getElementById("videoInput").addEventListener("change", (e) => {
      selectedVideoFile = e.target.files[0];
      if (selectedVideoFile) {
        const sizeInMB = (selectedVideoFile.size / 1024 / 1024).toFixed(2);
        document.getElementById("uploadStatus").textContent =
          `Video selected: ${selectedVideoFile.name} (${sizeInMB} MB)`;
      }
    });

    // Main function: runs the full process
    async function runFullProcess() {
      if (!selectedVideoFile) {
        alert("Please select a video before starting!");
        return;
      }

      const button = document.getElementById("startButton");
      button.disabled = true;

      // Clear previous results
      document.getElementById("serviceResponse").textContent = "Processing...";
      document.getElementById("uploadStatus").textContent = "Waiting for upload...";
      document.getElementById("sseResults").textContent = "Waiting for results...";

      try {
        // 1. Create Service Request
        const serviceResponse = await makeServiceRequest();
        document.getElementById("serviceResponse").textContent =
          JSON.stringify(serviceResponse, null, 2);

        // 2. Upload video
        await uploadVideo(serviceResponse);

        // 3. Listen to real-time results (SSE)
        listenToSSE(serviceResponse);

      } catch (error) {
        console.error("Process error:", error);
        document.getElementById("uploadStatus").textContent = `Error: ${error.message}`;
        button.disabled = false;
      }
    }

    // === 1. Service Request ===
    async function makeServiceRequest() {
      const createdDate = new Date().toISOString();

      const requestBody = {
        serviceList: [
          "wc_pr-avg_sk_beta",     // Pulse
          "wc_o2-avg_sk_beta",     // Oxygen Saturation
          "wc_bp-neural_sk_beta"   // Blood Pressure
        ],
        WPG_Object: {
          header: { "content-type": "", version: "", hash: "", secure: true },
          study: {
            created: createdDate,
            source: {
              device: { model: navigator.userAgent, features: [] },
              institution: "Wavelight",
              application: "WaveLight API Demo"
            }
          },
          // ⚠️ IMPORTANT:
          // In this example, patient data is FIXED for demonstration.
          // In a real application, these values must come from a form
          // or integration with an electronic health record (EHR).
          patient: {
            anonymous: [
              { label: "age", unit: "years", value: 45 },
              { label: "sex", unit: "enum", value: "MALE" },
              { label: "height", unit: "cm", value: 172 },
              { label: "weight", unit: "kg", value: 85 }
            ]
          }
        }
      };

      const response = await fetch(`${API_URL}/gateway/service-request`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": API_KEY
        },
        body: JSON.stringify(requestBody)
      });

      if (!response.ok) {
        throw new Error(`Service Request Error: HTTP ${response.status}`);
      }
      return await response.json();
    }

    // === 2. Video Upload ===
    async function uploadVideo(serviceResponse) {
      const uploadUrl = serviceResponse.uploadVideoUrl;
      if (!uploadUrl) throw new Error("Upload URL not provided");

      const videoSize = (selectedVideoFile.size / 1024 / 1024).toFixed(2);
      document.getElementById("uploadStatus").textContent =
        `Uploading video (${videoSize} MB)...`;

      const uploadResponse = await fetch(uploadUrl, {
        method: "PUT",
        headers: { "Content-Type": "application/octet-stream" },
        body: selectedVideoFile
      });

      if (!uploadResponse.ok) {
        throw new Error(`Upload failed: HTTP ${uploadResponse.status}`);
      }

      document.getElementById("uploadStatus").textContent =
        `Upload completed (${videoSize} MB)`;
    }

    // === 3. Listen to SSE ===
    function listenToSSE(serviceResponse) {
      const requestId = serviceResponse.requestId;
      if (!requestId) throw new Error("Request ID not provided");

      const sseUrl = `${API_URL}/gateway/sse-request-track/${requestId}`;
      const sseResultsEl = document.getElementById("sseResults");

      if (eventSource) eventSource.close(); // close old connection

      eventSource = new EventSourcePolyfill(sseUrl, {
        headers: { "x-api-key": API_KEY }
      });

      eventSource.onopen = () => {
        sseResultsEl.textContent = "SSE connection established...\n";
      };

      eventSource.onmessage = (event) => {
        const data = JSON.parse(event.data);
        sseResultsEl.textContent += JSON.stringify(data, null, 2) + "\n\n";

        if (data.event === "status" && data.data === "SUCCESS") {
          sseResultsEl.textContent += "\n✅ Final results received.\n";
          eventSource.close();
          document.getElementById("startButton").disabled = false;
        }
      };

      eventSource.onerror = (err) => {
        sseResultsEl.textContent += "\n❌ SSE connection error\n";
        console.error("SSE error:", err);
        eventSource.close();
        document.getElementById("startButton").disabled = false;
      };
    }

    // Close SSE connection when leaving the page
    window.addEventListener("beforeunload", () => {
      if (eventSource) eventSource.close();
    });
  </script>
</body>
</html>

Alternative Example (Form Input)

In this example, patient data is collected from a simple HTML form.


If the developer selects Blood Pressure, the form appears and requires values for Age, Sex, Height, and Weight.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>WaveLight API - Example with Form</title>
  <script src="https://unpkg.com/event-source-polyfill@1.0.31/src/eventsource.min.js"></script>
</head>
<body>
  <h1>WaveLight API Demo (with form)</h1>

  <!-- Service selection -->
  <h3>Select services</h3>
  <label><input type="checkbox" class="serviceOption" value="wc_pr-avg_sk_beta"> Pulse</label><br>
  <label><input type="checkbox" class="serviceOption" value="wc_o2-avg_sk_beta"> Oxygen Saturation</label><br>
  <label><input type="checkbox" id="bpCheckbox" class="serviceOption" value="wc_bp-neural_sk_beta"> Blood Pressure</label>

  <!-- Patient form (only visible if Blood Pressure is selected) -->
  <div id="bpForm" style="display:none; margin-top:10px;">
    <label>Age: <input type="number" id="age"></label><br>
    <label>Sex:
      <select id="sex">
        <option value="MALE">Male</option>
        <option value="FEMALE">Female</option>
      </select>
    </label><br>
    <label>Height (cm): <input type="number" id="height"></label><br>
    <label>Weight (kg): <input type="number" id="weight"></label>
  </div>

  <!-- Controls -->
  <br>
  <input type="file" id="videoInput" accept="video/*" style="display: none;" />
  <button onclick="document.getElementById('videoInput').click()">Select Video</button>
  <button id="startButton" onclick="runFullProcess()">Start</button>

  <!-- Results -->
  <h3>Service Request Response</h3>
  <pre id="serviceResponse">Waiting...</pre>

  <h3>Upload Status</h3>
  <pre id="uploadStatus">Waiting...</pre>

  <h3>Real-time Results (SSE)</h3>
  <pre id="sseResults">Waiting...</pre>

  <script>
    const API_URL = "https://api.wavelighthealth.com";
    const API_KEY = "YOUR_API_KEY_HERE"; // insert your valid key

    let eventSource = null;
    let selectedVideoFile = null;

    // Show/hide patient form if Blood Pressure is selected
    document.getElementById("bpCheckbox").addEventListener("change", function() {
      document.getElementById("bpForm").style.display = this.checked ? "block" : "none";
    });

    // File selection
    document.getElementById("videoInput").addEventListener("change", (e) => {
      selectedVideoFile = e.target.files[0];
      if (selectedVideoFile) {
        document.getElementById("uploadStatus").textContent =
          `Video selected: ${selectedVideoFile.name}`;
      }
    });

    // Main flow
    async function runFullProcess() {
      if (!selectedVideoFile) {
        alert("Please select a video before starting!");
        return;
      }

      document.getElementById("serviceResponse").textContent = "Processing...";
      document.getElementById("uploadStatus").textContent = "Waiting for upload...";
      document.getElementById("sseResults").textContent = "Waiting for results...";

      try {
        const serviceResponse = await makeServiceRequest();
        document.getElementById("serviceResponse").textContent =
          JSON.stringify(serviceResponse, null, 2);

        await uploadVideo(serviceResponse);
        listenToSSE(serviceResponse);

      } catch (error) {
        document.getElementById("uploadStatus").textContent = `Error: ${error.message}`;
      }
    }

    // 1. Service Request
    async function makeServiceRequest() {
      const createdDate = new Date().toISOString();
      const selectedServices = Array.from(document.querySelectorAll(".serviceOption:checked"))
                                   .map(el => el.value);

      if (selectedServices.length === 0) {
        throw new Error("Please select at least one service.");
      }

      // Prepare patient data
      let patientData;
      if (selectedServices.includes("wc_bp-neural_sk_beta")) {
        const age = document.getElementById("age").value;
        const sex = document.getElementById("sex").value;
        const height = document.getElementById("height").value;
        const weight = document.getElementById("weight").value;

        if (!age || !height || !weight) {
          throw new Error("Please fill all patient data for blood pressure.");
        }

        patientData = {
          anonymous: [
            { label: "age", unit: "years", value: parseInt(age) },
            { label: "sex", unit: "enum", value: sex },
            { label: "height", unit: "cm", value: parseInt(height) },
            { label: "weight", unit: "kg", value: parseInt(weight) }
          ]
        };
      } else {
        patientData = {
          anonymous: [
            { label: "age", unit: "years" },
            { label: "sex", unit: "enum", value: "UNDEFINED" },
            { label: "height", unit: "cm" },
            { label: "weight", unit: "kg" }
          ]
        };
      }

      const requestBody = {
        serviceList: selectedServices,
        WPG_Object: {
          header: { "content-type": "", version: "", hash: "", secure: true },
          study: { created: createdDate, source: { device: { model: navigator.userAgent } } },
          patient: patientData
        }
      };

      const response = await fetch(`${API_URL}/gateway/service-request`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": API_KEY
        },
        body: JSON.stringify(requestBody)
      });

      if (!response.ok) {
        throw new Error(`Service Request Error: HTTP ${response.status}`);
      }
      return await response.json();
    }

    // 2. Video Upload
    async function uploadVideo(serviceResponse) {
      const uploadUrl = serviceResponse.uploadVideoUrl;
      if (!uploadUrl) throw new Error("Upload URL not provided");

      document.getElementById("uploadStatus").textContent = "Uploading video...";
      const uploadResponse = await fetch(uploadUrl, {
        method: "PUT",
        headers: { "Content-Type": "application/octet-stream" },
        body: selectedVideoFile
      });

      if (!uploadResponse.ok) {
        throw new Error(`Upload failed: HTTP ${uploadResponse.status}`);
      }
      document.getElementById("uploadStatus").textContent = "Upload completed!";
    }

    // 3. Listen to SSE
    function listenToSSE(serviceResponse) {
      const requestId = serviceResponse.requestId;
      if (!requestId) throw new Error("Request ID not provided");

      const sseUrl = `${API_URL}/gateway/sse-request-track/${requestId}`;
      const sseResultsEl = document.getElementById("sseResults");

      if (eventSource) eventSource.close();

      eventSource = new EventSourcePolyfill(sseUrl, { headers: { "x-api-key": API_KEY } });

      eventSource.onopen = () => {
        sseResultsEl.textContent = "SSE connection opened...\n";
      };

      eventSource.onmessage = (event) => {
        const data = JSON.parse(event.data);
        sseResultsEl.textContent += JSON.stringify(data, null, 2) + "\n\n";

        if (data.event === "status" && data.data === "SUCCESS") {
          sseResultsEl.textContent += "\n✅ Final results received.\n";
          eventSource.close();
        }
      };

      eventSource.onerror = () => {
        sseResultsEl.textContent += "\n❌ SSE connection error\n";
        eventSource.close();
      };
    }
  </script>
</body>
</html>

Troubleshooting

This example includes Pulse, Oxygen Saturation, and Blood Pressure.

  •  HTTP 403 (Forbidden)  → check if your API key is valid.

  •  Ppload URL not provided  → the service request did not return an upload URL, check your request body.

  •  SSE connection error  → could be a network issue or invalid API key.

  •  Please fill all Blood Pressure parameters  → blood pressure requires age, sex, height, and weight.

Extra Resources

1. Sample Media File​

To simplify the understanding of our APIs, we provide an MP4 media file as an example. This file serves as a practical resource for developers to test the upload process and integrate with our video upload API.

How to Use

  • Click here to Download the file and use it in your upload requests.

  • Use the appropriate endpoint for media uploads as described in the API documentation.
  • Ensure compliance with the supported format and size specifications.

This example helps validate the correct integration before using real files in production.

2. EventSource Polyfill

EventSource Polyfill (for SSE support in browsers): https://www.npmjs.com/package/event-source-polyfill

bottom of page