freddy Personal API
Read-only access to your own health data. Authenticate with a personal API key (Authorization: Bearer fk_live_...). Your plan's history window applies.
Authentication
Send your personal API key as a bearer token: Authorization: Bearer fk_live_.... Generate keys from your dashboard under AI apps → API keys. Keys are read-only and bounded by your plan's history window.
Base URL
https://freddy.coach
Endpoints
GET /api/v1/metrics
List your normalized health metrics
Returns your metrics newest-first, bounded by your plan's history window. Paginate with the opaque cursor from next_cursor. Each row has a `source` label that names the device or app it came from. If you show or pass on Garmin data, keep that label with it. Each row also carries `device` (the stored source device), `deviceLabel` (its display name) and `sourceId` (the provider's record id). A device-push daily metric (Apple Health, Health Connect) can return several rows per day, one per source app; do not add them together. For Apple Health cumulative metrics use the `<metric>_total` twin, the Health app's de-duplicated daily total. With include_raw=true each row also carries `raw` and `rawStatus`. One provider record is often several rows: join them on (`provider`, `sourceId`); `sourceId` can be null. Where the payload sits depends on the source: Garmin, Withings and Intervals.icu put it on one row of the record, Oura on each row, and Apple Health and Health Connect only on the `<metric>_raw` row, so request that metric by name. Two rows of one record can each carry a payload, and the two can differ; both are returned as stored. A page with include_raw ends at 50 rows, or after the row that reaches about 8 MB, so its last row can take it past 8 MB and one large row can come alone; `page_cut` says which limit applied.
Query parameters
metric— Filter to one or more metric names. Repeat the param (?metric=a&metric=b) or comma-separate (?metric=a,b).provider— Filter to one or more providers (e.g. OURA, GARMIN), case-insensitive. Repeat the param (?provider=oura&provider=polar) or comma-separate (?provider=oura,polar).from— Start date (clamped to your plan window if earlier).to— End date (inclusive).cursor— Opaque pagination cursor from next_cursor.limit— Page size (max 1000; max 50 with include_raw).include_raw— Add the stored raw payload to each row (per-exercise sets, sleep stages, sample streams). Pages hold at most 50 rows and end after the row that reaches about 8 MB, so the last row can take a page past 8 MB and one large row can come alone. 30 raw requests a minute per account.device— Filter to one or more stored device values (the `device` field, not `deviceLabel`). Requires `metric`; `provider` is optional. Repeat or comma-separate; a device value that contains a comma cannot be matched. Rows with no device cannot be selected.source_id— Filter to one or more provider record ids. Requires `provider`.
GET /api/v1/catalog
Distinct metrics + providers available to you (within your window)
GET /api/v1/sources
Your connected sources
GET /api/v1/profile
Your profile + plan window
Machine-readable spec
OpenAPI 3.1: /api/openapi.json — import into Postman, Insomnia, or your own tooling.