# VitalDB Open Dataset API — guide for agents

Read-only, public, no authentication. Base URL: `https://api.vitaldb.net`.
Machine spec: [`/openapi.json`](https://api.vitaldb.net/openapi.json) ·
Human docs: [`/docs`](https://api.vitaldb.net/docs) ·
Live monitor demo: [`/demo`](https://api.vitaldb.net/demo).

## What this is

6,388 surgical cases from Seoul National University Hospital with
high-resolution intra-operative waveforms (ECG/ART/PLETH/EEG/CO2 at up to
500 Hz) and numeric vitals, plus clinical data. Licensed CC BY 4.0. Use it
for research, ML, and building monitoring software. Cite Lee et al.,
*Sci Data* 2022.

There are three ways to read it. Pick by task.

## 1. FHIR R4 (`/fhir`) — structured, queryable

R4 resources, JSON. Start at [`/fhir/metadata`](https://api.vitaldb.net/fhir/metadata).

- `Location/OR1..OR10` — operating rooms. `GET /fhir/Location?physicalType=ro`
- `Patient/{subjectid}` — 6,090 de-identified patients
- `Encounter/{caseid}` — 6,388 surgeries. `identifier` system
  `https://vitaldb.net/caseid` is shared with the INSPIRE dataset, so you
  can join the two at the case level.
- `Observation` — waveform + numeric tracks and labs of a case:
  - `GET /fhir/Observation?encounter=1&_summary=true` → list a case's tracks
  - `GET /fhir/Observation?encounter=1&code=SNUADC/ECG_II&date=ge2100-01-01T00:01:00Z&date=le2100-01-01T00:03:00Z`
  - Waveforms are `valueSampledData`: physical = `raw * factor + origin`
    (factor=gain, origin=bias). Decoding is lossless at float64.
- `Procedure` / `Condition` / `MedicationAdministration` — INSPIRE-derived
  clinical context (ICD-10-PCS / ICD-10 / ATC) for the ~2,087 cases that
  exist in INSPIRE. `GET /fhir/Procedure?encounter=147`. Enriched
  Encounters carry an `inspire-clinical` meta tag.

Search is per-case: pass `encounter={caseid}` or `patient={subjectid}`.
Paginate with `_count` / `_offset`.

## 2. Virtual real-time replay — a perpetual live monitor

Each OR plays its cases back-to-back forever from epoch 2000-01-01T00:00:00Z
(20-min turnover between cases). Any virtual timestamp resolves to
live-looking data, so you can build a real-time monitor by polling.

- `GET /fhir/Location/OR1/$status` → which case is playing now, elapsed,
  or `state=idle` with seconds to the next patient during turnover.
- `GET /fhir/Location/OR1/$sample?code=SNUADC/ECG_II,SNUADC/PLETH,Solar8000/HR&window=10`
  → SampledData window per track, stamped at virtual time. Omit `code` to
  get the case's monitor-drawable tracks; each carries a `track-display`
  extension (mindisp/maxdisp/color) so a client can render without
  hardcoding scales. `409` during turnover.
- Pass `at=<ISO|unix>` for a specific, reproducible (cacheable) instant;
  omit for live now.

Polling pattern: first request `window=30` to fill the screen, then
`window=10` every 10 s advancing `at`. See `/demo` for a working monitor.

## 3. Raw bulk — files and tables

- `GET /{caseid}.parquet` (1..6388) — analysis format, lossless, zstd.
  With the Python library: `vitaldb.VitalFile('https://api.vitaldb.net/1.parquet')`.
- `GET /{caseid}.vital` — original .vital binary.
- `GET /cases` — clinical info CSV (age, sex, asa, department, opname, …).
- `GET /labs` — lab results CSV (caseid, dt, name, result).

## Notes for agents

- Everything is GET, public, CORS `*`, and cacheable. Identical
  explicit-`at` replay URLs are immutable — cache freely.
- Track names are `Device/Channel` (e.g. `SNUADC/ECG_II`, `Solar8000/HR`,
  `Primus/CO2`, `BIS/BIS`). Get a case's exact list via
  `Observation?encounter={id}&_summary=true`.
- Times in waveform/replay data use the anonymized recording clock
  (origin ~2100-01-01); lab `dt` is seconds relative to case start.
- Prefer the FHIR/replay endpoints for slices and live use; download the
  parquet for whole-case ML.
- Python: `pip install vitaldb` (>=1.7 for parquet).
