> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usefusion.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Endpoint reference for the ZUNA EEG model inference API

# 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

<Tip>Check GPU availability before sending inference requests.</Tip>

```
GET /api/eeg-models/health
```

**Response (GPU running):**

```json theme={null}
{
  "status": "ok",
  "model": "zuna",
  "zuna_available": true,
  "gpu_name": "NVIDIA A100 80GB PCIe"
}
```

**Response (VM deallocated):**

```json theme={null}
{
  "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:**

```json theme={null}
{
  "status": "starting",
  "message": "GPU VM is starting up",
  "estimatedWaitSeconds": 90
}
```

## VM Status

```
GET /api/eeg-models/vm-status
```

**Response:**

```json theme={null}
{
  "status": "running",
  "vmStatus": "running"
}
```

Possible `vmStatus` values: `running`, `deallocated`, `starting`, `stopping`, `deallocating`

## Run ZUNA Inference

<Warning>If the GPU VM is deallocated, this returns HTTP 202 with a retry instruction. Check health first or handle the 202 response.</Warning>

```
POST /api/eeg-models/inference
```

### Request Body

```json theme={null}
{
  "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"
}
```

| Field               | Type      | Required | Description                                      |
| ------------------- | --------- | -------- | ------------------------------------------------ |
| `task`              | string    | ✅        | `"denoise"`, `"reconstruct"`, or `"upsample"`    |
| `eeg.csv_content`   | string    | ✅        | Raw CSV data with channel columns (values in µV) |
| `eeg.device_type`   | string    | ✅        | `"neurosity"`, `"muse"`, or `"auto"`             |
| `eeg.sfreq`         | number    |          | Sampling frequency in Hz (default: 256)          |
| `eeg.channel_names` | string\[] |          | Override auto-detected channel names             |
| `output_format`     | string    |          | `"json"` (default) or `"csv"`                    |
| `target_channels`   | string\[] |          | For `upsample` task: target channel names        |
| `bad_channels`      | string\[] |          | Channels to exclude from processing              |
| `gpu_device`        | number    |          | GPU device index (default: 0)                    |

### Response (JSON format)

```json theme={null}
{
  "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)

```json theme={null}
{
  "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)

```json theme={null}
{
  "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

```csv theme={null}
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

```csv theme={null}
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
...
```

<Note>
  **Important**: Values should be in **microvolts (µV)**. The API automatically converts to volts for MNE processing and back to µV for the output.
</Note>

## Error Responses

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

## Code Examples

### JavaScript/TypeScript

```typescript theme={null}
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

```python theme={null}
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

```bash theme={null}
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"
  }'
```
