Writing Article

Healthagent: Apple Health data ingestion and insights

· 2 min read
Project Health Agent

HealthAgent is my attempt to turn the stats sitting in Apple Health into something I can actually read and act on.

Why I built it

I track nutrition in Macrofactor on my iPhone, and my Apple Watch handles workouts, heart rate, and activity. I could view these separately in each app, but I wanted to compare the trends side by side and figure out which signals actually mattered to me.

Macrofactor automatically writes nutrition data to Apple Health, and Watch workouts go there too, which made it the natural hub. I set up a daily export to my own service using Health Auto Export, an iOS app that can POST selected data to a REST API.

What it does

HealthAgent ingests Apple Health Auto Export JSON and stores the raw file locally in dev, or in GCS in production. It normalises everything into Postgres and rolls it up into daily metrics, then presents trends and next actions in a Next.js UI. There's an optional weekly insights pass gated behind INSIGHTS_ENABLED. It also supports multi-user access via GitHub auth (NextAuth), with per-user ingest tokens and scoped data. The daily pipeline is what earns it the "agent" label.

What I'm working on now

With everything normalised in the database, the next step is asking an LLM to surface correlations automatically: "Your sleep was down this week and sugar was up," or "Training volume increased while recovery dipped." Finding those patterns without having to go looking for them is the focus of the current iteration. I use Neon for the database since it's cheap and doesn't need to be always on.

Infrastructure

Cloud Build runs Prisma migrations, builds and pushes the Fastify API Docker image, and deploys to Cloud Run. Secrets live in Secret Manager, raw files in a GCS bucket. Cloud Scheduler triggers /api/pipeline/run daily with X-PIPELINE-TOKEN and X-USER-ID. The frontend is on Vercel.

If you want to try it, it's live at health.hamishburke.dev. Sign in and have a look. The code is on GitHub too — if you find any bugs, open an issue.