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.
- An OpenAI or Anthropic API key, and an email account n8n can send from (SMTP), or Telegram or Slack.
New to n8n and HealthAPI? The n8n guide covers the basics with a daily workflow. This page builds the weekly summary on top.
How it works
| Node | What it does |
|---|---|
| Every Monday | Starts the workflow at 8:00 on Mondays, in the workflow's timezone. |
| Last week | Reads the weekly summary for the week that just ended. |
| Week before | Reads the week before that, so the summary can compare. |
| Write the summary | A Basic LLM Chain: sends both weeks and the prompt to the chat model under it. |
| Email me | Sends the summary to your inbox. |
Each weekly summary is one request with totals and averages for Monday to Sunday plus a line for every day, in your account's timezone. The week is an expression ({{ $today.minus({ weeks: 1 }).toFormat("kkkk-'W'WW") }}), so it is always the week that just ended.
Set it up in 6 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.Paste the workflow
Copy the workflow below and paste it onto an empty n8n canvas with Ctrl+V (⌘V on a Mac). You get a Monday 8:00 schedule, two HTTP Requests, a Basic LLM Chain with an OpenAI Chat Model, and Send Email.Add your HealthAPI key
Open Last week and create a Header Auth credential with NameAuthorizationand ValueBearerfollowed by your key. Select the same credential in Week before.Add your AI key
Open OpenAI Chat Model, create a credential with your OpenAI API key, and pick a model. For Claude, swap in the Anthropic Chat Model (below).Set up the email
Open Email me, add your SMTP credential, and put your own address in From Email and To Email. Or replace it with Telegram or Slack.Test it, then activate
Select Execute workflow. A summary of last week lands in your inbox. Then switch the workflow to Active.
The workflow
No keys are in it: n8n asks for each credential when you open the node. Paste it onto an empty canvas.
{
"name": "Apple Health: weekly summary by AI",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 8
}
]
}
},
"name": "Every Monday",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"url": "https://healthapi.app/api/v1/health/weekly-summary",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "week",
"value": "={{ $today.minus({ weeks: 1 }).toFormat(\"kkkk-'W'WW\") }}"
}
]
},
"options": {}
},
"name": "Last week",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
220,
0
]
},
{
"parameters": {
"url": "https://healthapi.app/api/v1/health/weekly-summary",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "week",
"value": "={{ $today.minus({ weeks: 2 }).toFormat(\"kkkk-'W'WW\") }}"
}
]
},
"options": {}
},
"name": "Week before",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
0
]
},
{
"parameters": {
"promptType": "define",
"text": "=You write a short weekly health note for one person, from their Apple Health data.\n\nRules:\n- Plain English, under 150 words, no headings, no medical advice.\n- Cover steps, sleep, resting heart rate, HRV and workouts. Compare last week with the week before, and name the best and the hardest day.\n- Use only the numbers below. A 0 or null means nothing was recorded, not a bad day.\n- sleep_hours is time asleep in the night that ended that morning. totals.distance_m is meters. averages.hrv_ms is HRV (SDNN) in milliseconds.\n\nLast week ({{ $('Last week').first().json.week }}):\n{{ JSON.stringify($('Last week').first().json) }}\n\nThe week before:\n{{ JSON.stringify($json) }}"
},
"name": "Write the summary",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.5,
"position": [
660,
0
]
},
{
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini"
},
"options": {}
},
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
660,
220
]
},
{
"parameters": {
"fromEmail": "you@example.com",
"toEmail": "you@example.com",
"subject": "=Your week in health ({{ $('Last week').first().json.week }})",
"emailFormat": "text",
"text": "={{ $json.text }}",
"options": {}
},
"name": "Email me",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [
940,
0
]
}
],
"connections": {
"Every Monday": {
"main": [
[
{
"node": "Last week",
"type": "main",
"index": 0
}
]
]
},
"Last week": {
"main": [
[
{
"node": "Week before",
"type": "main",
"index": 0
}
]
]
},
"Week before": {
"main": [
[
{
"node": "Write the summary",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Write the summary",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Write the summary": {
"main": [
[
{
"node": "Email me",
"type": "main",
"index": 0
}
]
]
}
}
}Set the workflow's timezone (Workflow settings, Timezone) to the one your iPhone uses, so “last week” and the 8:00 start match your days.
The prompt
This is the text in Write the summary. Change it to suit you: shorter, a different tone, a focus on sleep or training. The last two lines hand the model both weeks as JSON.
You write a short weekly health note for one person, from their Apple Health data.
Rules:
- Plain English, under 150 words, no headings, no medical advice.
- Cover steps, sleep, resting heart rate, HRV and workouts. Compare last week with the week before, and name the best and the hardest day.
- Use only the numbers below. A 0 or null means nothing was recorded, not a bad day.
- sleep_hours is time asleep in the night that ended that morning. totals.distance_m is meters. averages.hrv_ms is HRV (SDNN) in milliseconds.
Last week ({{ $('Last week').first().json.week }}):
{{ JSON.stringify($('Last week').first().json) }}
The week before:
{{ JSON.stringify($json) }}The rules about units and missing values matter. Without them a model can read sleep as minutes, or call a day with no watch on it a bad day. The numbers come from your HealthAPI account; only the wording is the model's, so check anything surprising against the Health app.
Claude instead of OpenAI
Delete OpenAI Chat Model, select the + under Model on Write the summary, and add Anthropic Chat Model. Create a credential with your Anthropic API key and pick a Claude model from its list. Nothing else changes: the prompt and the email stay as they are.
Telegram or Slack instead of email
Replace Email me with a Telegram node (Send Message, your Chat ID) or a Slack node (Send, to yourself or a channel), and set its text to {{ $json.text }}. That is the summary the chain wrote.
Questions
How many HealthAPI requests does it use?
Two a week, both on Monday morning: one for last week and one for the week before. Each test run also uses two. That is far inside any plan's daily limit, so the rest of your requests stay free for other tools.
What does the AI part cost?
The AI provider bills your API key for each run, at its own prices. One run sends two weeks of daily numbers and gets back about 150 words, once a week. HealthAPI doesn't charge for it.
Where does my data go?
n8n reads two weeks of numbers from your HealthAPI account and sends them to the AI provider you picked, under that provider's API terms, and the summary to your inbox. Nothing else is sent, and only when the workflow runs.
Can it look at more than steps and sleep?
Yes. The weekly summary also has active and resting energy, distance, flights climbed, exercise minutes, average heart rate, blood oxygen and breathing rate, for the week and for each day. Name them in the prompt and the summary will cover them.
Why not just ask Claude or ChatGPT?
You can, any time: connect your assistant and ask about any day, week or trend. This workflow is for a summary that arrives on its own, without you asking.
Does HealthAPI send the data to n8n itself?
No, HealthAPI doesn't push or send webhooks. n8n asks for the two weeks on its schedule, which also means a missed Monday simply runs the next time.
