API Reference

A small, predictable REST API over your Apple Health data. JSON in, JSON out, Bearer auth.

Quickstart

Install the HealthAPI app for iPhone, authorize Apple Health, and open Connect AI to copy your personal key. Then call the API with your key as a Bearer token. The base URL is:

https://healthapi.app/api/v1

Every example below is a complete request — drop in your key and run it.

Authentication

All endpoints require your API key in the Authorization header. There are no other credentials — the key is the identity.

Authorization: Bearer <YOUR_API_KEY>

Keys are issued by the iPhone app and can be rotated from the Console or via /account/regenerate-key. A missing or invalid key returns 401.

Usage & quota

GET /usage

Returns your plan and how much of your daily quota you've used. This call is cheap and reflects live consumption.

# request curl "https://healthapi.app/api/v1/usage" -H "Authorization: Bearer $KEY" # response { "plan_tier": "free", "plan_label": "Trial", "window": "1d", "limit": 25, "used": 7, "remaining": 18, "reset_at": "2026-06-12T00:00:00Z" }

Daily summary

GET /query/daily-summary

Steps, average heart rate, and workouts for a single local day.

ParamTypeNotes
datestringYYYY-MM-DD. Defaults to today in your timezone.
tzstringIANA zone, e.g. America/New_York. Defaults to your account timezone.
curl "https://healthapi.app/api/v1/query/daily-summary?date=2026-06-11&tz=UTC" \ -H "Authorization: Bearer $KEY" { "date": "2026-06-11", "steps": 11294, "avg_heart_rate": 62, "workouts": [ … ] }

Step totals are aggregated across sources, so overlapping iPhone and Apple Watch samples aren't counted twice — the number matches Apple Health.

GET /query/trends

Per-day statistics for one metric over a window.

ParamTypeNotes
typestringRequired. e.g. stepCount, heartRate, activeEnergyBurned.
daysinteger1–365. Defaults to 7.
tzstringIANA zone. Optional.
curl "https://healthapi.app/api/v1/query/trends?type=heartRate&days=7&tz=UTC" \ -H "Authorization: Bearer $KEY" { "type": "heartRate", "period_days": 7, "data": [ { "date": "2026-06-10", "avg": 64, "min": 48, "max": 142, "samples": 870 }, … ] }

For point-in-time metrics (heart rate, HRV, SpO₂), each day's avg/min/max is served from a pre-computed daily rollup, so long ranges stay fast.

Full daily aggregate

GET /health/daily-summary

The complete daily roll-up: steps, active & basal energy, distance, flights, exercise time, heart-rate averages, sleep, and workouts.

ParamTypeNotes
datestringRequired. YYYY-MM-DD.
tzstringIANA zone. Optional.
curl "https://healthapi.app/api/v1/health/daily-summary?date=2026-06-11" \ -H "Authorization: Bearer $KEY" { "totals": { "steps": 11294, "active_energy_kcal": 540, "distance_m": 8120 }, "averages": { "heart_rate_bpm": 62 }, "sleep": { … }, "data_coverage_pct": 86 }

Weekly summary

GET /health/weekly-summary

The same aggregate as the full daily roll-up, totalled and averaged across an ISO calendar week.

ParamTypeNotes
weekstringRequired. ISO week in YYYY-Www format, e.g. 2026-W19.
tzstringIANA zone. Optional.
curl "https://healthapi.app/api/v1/health/weekly-summary?week=2026-W23" \ -H "Authorization: Bearer $KEY"

Raw samples

GET /health/samples

Individual data points — when you want the raw series, not an aggregate. All filters are optional; results are newest-first.

ParamTypeNotes
typestringOptional. Filter by metric (e.g. heartRate).
start_datestringISO date/time. Optional.
end_datestringISO date/time. Optional.
limitinteger1–20000. Defaults to 100.
curl "https://healthapi.app/api/v1/health/samples?type=heartRate&start_date=2026-06-11&end_date=2026-06-12" \ -H "Authorization: Bearer $KEY"

Workouts

GET /health/workouts

Your workout sessions — type, duration, distance, and energy.

ParamTypeNotes
activity_typestringOptional. Filter by workout activity type.
start_datestringISO date/time. Optional.
end_datestringISO date/time. Optional.
limitinteger1–20000. Defaults to 100.
curl "https://healthapi.app/api/v1/health/workouts?limit=20" \ -H "Authorization: Bearer $KEY"

Latest readings

GET /health/latest

The most recent reading for every metric you sync — one indexed call, ideal for a dashboard.

curl "https://healthapi.app/api/v1/health/latest" -H "Authorization: Bearer $KEY" { "heartRate": { "value": 62, "unit": "count/min", "date": "2026-06-11T14:02:00Z" }, … }

Regenerate key

POST /account/regenerate-key

Issues a new key and invalidates the current one immediately. Update any connected agents afterward.

curl -X POST "https://healthapi.app/api/v1/account/regenerate-key" \ -H "Authorization: Bearer $KEY" { "api_key": "<new key>", "created_at": "2026-06-11T14:22:00Z", "expires_at": null }

Export your data

GET /gdpr/export

Downloads a complete JSON export of your account, health samples, and workouts.

curl "https://healthapi.app/api/v1/gdpr/export" -H "Authorization: Bearer $KEY" -o export.json

Delete account

DELETE /account/delete

Deactivates your account immediately and schedules permanent deletion. You have a 30-day grace period — sign back in within 30 days to recover everything. For immediate, irreversible erasure, use DELETE /gdpr/account with a confirmation body.

curl -X DELETE "https://healthapi.app/api/v1/account/delete" -H "Authorization: Bearer $KEY"

Rate limits

Quotas are per account, per day — the window resets at 00:00 UTC. Your own data uploads from the app don't count against them — only API queries do. Every account starts with a 7-day free trial; after that, an active subscription (Pro or Developer) is required — there is no permanent free tier. See plans for details.

PlanRequests / dayBest for
Free trial25First 7 days
Pro100Personal dashboards
Developer1,000Agents that poll
EnterpriseCustomProducts & teams

Every authenticated response includes your live quota in headers:

X-RateLimit-Limit: 25 X-RateLimit-Remaining: 18 X-RateLimit-Reset: 1749654000

Exceeding the limit returns 429 Too Many Requests with a Retry-After header.

Errors

Errors return the appropriate HTTP status with a JSON body shaped like:

{ "detail": "Rate limit exceeded. Your free trial allows 25 requests/day. Upgrade for a higher daily limit." }
StatusMeaning
401Missing or invalid API key.
409Conflict — e.g. an Apple ID already linked to another account (detail.code = account_exists).
422Validation error — a required parameter is missing or malformed.
429Rate limit exceeded. Back off until Retry-After.