
Exemplos de Códigos
Nesta seção, forneceremos exemplos práticos de código para orientar os desenvolvedores em sua integração inicial com nossas APIs, oferecendo implementações claras e concisas para acelerar o processo de integração e simplificar a adoção da API.
Introdução
Bem-vindo à documentação de integração com a API WaveLight.
Nossa documentação fornece um exemplo simples de código em JavaScript (JS), projetado para facilitar a integração com a API WaveLight. Fornecemos implementações detalhadas para atender às diversas necessidades dos desenvolvedores.
Nosso objetivo é simplificar a implementação de APIs em diferentes ambientes, garantindo flexibilidade e compatibilidade. Nosso guia fornece instruções claras e exemplos práticos para uma integração eficiente.
Aqui você aprenderá como:
-
Criar um Service Request (pedido de análise)
-
Fazer o Upload de um vídeo para análise
-
Obter os Resultados em tempo real via SSE (Server-Sent Events)
Visão Geral
O fluxo de integração segue 3 passos principais:
[1] Service Request ---> retorna requestId + uploadUrl
|
v
[2] Upload do Vídeo ---> envia o vídeo para uploadUrl
|
v
[3] SSE Results -----> conecta usando requestId e recebe os resultados em tempo real
1. Service Request Response
A Solicitação de Serviço é o ponto de partida.
Aqui você informa à API quais serviços deseja executar:
-
Pulso → wc_pr-avg_sk_beta
-
Saturação de oxigênio → wc_o2-avg_sk_beta
-
Pressão Arterial → wc_bp-neural_sk_beta
Notas importantes:
-
Se você solicitar aferição de pressão arterial, deverá fornecer dados do paciente (idade, sexo, altura, peso).
-
Para outros serviços, esses valores podem ser omitidos.
Exemplo de Requisição
POST https://api.wavelighthealth.com/gateway/service-request
Headers:
Content-Type: application/json
x-api-key: SUA_CHAVE_API
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" }
]
}
}
}
Exemplo de Resposta
{
"requestId": "12345-abcde",
"uploadVideoUrl": "https://upload-url-gerada-pela-api.com/xyz",
"status": "PENDING"
}
2. Video Upload Status
Após o Service Request, você deve enviar o vídeo para a URL retornada (uploadVideoUrl).
Exemplo de Upload (JavaScript)
await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "application/octet-stream" },
body: selectedVideoFile
});
Resposta Esperada
{
"status": 200,
"statusText": "OK",
"videoSize": "12.5 MB",
"uploadUrl": "https://upload-url-gerada-pela-api.com/xyz",
"timestamp": "2025-09-16T14:00:00.000Z"
}
3. Real-time Results (SSE)
A API envia os resultados em tempo real via SSE (Server-Sent Events).
Como funciona:
-
Você conecta ao endpoint: /gateway/sse-request-track/{requestId}
-
A API envia eventos até o processamento ser concluído.
Tipos de Eventos
-
PARTIAL_PROGRESS → resultados parciais
-
SUCCESS → resultados finais
Exemplo de Resultado Final
{
"event": "status",
"data": "SUCCESS",
"results": [
{ "name": "HEART BEATS", "return": "[{\"label\": \"PR-AVG\", \"value\": [72]}]" },
{ "name": "OXIMETRY", "return": "[{\"label\": \"Oximetry\", \"value\": [98]}]" }
]
}
Exemplo Completo (Dados Fixos)
Este exemplo inclui Pulso, Saturação e Pressão Arterial.
Usamos dados fictícios de paciente fixos no código apenas para demonstração:
-
Idade = 45
-
Sexo = Masculino
-
Altura = 172 cm
-
Peso = 85 kg
Atenção: Em produção, esses valores devem ser coletados do usuário real ou de um prontuário eletrônico.
<!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>
<!-- Botões de controle -->
<input type="file" id="videoInput" accept="video/*" style="display: none;" />
<button onclick="document.getElementById('videoInput').click()">Selecionar Vídeo</button>
<button id="startButton" onclick="runFullProcess()">Iniciar</button>
<!-- Áreas de resultado -->
<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>
// Configuração da API
const API_URL = "https://api.wavelighthealth.com";
const API_KEY = "SUA_CHAVE_API_AQUI="; // substitua pela sua chave real
let eventSource = null;
let selectedVideoFile = null;
// Seleção de arquivo
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 =
`Vídeo selecionado: ${selectedVideoFile.name} (${sizeInMB} MB)`;
}
});
// Função principal: roda o processo completo
async function runFullProcess() {
if (!selectedVideoFile) {
alert("Selecione um vídeo antes de iniciar!");
return;
}
const button = document.getElementById("startButton");
button.disabled = true;
// Limpa resultados anteriores
document.getElementById("serviceResponse").textContent = "Processando...";
document.getElementById("uploadStatus").textContent = "Aguardando upload...";
document.getElementById("sseResults").textContent = "Aguardando resultados...";
try {
// 1. Criar Service Request
const serviceResponse = await makeServiceRequest();
document.getElementById("serviceResponse").textContent =
JSON.stringify(serviceResponse, null, 2);
// 2. Fazer upload do vídeo
await uploadVideo(serviceResponse);
// 3. Escutar resultados em tempo real (SSE)
listenToSSE(serviceResponse);
} catch (error) {
console.error("Erro no processo:", error);
document.getElementById("uploadStatus").textContent = `Erro: ${error.message}`;
button.disabled = false;
}
}
// === 1. Service Request ===
async function makeServiceRequest() {
const createdDate = new Date().toISOString();
const requestBody = {
serviceList: [
"wc_pr-avg_sk_beta", // Pulso
"wc_o2-avg_sk_beta", // Saturação
"wc_bp-neural_sk_beta" // Pressão Arterial
],
WPG_Object: {
header: { "content-type": "", version: "", hash: "", secure: true },
study: {
created: createdDate,
source: {
device: { model: navigator.userAgent, features: [] },
institution: "Wavelight",
application: "WaveLight API Demo"
}
},
// ⚠️ IMPORTANTE:
// Neste exemplo os dados do paciente estão FIXOS para demonstração.
// Em uma aplicação real, esses valores devem vir de um formulário
// ou integração com prontuário eletrônico.
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(`Erro Service Request: HTTP ${response.status}`);
}
return await response.json();
}
// === 2. Upload do Vídeo ===
async function uploadVideo(serviceResponse) {
const uploadUrl = serviceResponse.uploadVideoUrl;
if (!uploadUrl) throw new Error("Upload URL não fornecida");
const videoSize = (selectedVideoFile.size / 1024 / 1024).toFixed(2);
document.getElementById("uploadStatus").textContent =
`Enviando vídeo (${videoSize} MB)...`;
const uploadResponse = await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "application/octet-stream" },
body: selectedVideoFile
});
if (!uploadResponse.ok) {
throw new Error(`Falha no upload: HTTP ${uploadResponse.status}`);
}
document.getElementById("uploadStatus").textContent =
`Upload concluído (${videoSize} MB)`;
}
// === 3. Escutar SSE ===
function listenToSSE(serviceResponse) {
const requestId = serviceResponse.requestId;
if (!requestId) throw new Error("Request ID não fornecido");
const sseUrl = `${API_URL}/gateway/sse-request-track/${requestId}`;
const sseResultsEl = document.getElementById("sseResults");
if (eventSource) eventSource.close(); // fecha conexão antiga
eventSource = new EventSourcePolyfill(sseUrl, {
headers: { "x-api-key": API_KEY }
});
eventSource.onopen = () => {
sseResultsEl.textContent = "Conexão SSE estabelecida...\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✅ Resultados finais recebidos.\n";
eventSource.close();
document.getElementById("startButton").disabled = false;
}
};
eventSource.onerror = (err) => {
sseResultsEl.textContent += "\n❌ Erro na conexão SSE\n";
console.error("SSE error:", err);
eventSource.close();
document.getElementById("startButton").disabled = false;
};
}
// Fecha SSE quando a página for fechada
window.addEventListener("beforeunload", () => {
if (eventSource) eventSource.close();
});
</script>
</body>
</html>
Exemplo Alternativo (Com Formulário)
Neste exemplo, os dados do paciente são coletados por um formulário simples em HTML.
Se o dev selecionar pressão arterial, o formulário aparece e exige os valores para idade, sexo, peso e altura.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>WaveLight API - Exemplo com Formulário</title>
<script src="https://unpkg.com/event-source-polyfill@1.0.31/src/eventsource.min.js"></script>
</head>
<body>
<h1>WaveLight API Demo (com formulário)</h1>
<!-- Seleção de serviços -->
<h3>Selecione os serviços</h3>
<label><input type="checkbox" class="serviceOption" value="wc_pr-avg_sk_beta"> Pulso</label><br>
<label><input type="checkbox" class="serviceOption" value="wc_o2-avg_sk_beta"> Saturação</label><br>
<label><input type="checkbox" id="bpCheckbox" class="serviceOption" value="wc_bp-neural_sk_beta"> Pressão Arterial</label>
<!-- Formulário do paciente (aparece apenas se pressão for selecionada) -->
<div id="bpForm" style="display:none; margin-top:10px;">
<label>Idade: <input type="number" id="age"></label><br>
<label>Sexo:
<select id="sex">
<option value="MALE">Masculino</option>
<option value="FEMALE">Feminino</option>
</select>
</label><br>
<label>Altura (cm): <input type="number" id="height"></label><br>
<label>Peso (kg): <input type="number" id="weight"></label>
</div>
<!-- Controles -->
<br>
<input type="file" id="videoInput" accept="video/*" style="display: none;" />
<button onclick="document.getElementById('videoInput').click()">Selecionar Vídeo</button>
<button id="startButton" onclick="runFullProcess()">Iniciar</button>
<!-- Resultados -->
<h3>Service Request Response</h3>
<pre id="serviceResponse">Waiting...</pre>
<h3>Upload Status</h3>
<pre id="uploadStatus">Waiting...</pre>
<h3>Resultados em Tempo Real (SSE)</h3>
<pre id="sseResults">Waiting...</pre>
<script>
const API_URL = "https://api.wavelighthealth.com";
const API_KEY = "SUA_CHAVE_API_AQUI"; // insira sua chave real
let eventSource = null;
let selectedVideoFile = null;
// Mostra/esconde o formulário de paciente se Pressão for marcada
document.getElementById("bpCheckbox").addEventListener("change", function() {
document.getElementById("bpForm").style.display = this.checked ? "block" : "none";
});
// Seleção de arquivo
document.getElementById("videoInput").addEventListener("change", (e) => {
selectedVideoFile = e.target.files[0];
if (selectedVideoFile) {
document.getElementById("uploadStatus").textContent =
`Vídeo selecionado: ${selectedVideoFile.name}`;
}
});
// Fluxo principal
async function runFullProcess() {
if (!selectedVideoFile) {
alert("Selecione um vídeo antes de iniciar!");
return;
}
document.getElementById("serviceResponse").textContent = "Processando...";
document.getElementById("uploadStatus").textContent = "Aguardando upload...";
document.getElementById("sseResults").textContent = "Aguardando resultados...";
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 = `Erro: ${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("Selecione ao menos um serviço.");
}
// Prepara dados do paciente
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("Preencha todos os dados do paciente para pressão arterial.");
}
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(`Erro Service Request: HTTP ${response.status}`);
}
return await response.json();
}
// 2. Upload do Vídeo
async function uploadVideo(serviceResponse) {
const uploadUrl = serviceResponse.uploadVideoUrl;
if (!uploadUrl) throw new Error("Upload URL não fornecida");
document.getElementById("uploadStatus").textContent = "Enviando vídeo...";
const uploadResponse = await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "application/octet-stream" },
body: selectedVideoFile
});
if (!uploadResponse.ok) {
throw new Error(`Falha no upload: HTTP ${uploadResponse.status}`);
}
document.getElementById("uploadStatus").textContent = "Upload concluído!";
}
// 3. Escutar SSE
function listenToSSE(serviceResponse) {
const requestId = serviceResponse.requestId;
if (!requestId) throw new Error("Request ID não fornecido");
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 = "Conexão SSE aberta...\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✅ Resultados finais recebidos.\n";
eventSource.close();
}
};
eventSource.onerror = () => {
sseResultsEl.textContent += "\n❌ Erro SSE\n";
eventSource.close();
};
}
</script>
</body>
</html>
Solução de Problemas
-
HTTP 403 (Forbidden) → verifique se a chave API está correta.
-
Upload URL not provided → o service request não retornou a URL, verifique a requisição inicial.
-
SSE connection error → pode ser problema de rede ou chave inválida.
-
Please fill all Blood Pressure parameters → pressione arterial exige idade, sexo, altura e peso.
Recursos Extras
1. Arquivo de Mídia de Exemplo
Para simplificar o entendimento de nossas APIs, fornecemos um arquivo de mídia MP4 como exemplo. Este arquivo serve como um recurso prático para que os desenvolvedores testem o processo de upload e integrem com nossa API de upload de vídeos.
Como usar
-
Clique aqui para fazer o download do arquivo e utilizá-lo em suas requisições de upload.
- Utilize o endpoint apropriado para uploads de mídia conforme descrito na documentação da API..
-
Certifique-se de estar em conformidade com o formato e as especificações de tamanho suportados.
Este exemplo ajuda a validar a integração correta antes de utilizar arquivos reais em produção.
2. EventSource Polyfill
EventSource Polyfill (para suporte a SSE nos navegadores): https://www.npmjs.com/package/event-source-polyfill