Envoyer les données Apple Health vers un webhook
Apple Health n’a pas d’API web : vos données n’arrivent donc sur un webhook que si une app de votre iPhone les envoie. Marrow Health le fait gratuitement : une automatisation envoie en POST vos mesures de santé, entraînements, séries de musculation, journal alimentaire, ou symptômes et humeur vers n’importe quelle URL, en JSON ou en CSV, selon le calendrier que vous choisissez, app fermée. Voici la configuration, la charge utile et des récepteurs qui fonctionnent pour n8n, Home Assistant et un serveur simple. Nous créons Marrow.
Configurer l’automatisation
- Dans Marrow Health, ouvrez l’onglet Exporter, puis Automatisé, puis Nouvelle automatisation.
- Collez l’URL de votre webhook (en HTTPS). Ajoutez les en-têtes que votre récepteur vérifie, comme un jeton
Authorizationde type bearer ou une clé d’authentification par en-tête n8n. - Choisissez le type de données : Mesures de santé, Entraînements, Journal de musculation, Journal alimentaire ou Symptômes et humeur. Une automatisation envoie un seul type, et vous pouvez en avoir jusqu’à dix.
- Choisissez JSON ou CSV, la période (Depuis la dernière exécution par défaut) et la fréquence, en minutes, heures ou jours.
- Activez-la et touchez Lancer maintenant pour envoyer une première charge utile en surveillant le récepteur.
Chaque requête est un POST avec Content-Type: application/json (ou text/csv) et vos en-têtes. Chaque exécution, avec son code de réponse, figure dans l’historique de l’automatisation dans l’app.
Ce qui arrive
Les mesures de santé arrivent sous forme de totaux quotidiens, dans l’unité indiquée dans units. La fréquence cardiaque arrive avec la moyenne, le minimum et le maximum de chaque jour, et le sommeil avec chaque nuit et ses phases, en heures :
{"data": {"metrics": [
{"name": "body_mass", "units": "kg",
"data": [{"date": "2026-09-11", "qty": 81.3}]},
{"name": "step_count", "units": "count",
"data": [{"date": "2026-09-11", "qty": 8746}]},
{"name": "heart_rate", "units": "bpm",
"data": [{"date": "2026-09-11", "Avg": 71, "Min": 52, "Max": 148}]},
{"name": "sleep_analysis", "units": "h",
"data": [{"date": "2026-09-11", "totalSleep": 7.2, "asleep": 7.2, "deep": 1.1, "rem": 1.6, "core": 4.3, "awake": 0.2,
"sleepStart": "2026-09-10 23:36:00 -0400", "sleepEnd": "2026-09-11 07:02:00 -0400"}]}
]}}
Les charges utiles des entraînements, de la musculation, de la nutrition et de l’humeur, les échantillons bruts au lieu des totaux quotidiens, et la structure du CSV se trouvent dans la référence des automatisations.
Le recevoir dans n8n
- Ajoutez un nœud Webhook. Réglez HTTP Method sur
POSTet donnez-lui un chemin, par exempleapple-health. - Pour un secret, réglez Authentication sur Header Auth et ajoutez les mêmes nom et valeur d’en-tête à l’automatisation Marrow.
- Cliquez sur Listen for test event, puis touchez Lancer maintenant dans Marrow dans les deux minutes. La charge utile apparaît dans l’éditeur.
- Publiez le workflow et pointez Marrow vers la Production URL (celle qui contient
/webhook/, pas/webhook-test/). L’URL de test cesse d’écouter après un test.
La charge utile se trouve sous body, donc les pas du jour sont {{ $json.body.data.metrics.find(m => m.name === 'step_count').data.at(-1).qty }} dans une expression. Ajoutez un nœud Split Out sur body.data.metrics pour traiter chaque mesure comme un élément à part. n8n accepte par défaut des charges utiles jusqu’à 16 Mo, ce qui couvre des années de totaux quotidiens. Les exécutions en production s’affichent sous Executions, pas dans l’éditeur. (Documentation du nœud Webhook n8n)
Le recevoir dans Home Assistant
Un déclencheur webhook reçoit le POST à l’adresse /api/webhook/<webhook_id>. Cette automatisation stocke le dernier nombre de pas dans un assistant numérique appelé input_number.steps_today (créez-le d’abord, avec un maximum supérieur à votre meilleur jour) :
automation:
- alias: "Apple Health from Marrow"
triggers:
- trigger: webhook
webhook_id: "pick-a-long-random-id"
allowed_methods:
- POST
local_only: false
actions:
- action: input_number.set_value
target:
entity_id: input_number.steps_today
data:
value: >-
{{ ((trigger.json.data.metrics
| selectattr('name', 'eq', 'step_count') | first).data
| last).qty }}
- Le corps JSON se trouve dans
trigger.jsonparce que Marrow envoieContent-Type: application/json. local_onlyest activé par défaut, ce qui n’accepte que les envois depuis votre réseau domestique ou depuis une URL de webhook cloud Nabu Casa. Réglez-le surfalsequand le téléphone envoie via internet vers votre propre adresse HTTPS.- L’identifiant du webhook est le seul secret : faites-le long et aléatoire.
(Documentation du déclencheur webhook de Home Assistant)
Le recevoir sur votre propre serveur
Tout point de terminaison qui accepte un POST HTTPS et répond en 2xx convient. Celui-ci archive chaque charge utile dans un fichier :
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class H(BaseHTTPRequestHandler):
def do_POST(self):
body = self.rfile.read(int(self.headers.get("Content-Length", 0)))
with open(f"marrow-{int(time.time())}.json", "wb") as f:
f.write(body)
self.send_response(200)
self.end_headers()
HTTPServer(("0.0.0.0", 8798), H).serve_forever()
Placez-le derrière HTTPS avec un Cloudflare Tunnel, Tailscale Funnel ou un reverse proxy. Si vous préférez une base de données interrogeable à un dossier de fichiers, le miroir autohébergé de Marrow est ce récepteur déjà écrit, et les agents IA peuvent aussi l’interroger.
Trois règles pour un récepteur qui ne perd jamais de données
- Le dernier gagne. Stockez chaque valeur avec la mesure et le jour pour clé, et écrasez en cas de répétition. Depuis la dernière exécution renvoie volontairement les deux derniers jours, car Apple Health continue de compléter une journée après sa fin.
- Enregistrez d’abord le corps brut, puis analysez-le. Un bogue d’analyse ne doit jamais vous coûter des données.
- Répondez vite. Marrow attend jusqu’au délai que vous avez réglé (60 secondes par défaut) et relance une exécution échouée depuis la dernière période réussie à son tour suivant.
Quand s’exécute-t-elle ?
Chaque fois qu’iOS laisse Marrow s’exécuter : après sa synchronisation avec Apple Health, quand vous l’ouvrez et pendant l’actualisation en arrière-plan, dès que l’intervalle choisi est écoulé. C’est iOS qui décide du moment de l’actualisation en arrière-plan : un téléphone laissé verrouillé toute la journée envoie donc au prochain déverrouillage, et Depuis la dernière exécution comble l’écart.
D’autres façons de faire
- Health Auto Export envoie aussi les données Apple Health vers des webhooks, et son JSON de mesures a la même structure que celui de Marrow. Ses automatisations demandent l’offre Premium.
- Raccourcis Apple peut lire des échantillons de santé et les envoyer avec Get Contents of URL, dans une automatisation personnelle à heure fixe. C’est gratuit, mais cela ne peut lire les données Santé que téléphone déverrouillé, et vous construisez et entretenez chaque mesure vous-même.
- L’export.zip d’Apple est une sauvegarde complète ponctuelle, pas un flux. Pour en tirer du CSV, utilisez notre convertisseur dans le navigateur.