BeaconRequest access

Beacon · API reference · v1

A signal & research API
for sleep.

Beacon implements published, peer-reviewed sleep algorithms, the ones already in use in the sleep research literature. Every value comes back 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": "..."}}. The status code follows the usual conventions. 400 means a bad parameter, 404 an unknown night or signal key, and 503 that 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."
  }
}

Every signal carries a scope

A "night" signal is computed from the recording it is attached to. A "subject" signal is computed across that subject’s consecutive recording days. The Sleep Regularity Index is the subject-scoped one: it compares sleep/wake state at points 24 h apart, so it is returned on every night belonging to the subject with the same value and with detail.days stating how many days it spans. Read it as a property of the subject, never of the displayed night.

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 and sleep efficiency. Each metric also reports 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,
          "scope": "night", "unavailable_reason": null },
        { "key": "sri", "name": "Sleep Regularity Index",
          "available": false, "unit": "0-100", "coverage": 0.35,
          "scope": "subject",
          "unavailable_reason": "SRI compares states 24 h apart and needs at least two consecutive recording days; 1 supplied." }
      ]
    }
  ]
}
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 are omitted by default so the response stays small. Those are the hypnogram and the ORP series, each roughly a thousand entries for a full night. 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,
    "scope": "night",
    "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,
  "scope": "subject",
  "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",
      "scope": "night",
      "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
Scope
nightComputed from the single recording it is returned with.
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`. The re-derived table also widens the reference class from the published wake-only class to W+N1: the open corpus Beacon fits on is too small to populate the sleep end of a wake-only scale, and with wake-only the N2/N3/REM means all collapse to about 0.15 and the paper's stage ordering is lost. Every ORP response states this in `detail.reference_class`.

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
Scope
nightComputed from the single recording it is returned with.
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
Scope
nightComputed from the single recording it is returned with.
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 the detail object.

Unit
alpha (dimensionless)
Input class
Staged hypnogram
Scope
nightComputed from the single recording it is returned with.
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
Scope
subjectComputed across the subject's consecutive recording days. The same value is returned on every night that subject contributed, and it is not a property of any one night.
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
SRI is subject-scoped: it is computed across a subject's consecutive recording days, so the same value is attached to every night belonging to that subject and is not a property of any one night. `detail.days` reports how many days it spans. 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. When they can be computed, they come back with scope: "subject"on each of that subject’s nights. That is one value describing the subject, not five descriptions of five nights.

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, which is expert-scored polysomnography. The dataset and provider are 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.

The re-derivation also changes one parameter, and every ORP response says so in detail.reference_class: the reference class is widened from the published wake-only class to W+N1. The open corpus Beacon fits on does not contain enough wake to populate the sleep end of a wake-only scale. Fit that way, the N2, N3 and REM means all collapse to about 0.15 and the paper’s stage ordering disappears. Widening the class restores the ordering, and it means Beacon’s ORP values are not numerically interchangeable with values from the vendor table.

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.

Demo

These endpoints, on a real scored night

Research

The five papers behind the catalogue