Skip to main content

API Reference

All endpoints are available through the NeuroFusion backend at https://usefusion.ai/api/eeg-models/ or directly on the GPU server at https://models.usefusion.ai/.

Health Check

Check GPU availability before sending inference requests.
GET /api/eeg-models/health
Response (GPU running):
{
  "status": "ok",
  "model": "zuna",
  "zuna_available": true,
  "gpu_name": "NVIDIA A100 80GB PCIe"
}
Response (VM deallocated):
{
  "status": "unavailable",
  "vm": { "status": "deallocated" },
  "message": "GPU VM is not running"
}

Wake GPU VM

Start the GPU VM if it’s deallocated. The VM takes ~90 seconds to boot.
POST /api/eeg-models/wake
Response:
{
  "status": "starting",
  "message": "GPU VM is starting up",
  "estimatedWaitSeconds": 90
}

VM Status

GET /api/eeg-models/vm-status
Response:
{
  "status": "running",
  "vmStatus": "running"
}
Possible vmStatus values: running, deallocated, starting, stopping, deallocating

Run ZUNA Inference

If the GPU VM is deallocated, this returns HTTP 202 with a retry instruction. Check health first or handle the 202 response.
POST /api/eeg-models/inference

Request Body

{
  "task": "denoise",
  "eeg": {
    "csv_content": "timestamp,CP3,C3,F5,...\n1700000000,12.5,-3.2,8.1,...\n...",
    "device_type": "neurosity",
    "sfreq": 256
  },
  "output_format": "json"
}
FieldTypeRequiredDescription
taskstring"denoise", "reconstruct", or "upsample"
eeg.csv_contentstringRaw CSV data with channel columns (values in µV)
eeg.device_typestring"neurosity", "muse", or "auto"
eeg.sfreqnumberSampling frequency in Hz (default: 256)
eeg.channel_namesstring[]Override auto-detected channel names
output_formatstring"json" (default) or "csv"
target_channelsstring[]For upsample task: target channel names
bad_channelsstring[]Channels to exclude from processing
gpu_devicenumberGPU device index (default: 0)

Response (JSON format)

{
  "task": "denoise",
  "model": "zuna",
  "input": {
    "channel_names": ["CP3", "C3", "F5", "PO3", "PO4", "F6", "C4", "CP4"],
    "n_channels": 8,
    "sfreq": 256.0,
    "duration_seconds": 5.996,
    "n_samples": 1536
  },
  "output": {
    "channel_names": ["CP3", "C3", "F5", "PO3", "PO4", "F6", "C4", "CP4"],
    "n_channels": 8,
    "sfreq": 256.0,
    "duration_seconds": 4.996,
    "n_samples": 1280,
    "format": "json"
  },
  "channel_data": {
    "CP3": [1.23, -0.45, 2.67, ...],
    "C3": [0.89, 1.34, -0.78, ...],
    ...
  }
}

Response (CSV format)

{
  "task": "denoise",
  "model": "zuna",
  "input": { ... },
  "output": {
    ...
    "format": "csv",
    "csv_content": "timestamp_s,CP3,C3,F5,...\n0.0,1.23,0.89,...\n..."
  }
}

Response (HTTP 202 — GPU warming up)

{
  "status": "warming_up",
  "vmAction": "starting",
  "message": "GPU VM is starting up. Please retry in ~90 seconds.",
  "estimatedWaitSeconds": 90,
  "retryAfter": 15
}

CSV Input Format

Your CSV should have columns for each EEG channel. An optional timestamp column is supported but not required.

Neurosity Crown

timestamp,CP3,C3,F5,PO3,PO4,F6,C4,CP4
1700000000.000,12.5,-3.2,8.1,5.6,-7.3,2.1,9.4,-1.8
1700000000.004,13.1,-2.8,7.9,5.2,-6.9,2.5,9.1,-2.1
...

Muse

timestamp,TP9,AF7,AF8,TP10
1700000000.000,15.2,-4.1,6.3,-8.7
1700000000.004,14.8,-3.9,6.1,-8.2
...
Important: Values should be in microvolts (µV). The API automatically converts to volts for MNE processing and back to µV for the output.

Error Responses

StatusMeaning
400Invalid request (missing fields, bad task, insufficient duration)
404Dataset not found (for analyze-dataset endpoint)
500Model inference failed
502GPU server unreachable
503EEG Models API not configured

Code Examples

JavaScript/TypeScript

import { api } from "~/config/api";

const response = await api.post("/eeg-models/inference", {
  task: "denoise",
  eeg: {
    csv_content: csvString,
    device_type: "neurosity",
    sfreq: 256,
  },
  output_format: "json",
});

const { channel_data, output } = response.data;
console.log(`Denoised ${output.n_channels} channels, ${output.n_samples} samples`);

Python

import requests

response = requests.post("https://models.usefusion.ai/inference/zuna", json={
    "task": "denoise",
    "eeg": {
        "csv_content": open("recording.csv").read(),
        "device_type": "muse",
        "sfreq": 256,
    },
    "output_format": "json",
})

result = response.json()
print(f"Channels: {result['output']['channel_names']}")
print(f"Samples: {result['output']['n_samples']}")

cURL

curl -X POST https://models.usefusion.ai/inference/zuna \
  -H "Content-Type: application/json" \
  -d '{
    "task": "denoise",
    "eeg": {
      "csv_content": "timestamp,TP9,AF7,AF8,TP10\n...",
      "device_type": "muse",
      "sfreq": 256
    },
    "output_format": "json"
  }'