{
  "openapi": "3.1.0",
  "info": {
    "title": "VitalDB Open Dataset API",
    "version": "2.0.0",
    "summary": "FHIR R4 + virtual real-time replay over the VitalDB open dataset.",
    "description": "Read-only API for the VitalDB open dataset (6,388 surgical cases, high-resolution intra-operative waveforms and numerics from Seoul National University Hospital).\n\nThree surfaces:\n- **FHIR R4** under `/fhir` — Location (10 ORs), Patient, Encounter, Observation, plus INSPIRE-derived Procedure / Condition / MedicationAdministration for linked cases.\n- **Virtual real-time replay** — `/fhir/Location/OR{n}/$status` and `/$sample` play every case back-to-back forever from epoch 2000-01-01Z, so any timestamp resolves to live-looking data. Powers the monitor demo at `/demo`.\n- **Raw bulk** — `/{caseid}.parquet` and `/{caseid}.vital` per case, plus `/cases` and `/labs` clinical tables.\n\nResponses are FHIR JSON (served as `application/json` so they gzip/brotli over the CDN). All endpoints are public and cacheable; explicit-time replay responses are immutable.",
    "license": { "name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/" },
    "contact": { "name": "VitalDB", "url": "https://vitaldb.net" }
  },
  "servers": [{ "url": "https://api.vitaldb.net", "description": "Production CDN" }],
  "tags": [
    { "name": "FHIR", "description": "FHIR R4 resources" },
    { "name": "Replay", "description": "Virtual real-time monitor replay" },
    { "name": "Clinical", "description": "INSPIRE-derived clinical resources (linked cases)" },
    { "name": "Bulk", "description": "Per-case files and clinical tables" }
  ],
  "paths": {
    "/fhir/metadata": {
      "get": {
        "tags": ["FHIR"],
        "summary": "CapabilityStatement",
        "description": "FHIR conformance statement listing supported resources and search params.",
        "responses": { "200": { "description": "CapabilityStatement", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Location": {
      "get": {
        "tags": ["FHIR"],
        "summary": "List operating rooms",
        "parameters": [
          { "name": "physicalType", "in": "query", "schema": { "type": "string", "enum": ["wa", "ro"] }, "description": "wa = OR suite, ro = room" }
        ],
        "responses": { "200": { "description": "Bundle of Location (OR1..OR10)", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Location/{id}": {
      "get": {
        "tags": ["FHIR"],
        "summary": "Read a room",
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "OR1" }],
        "responses": { "200": { "description": "Location", "content": { "application/json": {} } }, "404": { "description": "Unknown room" } }
      }
    },
    "/fhir/Location/{id}/$status": {
      "get": {
        "tags": ["Replay"],
        "summary": "Current replay state of a room",
        "description": "Resolves the virtual wall-clock time `at` (or server now) to the case playing in this room. Returns a Parameters resource: state=active (caseid, encounter, caseElapsedSec, caseDurationSec) or state=idle (nextCaseid, secondsToNext during the 20-min turnover).",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "OR1" },
          { "name": "at", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Virtual time (ISO 8601 or unix seconds). Omit for live now.", "example": "2026-06-11T09:00:00Z" }
        ],
        "responses": { "200": { "description": "Parameters", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Location/{id}/$sample": {
      "get": {
        "tags": ["Replay"],
        "summary": "Waveform/numeric window of the room's current case",
        "description": "Returns SampledData windows for the requested tracks of the case playing in this room at virtual time `at`. One track → a single Observation; multiple (or default montype set) → a Bundle. Each Observation is stamped at virtual time and carries `replay-source` (caseid, realOffsetSec) and `track-display` (mindisp/maxdisp/color/srate) extensions. 409 during turnover (room idle).\n\nPoll pattern for a live monitor: first call window=30, then window=10 advancing `at` by 10s.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "OR1" },
          { "name": "code", "in": "query", "schema": { "type": "string" }, "description": "Comma-separated track dtnames. Omit for the case's monitor-drawable (montype) tracks.", "example": "SNUADC/ECG_II,SNUADC/PLETH,Solar8000/HR" },
          { "name": "at", "in": "query", "schema": { "type": "string", "format": "date-time" }, "description": "Virtual time. Omit for live now." },
          { "name": "window", "in": "query", "schema": { "type": "integer", "default": 10, "minimum": 1, "maximum": 600 }, "description": "Window length in seconds." }
        ],
        "responses": {
          "200": { "description": "Observation or Bundle with valueSampledData", "content": { "application/json": {} } },
          "409": { "description": "Room idle (turnover); body OperationOutcome with next case + seconds" }
        }
      }
    },
    "/fhir/Patient": {
      "get": {
        "tags": ["FHIR"],
        "summary": "Search de-identified patients",
        "description": "6,090 patients (cases table subjectid). 237 had multiple surgeries.",
        "parameters": [
          { "name": "gender", "in": "query", "schema": { "type": "string", "enum": ["male", "female"] } },
          { "name": "_count", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 200 } },
          { "name": "_offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Bundle of Patient", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Patient/{id}": {
      "get": { "tags": ["FHIR"], "summary": "Read a patient", "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "5955" }], "responses": { "200": { "description": "Patient", "content": { "application/json": {} } } } }
    },
    "/fhir/Encounter": {
      "get": {
        "tags": ["FHIR"],
        "summary": "Search surgeries (cases)",
        "description": "6,388 encounters = surgical cases. identifier system https://vitaldb.net/caseid (shared with the INSPIRE dataset). Enriched cases carry an inspire-clinical meta tag.",
        "parameters": [
          { "name": "patient", "in": "query", "schema": { "type": "string" }, "description": "Patient reference, e.g. Patient/5955 or 5955" },
          { "name": "location", "in": "query", "schema": { "type": "string" }, "description": "Room, e.g. OR1" },
          { "name": "_count", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 200 } },
          { "name": "_offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Bundle of Encounter", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Encounter/{id}": {
      "get": { "tags": ["FHIR"], "summary": "Read a surgery", "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "1" }], "responses": { "200": { "description": "Encounter", "content": { "application/json": {} } } } }
    },
    "/fhir/Observation": {
      "get": {
        "tags": ["FHIR"],
        "summary": "Search observations of a case",
        "description": "Waveform (60s SampledData chunks) and numeric tracks plus labs. Waveform values are raw ADC ints with SampledData factor=gain, origin=bias (physical = raw*factor+origin, lossless float64). Use `_summary=true` for a track listing.",
        "parameters": [
          { "name": "encounter", "in": "query", "schema": { "type": "string" }, "description": "Encounter reference, e.g. Encounter/1 or 1", "example": "1" },
          { "name": "patient", "in": "query", "schema": { "type": "string" } },
          { "name": "code", "in": "query", "schema": { "type": "string" }, "description": "Track dtname or lab/{name}", "example": "SNUADC/ECG_II" },
          { "name": "category", "in": "query", "schema": { "type": "string", "enum": ["vital-signs", "laboratory"] } },
          { "name": "date", "in": "query", "schema": { "type": "string" }, "description": "ge/le prefixed time, ISO or unix", "example": "ge2100-01-01T00:01:00Z" },
          { "name": "_summary", "in": "query", "schema": { "type": "string", "enum": ["true"] }, "description": "Track listing only (no sample data)" },
          { "name": "_count", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 200 } },
          { "name": "_offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Bundle of Observation", "content": { "application/json": {} } } }
      }
    },
    "/fhir/Observation/{id}": {
      "get": { "tags": ["FHIR"], "summary": "Read an observation", "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "example": "1-42-c1" }], "responses": { "200": { "description": "Observation", "content": { "application/json": {} } } } }
    },
    "/fhir/Procedure": {
      "get": { "tags": ["Clinical"], "summary": "INSPIRE procedures of a case (ICD-10-PCS)", "description": "Available for ~2,087 cases linked to the INSPIRE dataset.", "parameters": [{ "name": "encounter", "in": "query", "schema": { "type": "string" }, "example": "147" }, { "name": "patient", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "description": "Bundle of Procedure", "content": { "application/json": {} } } } }
    },
    "/fhir/Condition": {
      "get": { "tags": ["Clinical"], "summary": "INSPIRE diagnoses of a case (ICD-10)", "parameters": [{ "name": "encounter", "in": "query", "schema": { "type": "string" }, "example": "147" }, { "name": "patient", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "description": "Bundle of Condition", "content": { "application/json": {} } } } }
    },
    "/fhir/MedicationAdministration": {
      "get": { "tags": ["Clinical"], "summary": "INSPIRE perioperative drugs of a case (ATC)", "parameters": [{ "name": "encounter", "in": "query", "schema": { "type": "string" }, "example": "147" }, { "name": "patient", "in": "query", "schema": { "type": "string" } }], "responses": { "200": { "description": "Bundle of MedicationAdministration", "content": { "application/json": {} } } } }
    },
    "/{caseid}.parquet": {
      "get": {
        "tags": ["Bulk"],
        "summary": "Per-case parquet (analysis format)",
        "description": "Long-format polymorphic schema, zstd-compressed, lossless. Readable with vitaldb>=1.7 (`VitalFile('https://api.vitaldb.net/1.parquet')`).",
        "parameters": [{ "name": "caseid", "in": "path", "required": true, "schema": { "type": "integer", "minimum": 1, "maximum": 6388 } }],
        "responses": { "200": { "description": "parquet file", "content": { "application/vnd.apache.parquet": {} } } }
      }
    },
    "/{caseid}.vital": {
      "get": {
        "tags": ["Bulk"],
        "summary": "Per-case .vital file",
        "parameters": [{ "name": "caseid", "in": "path", "required": true, "schema": { "type": "integer", "minimum": 1, "maximum": 6388 } }],
        "responses": { "200": { "description": ".vital binary", "content": { "application/octet-stream": {} } } }
      }
    },
    "/cases": {
      "get": { "tags": ["Bulk"], "summary": "Clinical information table (CSV)", "description": "One row per case: age, sex, height, weight, bmi, asa, department, opname, diagnosis, times, outcomes.", "responses": { "200": { "description": "CSV", "content": { "text/csv": {} } } } }
    },
    "/labs": {
      "get": { "tags": ["Bulk"], "summary": "Laboratory results table (CSV)", "description": "Long format: caseid, dt (case-relative seconds), name, result.", "responses": { "200": { "description": "CSV", "content": { "text/csv": {} } } } }
    }
  }
}
