# Conventions.

> https://meetkeely.com/developers/conventions · Updated 2026-11-06 · Keely, by Metrica Fit LLC

## JSON and CORS

**JSON**, UTF-8, `Cache-Control: no-store`. CORS is open (`Access-Control-Allow-Origin: *`), so a browser app can call the API directly.

## Dates and times

**Dates** (`2026-09-27`) are the person’s local dates, as the Keely app stores them. **Times** are UTC, ISO 8601 with a `Z`. Nothing is converted on the server, so a night’s `start` and `end` are the instants it ran, and its `date` is the local morning it ended on. Date ranges (`from`, `to`) are inclusive.

## Units

**Units are in field names:** `hrv_ms`, `resting_hr_bpm`, `asleep_minutes`, `skin_temp_deviation_c`.

## Missing is null

A date without a night has `recovery: null`, with the reason in `missing`. A Recovery still calibrating says so in its `status` and `note`. An activity the person added for a time the band has no heart rate for keeps its sport and time, with Load and heart rate `null`, never zero.

## Not allowed is named

When parts of an answer need scopes you don’t have, those keys are left out and listed in `not_allowed`; when the whole answer does, the API answers `403 insufficient_scope`. An empty table never reads as “nothing happened”. [Permissions](https://meetkeely.com/developers/permissions#not-allowed-is-named-never-empty) has the detail.

## as_of and methodology

**Every answer carries `as_of`**, the band’s last sync to the person’s iPhone (`null` before the first), and `methodology`, the page that explains every number: [meetkeely.com/methodology](https://meetkeely.com/methodology). `GET /v1/explain/{topic}` gives the same in words and as a formula, per number.

## Sample data

Answers from Keely’s review account also carry `sample_data: true` and a `sample_note`. Real accounts never do: Keely shows nothing it didn’t measure.

## Versions

The version is in the path, `/v1`, and `GET /v1` answers it as `version`; every webhook body carries it as `api_version`. Within a version, fields and event types may be added (a subscription to all types hears a new one without a change), so read what you need and let the rest pass. What changes, and when, is in [the changelog](https://meetkeely.com/developers/changelog).
