Beacon · API reference · v1

A signal & research API
for sleep.

Beacon implements published, peer-reviewed sleep algorithms — the same methods used in the sleep research literature — and returns every value with the citation, DOI and input coverage behind it. Where an input cannot support a published method, the API says so explicitly instead of estimating.

Research and wellness use. Not a medical device; not intended for diagnosis.

Base URL & conventions

Getting a response

All endpoints are rooted at https://beaconsleep.rest/api/v1. Every response is JSON and carries the engine version that produced it, so a result can always be traced back to a specific build of the analysis code. Responses are not cached; GET requests carry permissive CORS headers and can be called from a browser on any origin.

Errors use a single shape across the whole surface — {"error": {"code": "...", "message": "..."}} — with a conventional status code: 400 for a bad parameter, 404 for an unknown night or signal key, 503 when the analysis dataset is not mounted.

Example error
HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": {
    "code": "unknown_signal",
    "message": "Night 'ngt_sc4001e0' has no signal 'rem_latency'. Computed for this night: orp, spindle_density, swa_decay, transition_dynamics, sri. The full catalogue is at /api/v1/signals."
  }
}

Authentication

Bearer tokens

Production access uses a bearer token issued per organisation and passed in the Authorization header. Tokens are scoped to read access on the endpoints below, are rotatable without downtime, and are never accepted as a query parameter — that keeps them out of proxy and browser logs.

The public demo deployment documented here is read-only over a fixed open dataset and is served without a token. No keys are issued from this page; ask us and we will provision one against a real account.

Authenticated request
curl https://beaconsleep.rest/api/v1/nights \
  -H "Authorization: Bearer $BEACON_API_KEY"

Endpoints

Four calls

GET

/api/v1/nights

Lists every analysed night as a summary: identifiers, duration, total sleep time, sleep efficiency, and — for each metric — whether it was computable for that night, with its coverage and, if not, the reason. This is the index you page through before requesting detail.

Request
curl https://beaconsleep.rest/api/v1/nights
Response 200
{
  "engine": "beacon-0.1.0",
  "generated_at": "2026-01-14T09:12:44Z",
  "source": {
    "dataset": "Sleep-EDF Expanded",
    "provider": "PhysioNet",
    "url": "https://physionet.org/content/sleep-edfx/1.0.0/"
  },
  "count": 8,
  "nights": [
    {
      "night_id": "ngt_sc4001e0",
      "subject": 0,
      "night": 1,
      "duration_hours": 8.4,
      "epoch_sec": 30,
      "tst_min": 428.5,
      "sleep_efficiency": 0.85,
      "signals": [
        { "key": "orp", "name": "Odds Ratio Product (sleep depth)",
          "available": true, "unit": "0-2.5", "coverage": 0.98,
          "unavailable_reason": null },
        { "key": "sri", "name": "Sleep Regularity Index",
          "available": false, "unit": "0-100", "coverage": 0.35,
          "unavailable_reason": "Combined recording spans 8.4 h; SRI needs more than 24 h so that each epoch has a same-clock-time counterpart." }
      ]
    }
  ]
}
GET

/api/v1/nights/{nightId}

The full record for one night: sleep architecture and every computed signal with its provenance. The two per-epoch arrays — the hypnogram and the ORP series, each roughly a thousand entries for a full night — are omitted by default so the response stays small. Ask for them with ?include=hypnogram,orp_series. An unrecognised include name returns 400 invalid_parameter; an unknown night id returns 404 not_found.

Request
curl "https://beaconsleep.rest/api/v1/nights/ngt_sc4001e0?include=hypnogram,orp_series"
Response 200
{
  "engine": "beacon-0.1.0",
  "generated_at": "2026-01-14T09:12:44Z",
  "source": { "dataset": "Sleep-EDF Expanded", "provider": "PhysioNet",
              "url": "https://physionet.org/content/sleep-edfx/1.0.0/" },
  "night": {
    "night_id": "ngt_sc4001e0",
    "subject": 0,
    "night": 1,
    "epoch_sec": 30,
    "duration_hours": 8.4,
    "architecture": {
      "tst_min": 428.5,
      "sleep_efficiency": 0.85,
      "waso_min": 47.0,
      "sleep_onset_latency_min": 21.5,
      "stage_minutes": { "W": 75.5, "N1": 32.0, "N2": 231.5,
                         "N3": 74.0, "R": 91.0 }
    },
    "hypnogram": ["W", "W", "N1", "N2", "..."],
    "orp_series": [2.41, 2.38, 1.72, null, "..."],
    "signals": [ /* see the signal endpoint below */ ]
  },
  "included": ["hypnogram", "orp_series"],
  "available_includes": ["hypnogram", "orp_series"]
}
GET

/api/v1/nights/{nightId}/signals/{key}

One signal, with the full provenance record: value, unit, citation, DOI, the fraction of the recording the algorithm actually consumed, and an algorithm-specific detail object (fit statistics, bout counts, detector parameters). An unknown key returns 404 unknown_signal listing the keys that exist for that night.

Request
curl https://beaconsleep.rest/api/v1/nights/ngt_sc4001e0/signals/swa_decay
Response 200
{
  "engine": "beacon-0.1.0",
  "generated_at": "2026-01-14T09:12:44Z",
  "source": { "dataset": "Sleep-EDF Expanded", "provider": "PhysioNet",
              "url": "https://physionet.org/content/sleep-edfx/1.0.0/" },
  "night_id": "ngt_sc4001e0",
  "signal": {
    "key": "swa_decay",
    "name": "Slow-wave activity decay (Process S)",
    "value": -0.184,
    "unit": "log10(uV^2)/hour",
    "citation": "Borbely, Hum Neurobiol 1982;1(3):195-204",
    "doi": "10.1016/0165-0173(82)90015-1",
    "coverage": 0.98,
    "detail": {
      "r_squared": 0.41,
      "p_value": 1.2e-12,
      "nrem_epochs": 611,
      "first_hour_swa_uv2": 284.3
    },
    "unavailable_reason": null,
    "engine": "beacon-0.1.0"
  }
}

A null value is not an error. It means the input did not meet the precondition the published method requires, and unavailable_reason states which one:

Response 200 · value unavailable
{
  "key": "sri",
  "name": "Sleep Regularity Index",
  "value": null,
  "unit": "0-100",
  "citation": "Phillips et al., Sci Rep 2017;7:3216; Windred et al., SLEEP 2024;47(1):zsad253",
  "doi": "10.1038/s41598-017-03171-4",
  "coverage": 0.35,
  "detail": {},
  "unavailable_reason": "SRI compares states 24 h apart and needs at least two consecutive recording days; 1 supplied.",
  "engine": "beacon-0.1.0"
}
GET

/api/v1/signals

The catalogue: every metric the engine implements, with its citation, DOI, unit, the input resolution the published algorithm requires, and the preconditions that must hold for it to be computable. This endpoint describes the engine rather than any particular recording, so it answers even when no dataset is mounted.

Request
curl https://beaconsleep.rest/api/v1/signals
Response 200
{
  "engine": "beacon-0.1.0",
  "count": 5,
  "disclaimer": "Research and wellness use. Not a medical device; not intended for diagnosis.",
  "signals": [
    {
      "key": "spindle_density",
      "name": "Sleep spindle density (N2)",
      "unit": "spindles/min",
      "description": "Spindles detected per minute of N2 sleep using the A7 detector, which was built to emulate human expert spindle scoring.",
      "citation": "Lacourse K, et al. J Neurosci Methods 2019;316:3-11 (A7)",
      "doi": "10.1016/j.jneumeth.2018.08.014",
      "required_input": "Single-channel EEG at >= 100 Hz plus a staged hypnogram",
      "requires": ["At least 5 minutes of N2 sleep — density is unstable below that"],
      "input_class": "raw_eeg",
      "engine": "beacon-0.1.0"
    }
  ]
}

Catalogue

What we compute, and whose paper it comes from

Each metric below is implemented from its originating publication. Beacon does not ship proprietary black-box scores.

Odds Ratio Product (sleep depth)

orp

Continuous measure of sleep depth from EEG spectral deciles: 0 is deepest sleep, 2.5 is fully awake. Reported as the mean across scored sleep, with a per-stage profile.

Unit
0-2.5
Input class
Raw EEG
Required input
Single-channel EEG at >= 100 Hz, analysed in 3 s windows over four bands (0.3-2.3, 2.3-7.0, 7.0-14.0, 14.0-35.0 Hz)
Computable when
  • At least one scored sleep epoch (N1, N2, N3 or R)
Citation
Younes M, et al. SLEEP 2015;38(4):641-654doi:10.5665/sleep.4588
Note
The original decile lookup table is proprietary (Cerebra Health). Beacon re-derives the same construction from the open Sleep-EDF corpus and labels it as such in `detail.table_source`.

Sleep spindle density (N2)

spindle_density

Spindles detected per minute of N2 sleep using the A7 detector, which was built to emulate human expert spindle scoring.

Unit
spindles/min
Input class
Raw EEG
Required input
Single-channel EEG at >= 100 Hz plus a staged hypnogram
Computable when
  • At least 5 minutes of N2 sleep — density is unstable below that
Citation
Lacourse K, et al. J Neurosci Methods 2019;316:3-11 (A7)doi:10.1016/j.jneumeth.2018.08.014

Slow-wave activity decay (Process S)

swa_decay

Decay rate of delta power (0.5-4.5 Hz) across NREM epochs, fitted as log(SWA) ~ a + b*t. A negative slope is the homeostatic dissipation predicted by the two-process model.

Unit
log10(uV^2)/hour
Input class
Raw EEG
Required input
Single-channel EEG at >= 100 Hz plus a staged hypnogram
Computable when
  • At least 20 NREM (N2/N3) epochs for the regression
Citation
Borbely AA. Hum Neurobiol 1982;1(3):195-204doi:10.1016/0165-0173(82)90015-1

Wake-bout power-law exponent

transition_dynamics

Maximum-likelihood exponent of the wake-bout duration distribution. Wake bouts follow a power law (alpha near 1.3 across species) while sleep bouts are exponential; stage-transition entropy rides along in `detail`.

Unit
alpha (dimensionless)
Input class
Staged hypnogram
Required input
Staged hypnogram on a 30 s grid
Computable when
  • At least 8 wake bouts for a power-law fit
Citation
Lo CC, et al. PNAS 2004;101(50):17545-17548doi:10.1073/pnas.0408242101

Sleep Regularity Index

sri

Probability of being in the same sleep/wake state at two times 24 h apart, rescaled so 100 is perfectly regular and 0 is chance.

Unit
0-100
Input class
Multi-day
Required input
Sleep/wake state on a 30 s grid spanning more than 24 h of continuous recording
Computable when
  • At least two consecutive recording days
  • Combined recording longer than 24 h so each epoch has a same-clock-time counterpart
Citation
Phillips AJK, et al. Sci Rep 2017;7:3216; Windred DP, et al. SLEEP 2024;47(1):zsad253doi:10.1038/s41598-017-03171-4
Note
On single-night inputs SRI is returned with `value: null` and an explicit `unavailable_reason`. That is the honest answer, not an error.

Limitations

What this API will not tell you

Some metrics need more than one night

The Sleep Regularity Index compares sleep/wake state at points 24 hours apart. On a single overnight recording it is not defined, and the API returns value: null with the reason rather than a number derived from a shorter window. Regularity metrics need at least two consecutive recording days, and are more stable over a week.

Some metrics need raw EEG

ORP, spindle density and slow-wave activity decay are spectral measures computed from the EEG waveform. They cannot be recovered from a hypnogram alone or from a consumer device that reports only stage labels. Wake-bout dynamics, by contrast, are computed from the staged series and travel further.

Coverage means coverage

Every signal carries a coverage field between 0 and 1: the fraction of the recording the algorithm could actually consume after unscored epochs and stage-specific requirements are excluded. A value at low coverage is a value computed over less of the night, not a value computed over an imputed one. Beacon never interpolates across missing epochs to raise it.

Published methods, open data, honest gaps

The demo dataset is Sleep-EDF Expanded from PhysioNet — expert-scored polysomnography, with the dataset and provider named on every response. Where a published algorithm depends on a component that is not public, we say so in the response rather than papering over it: the ORP decile table is proprietary to its original vendor, so Beacon re-derives the same construction from the open corpus and labels the result in detail.table_source.

Not a diagnostic

Beacon implements algorithms that have been validated in the peer-reviewed literature. That is a statement about methodology, not regulatory status: Beacon has not been cleared or approved as a medical device by any regulator, produces no diagnosis, and must not be used to detect, treat or rule out a sleep disorder. Clinical questions belong with a qualified clinician.

Research and wellness use. Not a medical device; not intended for diagnosis.