What you need
- An iPhone on iOS 15 or later with Apple Health. Apple Watch data comes along too.
- The HealthAPI app. Free for 2 days, no card needed. Then an optional 7-day free trial when you subscribe. The preview includes 25 requests a day. When the 2 days are up, AI apps and the API stop reading your data until you choose a plan in the app. Your synced data is kept for about 5 weeks, so subscribing picks up where you left off. Pro is $4.99 a month or $49.99 a year (100 requests a day); Developer is $9.99 a month or $99.99 a year (1,000 a day). Cancel anytime in the App Store.
- n8n, on n8n Cloud or your own server.
Set it up in 5 steps
Copy your API key
Get HealthAPI from the App Store and let it sync. Then open Connect, tap Other tools and copy your key.Add the workflow
Copy the workflow below and paste it onto an empty n8n canvas with Ctrl+V (⌘V on a Mac). You get two nodes: a schedule at 8:00 every morning and an HTTP Request to HealthAPI.Add your key as a credential
Open the HTTP Request node. Under Credential for Header Auth, create a new credential with Name set toAuthorizationand Value set toBearerfollowed by your key. Save it.Test it
Select Execute workflow. The HTTP Request node's output shows yesterday's totals, averages, sleep and workouts as JSON.Send it somewhere and activate
Add the node you want after the HTTP Request, such as Google Sheets, Slack, Telegram or email, and map the fields (recipes below). Then switch the workflow to Active.
The workflow
Two nodes: a Schedule Trigger at 8:00 each morning, and an HTTP Request for yesterday's daily summary. The date is an n8n expression, so it is always yesterday. Your key isn't in it; n8n asks for the credential when you open the node.
{
"name": "Apple Health: yesterday's summary",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "days",
"triggerAtHour": 8
}
]
}
},
"name": "Every morning",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"url": "https://healthapi.app/api/v1/health/daily-summary",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "date",
"value": "={{ $today.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}"
}
]
},
"options": {}
},
"name": "HealthAPI daily summary",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
0
]
}
],
"connections": {
"Every morning": {
"main": [
[
{
"node": "HealthAPI daily summary",
"type": "main",
"index": 0
}
]
]
}
}
}Prefer to build it by hand? Add a Schedule Trigger (Days, hour 8), then an HTTP Request with Method GET, URL https://healthapi.app/api/v1/health/daily-summary, Authentication Generic Credential Type, Header Auth, and a query parameter date set to the expression {{ $today.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}.
What comes back
One item with the whole day, already added up so iPhone and Apple Watch readings count once:
{
"totals": {
"steps": 11284,
"distance_m": 8600,
"active_energy_kcal": 684,
"basal_energy_kcal": 1633,
"flights_climbed": 9,
"exercise_time_min": 52
},
"averages": {
"heart_rate_bpm": 62,
"resting_heart_rate_bpm": 54,
"hrv_ms": 68,
"spo2_pct": 98,
"respiratory_rate_bpm": 14
},
"sleep_hours": 7.7,
"workout_count": 1,
"workout_duration_minutes": 41.5,
…
}In later nodes, read a field with an expression such as {{ $json.totals.steps }}. Sleep is the night that ended that morning; averages are null on a day without readings. Every field is in the API reference.
Recipes
A row in Google Sheets
Add a Google Sheets node with the operation that appends a row, pick your sheet, and map each column to an expression: Date to {{ $today.minus({ days: 1 }).toFormat('yyyy-MM-dd') }}, Steps to {{ $json.totals.steps }}, Sleep to {{ $json.sleep_hours }}, Resting HR to {{ $json.averages.resting_heart_rate_bpm }}. Rather not run n8n? The Google Sheets guide does the same with a free Apps Script.
A morning message in Slack, Telegram or email
Add the Slack, Telegram or Send Email node and use this as the message text:
Yesterday: {{ $json.totals.steps }} steps, {{ $json.sleep_hours }} h of sleep,
resting heart rate {{ $json.averages.resting_heart_rate_bpm }} bpm, HRV {{ $json.averages.hrv_ms }} ms.Ask an AI about it
You can pass the JSON to an AI node with a prompt such as “Summarize yesterday in two sentences and compare it with my usual week.” For questions you ask yourself, it is simpler to connect Claude or ChatGPT directly: they can then look up any day, week or trend on their own.
Other endpoints worth a node
| You want | Request |
|---|---|
| Last week, totalled | GET /health/weekly-summary?week=2026-W42 |
| One metric for 90 days | GET /query/trends?type=restingHeartRate&days=90 |
| The newest reading of each metric | GET /health/latest |
| Workouts since a date | GET /health/workouts?start_date=2026-10-01 |
| Requests left today (doesn't count as one) | GET /usage |
All of them use the same credential. Metric names such as heartRateVariability and bodyMass are on the metrics page.
Questions
Does n8n have an Apple Health node?
No. Apple Health only lives on your iPhone, so no server can read it directly. HealthAPI syncs it from the iPhone to your own account, and n8n reads it from there with the standard HTTP Request node.
Can HealthAPI push data to n8n with a webhook?
No, HealthAPI doesn't send webhooks. n8n asks for the data on a schedule instead, which also means a missed run simply catches up next time.
How often can the workflow run?
Each run that reads health data is one request. Pro allows 100 a day and Developer 1,000, reset at 00:00 UTC. Once a day is plenty for a summary; for a dashboard, every hour is still well inside Pro.
Which timezone does the workflow use?
The schedule and $today use the workflow's timezone (Workflow settings, Timezone). HealthAPI counts days in your account's timezone, the one your iPhone uses, so keep the two the same.
Does it work with n8n Cloud and self-hosted n8n?
Yes. It only uses built-in nodes and makes a normal HTTPS request, so any n8n that can reach the internet works.
What about Zapier or Make?
The same idea works there: a daily schedule, a GET request (Webhooks by Zapier, or Make's HTTP module) to /health/daily-summary?date=… with the header Authorization: Bearer <key>, then a step that writes or sends the result.
