Apple Health, in your own database
PulsHealth for iOS reads Apple Health and sends every sample to a server you run. It never writes back to Apple Health. It syncs the full history first, then keeps up in the background. There is no PulsHealth account and no PulsHealth cloud.
- It is on the App Store. Free, for iPhone. You can also build it yourself with Xcode 26 and XcodeGen. Running your own build on a real iPhone needs a paid Apple Developer team, because the HealthKit background-delivery entitlement requires one.
- You need a server first. The app has nowhere to sync until a backend exists. The reference stack comes up with one command; anything that speaks the documented protocol works just as well.
- All of it is open source. The app, the sync library, the server stack, the protocol and the dashboards are in one Apache-2.0 repository.
How the Sync Works
Each HealthKit type has its own cursor, saved only after your server confirms the batch. A failed upload re-sends the same page and the server deduplicates by sample UUID, so nothing is lost or duplicated.
What You Can Sync
80 HealthKit types, grouped the way Apple Health groups them. Turn on a starter set in one tap, or choose type by type. Nothing is read until you enable it and iOS grants permission.
Every type, by nameshow 80
Activity
- Active Energykcal
- Activity Rings
- Cycling Cadencecount/min
- Cycling Distancem
- Cycling PowerW
- Cycling Speedm/s
- Double Support %%
- Exercise Minutesmin
- Flights Climbedcount
- Ground Contact Timems
- Move Minutesmin
- Physical Effortkcal/hr*kg
- Resting Energykcal
- Running PowerW
- Running Speedm/s
- Running Stride Lengthm
- Stand Hours
- Stand Minutesmin
- Step Lengthm
- Stepscount
- Swimming Distancem
- Swimming Strokescount
- Vertical Oscillationcm
- VO₂ Maxml/kg*min
- Walking + Running Distancem
- Walking Asymmetry %%
- Walking Speedm/s
Heart
- AFib Burden%
- ECG
- Heart Ratecount/min
- Heartbeat Series (beat-to-beat)
- High HR Events
- HR Recovery (1 min)count/min
- HRV (SDNN)ms
- Irregular Rhythm Events
- Low Cardio Fitness Events
- Low HR Events
- Perfusion Index%
- Resting Heart Ratecount/min
- Walking HR Averagecount/min
Body
- Basal Body TemperaturedegC
- BMIcount
- Body Fat %%
- Body TemperaturedegC
- Body Weightkg
- Heightm
- Lean Body Masskg
- Waist Circumferencem
Respiratory
- Blood Oxygen%
- Respiratory Ratecount/min
Sleep
- Sleep Apnea Events
- Sleep Stages
- Wrist Temperature (Sleep)degC
Nutrition
- Caffeinemg
- Carbohydratesg
- Dietary Energykcal
- Fiberg
- Proteing
- Sodiummg
- Sugarg
- Total Fatg
- WatermL
Vitals
- Blood Alcohol Content%
- Blood Glucosemg/dL
- Blood Pressure (Diastolic)mmHg
- Blood Pressure (Systolic)mmHg
- Fallscount
Workouts
- Workouts
Other
- Environmental SounddBASPL
- Handwashing Events
- Headphone AudiodBASPL
- Loud Environment Events
- Loud Headphone Events
- Medication Doses
- Mindful Minutes
- Sound ReductiondBASPL
- State of Mind
- Time in Daylightmin
- Toothbrushing Events
- UV Exposurecount
Rendered at build time from the protocol's published vocabulary, catalog.json. Units are the canonical ones every sample is converted to before upload.
Workouts carry their GPS routes and per-second sensor series; ECGs bring their microvolt trace; State of Mind, sleep apnea events and medication doses come across on the iOS versions that support them.
One URL, one documented format
The app posts gzip-compressed NDJSON over HTTPS to the address you enter, with a bearer token you also choose. That is its only network destination. The format has a written spec, so the reference stack is one possible receiver rather than the only one.
Puls Sync Protocol v1
A JSON Schema for every line type, canonical units for every quantity, epoch-millisecond timestamps, and the retry and idempotency rules a receiver can rely on.
Write Your Own Backend
A fixture corpus, a batch checker, and a complete receiver in one standard-library Python file that writes to SQLite. Copy it, or read it alongside the spec.
Benchmark Before You Backfill
Reading HealthKit on the phone is the slow part, not the network. The in-app benchmark reads real data without uploading it, so you can see how long a backfill will take before starting one.
POST https://health.example.net/v1/batches
Authorization: Bearer <your token>
Content-Encoding: gzip
X-User-ID: <your user id>
{"batchID":"...","quantityCount":2,...}
{"uuid":"...","type":"HKQuantityType...
{"uuid":"...","type":"HKQuantityType...
→ 200 OK (only now does the phone
advance its cursor)What you can do with it
All of this ships in the same repository as the app.
Install it, then point it at your server
You need an iPhone on iOS 17 or later and a server you can reach. Apple Watch data arrives once iOS syncs it to the phone. If you would rather build it yourself, the repository has the Xcode instructions.
PulsHealth is not a medical device and gives no medical advice. Data is only as accurate as whatever recorded it into Apple Health. The name and logo belong to the developer; the code is Apache-2.0, so a fork ships under its own name.