Marrow Health
FR
Télécharger

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

  1. Dans Marrow Health, ouvrez l’onglet Exporter, puis Automatisé, puis Nouvelle automatisation.
  2. Collez l’URL de votre webhook (en HTTPS). Ajoutez les en-têtes que votre récepteur vérifie, comme un jeton Authorization de type bearer ou une clé d’authentification par en-tête n8n.
  3. 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.
  4. 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.
  5. 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

  1. Ajoutez un nœud Webhook. Réglez HTTP Method sur POST et donnez-lui un chemin, par exemple apple-health.
  2. Pour un secret, réglez Authentication sur Header Auth et ajoutez les mêmes nom et valeur d’en-tête à l’automatisation Marrow.
  3. Cliquez sur Listen for test event, puis touchez Lancer maintenant dans Marrow dans les deux minutes. La charge utile apparaît dans l’éditeur.
  4. 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 }}

(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

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