OpenCGM-StateEventSource ↗

API

The same encoder this site runs, over HTTP. No key, no account, nothing to install.

One request

curl -s https://<this-host>/api/v1/analyse \
  -H 'content-type: application/json' \
  -d '{
        "readings": [
          {"t": "2026-08-29T18:00:00Z", "mgdl": 96},
          {"t": "2026-08-29T18:05:00Z", "mgdl": 98},
          {"t": "2026-08-29T18:10:00Z", "mgdl": 103}
        ]
      }'

Send up to 20,000 readings. Timestamps are ISO-8601 or epoch milliseconds; glucose is mgdl or mmol. Without window_start, the 24 hours ending at the last reading are used.

What comes back

The response carries the gridded 288-slot window as the encoder received it, with null for every unobserved slot and the mask alongside it, plus the clinical metrics for the same window, the 128-dimensional embedding, and every probe with its held-out ROC-AUC, the cohort and subject count it was fitted on, and its coverage band. Skipped probes say why they were skipped. Provenance names the checkpoint, epoch, seed, architecture flags and the SHA-256 of the ONNX file that produced the numbers.

Endpoints

POST/api/v1/analyseencode a day, score the probes

Returns window, clinical_metrics, embedding, probes and provenance. Readings are held in memory for the request and are not written to disk or logged.

{
  "window": {
    "start_utc": "2026-08-29T17:53:08.897Z",
    "coverage": 0.9757,
    "values_mg_dl": [96.0, 98.0, null, 103.0, ...],   // null = not recorded
    "mask": [1, 1, 0, 1, ...],
    "circadian_start_index": 214
  },
  "clinical_metrics": {
    "mean_mg_dl": 102.9, "coefficient_of_variation": 0.1154,
    "time_in_range_70_180": 1.0, "glucose_management_indicator_percent": 5.77
  },
  "embedding": { "dim": 128, "vector": [-0.262430, -0.670614, ...] },
  "probes": [
    { "task": "hall:glucotype", "cohort": "hall", "scored": true,
      "predicted_class": 0, "raw_scores": [0.998, 0.002],
      "held_out_roc_auc": 0.8791, "n_subjects_fitted_on": 57 }
  ]
}
GET/api/v1/versionweights, corpus, protocol, licence

Checkpoint runs_5090/rawstats120/ckpt_ep040.pt, epoch 40, seed 17, 435,633 parameters, ONNX SHA-256 b1349deffd15ab62. Also reports the training corpus and the evaluation protocol, so a result can be tied to the run that produced it.

GET/api/v1/headsevery probe and how well it works

Per probe: task, cohort, class balance, held-out ROC-AUC with its standard deviation, subject-level ROC-AUC, number of subjects, folds, and the coverage band it is valid within. Probes below the signal floor are marked has_signal: false. The response also lists the heads withheld from publication and the licence question blocking each.

The scores are not probabilities

raw_scores comes from unregularised logistic heads fitted in 128 dimensions on a few hundred days. They saturate: most inputs return values near 0 or 1, including inputs drawn from the cohort a head was fitted on. Rank with them. Do not report them as confidence. The meaningful number is held_out_roc_auc, which ranges from 0.64 to 0.88.

Licence

Code Apache-2.0. Encoder weights CC-BY-NC-4.0. The probe-head bundle is CC-BY-NC-SA-4.0: eight of its eighteen heads are fitted on CGMacros, whose terms are share-alike (D025). Commercial use of either needs a separate licence. Source and reproduction instructions are on GitHub.

Running it yourself

The API is part of this Next.js application and loads the same encoder.onnx the browser demo does, through onnxruntime-node. To run a private instance: just web. For research use at scale, prefer your own instance: the public one allows 30 requests a minute per IP and four concurrent inferences.