Field notes · 15 Aug 2026 · spec
Verifying a OneDrum certified score
Every finished run has a canonical URL that returns the score as signed JSON. This note documents the payload, what the signature covers, and the two ways to check a score without trusting the device — or the person — that handed it to you.
The endpoint
GET https://onedrum.io/api/session/<sessionId>/participant/<participantId>/certified
This is the link printed on every player's end card. It answers with
application/json to browsers and programs alike (CORS is open), and the
response looks like this:
{
"participantId": "…",
"sessionId": "…",
"clipId": "chant-a",
"certified": 17,
"total": 18,
"certRate": 0.9444,
"calibrated": true,
"windowMs": 120,
"trusted": true,
"flags": [],
"issuedAt": "2026-08-15T09:41:00.000Z",
"signature": "…"
}
What the fields mean
| field | meaning |
|---|---|
certified / total | Answers accepted as in-sync, out of the scored cues in the clip. The single number the score card shows. |
certRate | certified / total, rounded to 4 decimal places. |
windowMs | The acceptance half-window in force for this run: a tap is accepted when its post-calibration offset from the nearest scored cue is within ±this many milliseconds. Currently 120 (why). |
calibrated | Whether the player's device latency was calibrated (from the warm-up bar, or adaptively during play). |
trusted / flags | The plausibility verdict. A run whose timing is tighter than human jitter allows is reported with trusted: false and "too_perfect" in flags — reported, not hidden: the operator gets the verdict, not just the number. |
issuedAt | When this payload was issued (ISO 8601). Signatures cover the issue time, so re-fetching yields a fresh payload and a fresh signature. |
signature | Integrity seal over every other field — construction below. |
Trust path 1 — fetch the canonical URL (anyone)
The simplest verification needs no cryptography: get the score from the
server yourself. If someone hands you a screenshot or a number, fetch their
certified URL over TLS and compare. The score was computed server-side from the raw
tap log — nothing the player's device claims is trusted in the first place — so a
TLS-authenticated response from onedrum.io is the record.
curl https://onedrum.io/api/session/SESSION/participant/PARTICIPANT/certified
Trust path 2 — check the signature (key-holding operators)
For offline verification — scores relayed through third parties, stored, or audited later — the payload carries a detached signature:
signature = base64url( HMAC-SHA256( key, canonical(payload) ) )
where canonical(payload) is the JSON serialization of every field
except signature, with keys in sorted (code-point) order,
no whitespace, numbers and strings exactly as JSON.stringify emits them; and base64url
is unpadded. In Node:
import { createHmac } from 'node:crypto';
function verify(score, key) {
const { signature, ...payload } = score;
const canonical = JSON.stringify(payload, Object.keys(payload).sort());
const expected = createHmac('sha256', key).update(canonical)
.digest('base64url');
return expected === signature;
}
In v0 the signing key is a single server-held secret, so signature verification is available to operators we share a key with, while the canonical-URL path serves everyone else. That is a deliberate v0 simplification: per-operator keys and public-key (asymmetric) signatures — where anyone can verify offline without any shared secret — are the planned production path.
What a valid signature does — and does not — claim
A verified payload proves the score was issued by the OneDrum server and has not
been altered since. It does not by itself prove when the run happened
(see issuedAt), and it is not a warranty of fitness for any purpose — see
the terms. The scoring rules themselves (the audible clock,
warm-up calibration, the ±120ms window, the plausibility gate) are described in the
field notes and are subject to tuning as
production data accumulates; windowMs in the payload records which rule
was in force for a given run.
Questions from operators are welcome — the certified-score API is the part of OneDrum built for you. · More field notes · Terms