HealthSync

Docs & Support

Everything you need to sync Apple Health.

Guides for setting up HealthSync, running your own backend, understanding the data format, and fixing common issues. Still stuck? Email us anytime.

Getting started

HealthSync works out of the box with a private hosted workspace, so you can be syncing in under a minute. You only need an iPhone with Apple Health.

  1. Install HealthSyncDownload HealthSync for free from the App Store on an iPhone running iOS 17 or later.
  2. Tap ContinueHealthSync creates a private hosted workspace for you, then asks you to review Apple Health read permissions.
  3. Grant read accessAllow the Apple Health categories you want to sync. HealthSync cannot read anything you do not grant.
  4. Run your first syncTap Sync last 24 hours, or open Backfill date range to import older history.
  5. Fine-tune in SettingsSwitch to your own backend, choose data types, and set the sync frequency to hourly, daily, or manual.

HealthSync requests read-only HealthKit access. It never writes to Apple Health, and this website never sees your health data.

Download HealthSync on the App Store

Storage modes

Choose where your data goes. You can switch between modes at any time in Settings.

Hosted workspace

Default
  • No server to run: created automatically when you tap Continue.
  • Each workspace is isolated with its own ingest token.
  • Includes a private, read-only agent endpoint and token.
  • Refresh the agent token or reset storage from Settings.

Your own backend

Self-hosted
  • Enter any HTTPS backend URL and bearer token in Settings.
  • Use the open-source FastAPI + Postgres backend, or your own.
  • Data never touches HealthSync infrastructure.
  • Ideal for Grafana, data warehouses, and custom apps.

Self-hosting the backend

The repository includes a FastAPI backend that stores uploads in Postgres. The fastest way to run it locally is Docker Compose:

Terminal
git clone https://github.com/megabyte0x/healthykit.git
cd healthykit
cp .env.example .env
python3 -m backend.scripts.generate_token   # paste as API_TOKEN
python3 -m backend.scripts.generate_token   # paste as TOKEN_HASH_SECRET
docker compose up --build

Then, in HealthSync Settings, switch to your own backend and enter:

  • Simulator: http://127.0.0.1:8080
  • iPhone on the same Wi-Fi: http://<mac-lan-ip>:8080
  • Production: an HTTPS endpoint you control
  • Auth token: the same value as API_TOKEN

For Supabase, Neon, or any managed Postgres, set DATABASE_URL, run alembic upgrade head, and deploy uvicorn backend.main:app. For HTTPS, backups, and upgrades, follow the server setup and server operations guides.

Data types & export format

HealthSync supports 180+ Apple Health types across 11 categories: Activity, Heart, Body, Sleep & Mindfulness, Nutrition, Respiratory, Mobility, Hearing & Environment, Clinical, Reproductive Health, and Symptoms & Events, plus Workouts.

  • Every metric and workout gets a stable ID, healthkit:{sample_uuid}, so re-sending a record never creates a duplicate.
  • Deleted Apple Health samples are sent as deletions, scoped to your workspace and device.
  • Workouts include activity type, duration, active and total energy, distance, average and max heart rate, METs, and effort scores when the source records them.
  • Missing values are omitted, never filled with zero. Metadata values are always strings.

Background sync

HealthSync combines three wake-up paths to keep data current:

HealthKit deliveryWakes the app when Apple Health saves or deletes selected samples.
Scheduled refreshHourly or daily best-effort background refresh, set in Settings.
Catch-up on openEvery time you open the app, queued and recent changes are synced.

iOS controls when background work actually runs, so timing is not exact. Manual sync and backfill are always the reliable paths. Successful batches are pruned from the device after 7 days; failed ones stay queued until they upload.

Sync API reference

To build your own backend, accept this request. Respond with a 2xx status once the batch is stored; anything else keeps the batch queued for retry.

Request
POST {backend_url}/api/apple-health/sync
Authorization: Bearer {token}
Content-Type: application/json
X-Device-Id: {stable_local_device_id}
X-App-Version: {app_version}
Body (schema_version 2)
{
  "device_id": "device-1",
  "export_id": "11111111-1111-4111-8111-111111111111",
  "generated_at": "2026-05-31T10:00:00.000Z",
  "timezone": "Asia/Kolkata",
  "source": "ios-healthkit",
  "schema_version": 2,
  "date_range": {
    "start": "2026-05-30T10:00:00.000Z",
    "end": "2026-05-31T10:00:00.000Z"
  },
  "metrics": [
    {
      "id": "healthkit:{sample_uuid}",
      "type": "step_count",
      "value": 1243,
      "unit": "count",
      "start_at": "…", "end_at": "…",
      "source_name": "iPhone",
      "metadata": {}
    }
  ],
  "workouts": [],
  "deletions": [
    { "id": "healthkit:{sample_uuid}", "kind": "metric" }
  ]
}

The reference backend responds with counts for received, duplicates, and deleted. It also exposes authenticated read endpoints:

EndpointReturns
GET /api/apple-health/syncsUploaded sync batches
GET /api/apple-health/metricsMetrics, filterable by device and type
GET /api/apple-health/workoutsWorkouts, filterable by device
GET /healthBackend health check

AI agent access

Hosted workspaces include a separate read-only agent endpoint and token. Give these to an AI tool instead of your ingest token or database credentials.

Agent request
curl -H "Authorization: Bearer $AGENT_TOKEN" \
  "https://api.example.com/api/agent/health-data"

Responses include raw records plus agent-friendly fields: a catalog of metric types, activity types, devices, and timezones; local dates on every record; daily metric and workout summaries; and pagination. See the agent access guide for setup steps.

Never share your ingest token with an agent. If a token may have been exposed, refresh it from Settings before continuing.

Troubleshooting

Apple Health permissions are not ready

Open the Apple Health permission prompt again from HealthSync (Settings → Apple Health Access), or review permissions in iPhone Settings → Health. HealthSync cannot read categories you have not granted.

Backend connection fails

Confirm the URL is reachable from the iPhone, uses HTTPS in production, and matches the token saved in HealthSync. For same-Wi-Fi local testing, allow iOS Local Network access if prompted.

No samples are found

Check that the selected data types contain Apple Health samples in the chosen date range. Simulators are useful for UI testing but do not represent real Apple Health data availability.

Uploads keep retrying

Failed uploads stay queued locally for the next HealthKit update, scheduled catch-up, app activation, or manual sync. Open Sync Logs and confirm the backend is healthy.

Background sync seems late

iOS decides when background work runs. Low Power Mode, a recent reboot, or force-quitting the app can delay it. Opening the app triggers a catch-up sync, and manual sync always runs immediately.

Hosted storage or agent credentials need refresh

Use the hosted storage controls in Settings to refresh the read-only agent token or reset hosted storage when the saved token is no longer valid.

Workout details are missing

Selecting Workouts also requests heart-rate, energy, distance, and effort access. Re-request these from Settings → Apple Health Access. Fields the source app did not record are omitted rather than set to zero.

Still need help?

Email [email protected] with your iPhone model, iOS version, app version, storage mode, and the Sync Log message you see.

Please don't send raw Apple Health exports or any tokens. HealthSync is a data sync utility, not a medical device, and does not provide medical advice or emergency support.