Server API
Start the server with:
healthsync server --port 8080
POST /api/upload
Upload an Apple Health export file for parsing.
- Content-Type:
multipart/form-data - Field:
file— the.zipor.xmlfile - Max size: 2GB
Response: 202 Accepted
{
"status": "accepted",
"message": "file uploaded, parsing in background",
"poll": "/api/upload/status"
}
Parsing runs asynchronously in the background. Poll /api/upload/status for progress.
Error responses:
| Code | Reason |
|---|---|
400 | Missing file, unsupported extension |
409 | A parse job is already running |
Example:
curl -F "file=@export.zip" http://localhost:8080/api/upload
GET /api/upload/status
Check the status of the current or most recent parse job.
Response: 200 OK
{
"status": "running",
"running": true,
"records": 340000,
"workouts": 0,
"started_at": "2026-02-12T14:30:00+05:30",
"elapsed": "8.5s"
}
Status values:
| Status | Description |
|---|---|
idle | No parse has been run since server start |
running | Parse is in progress |
completed | Last parse finished successfully |
failed | Last parse encountered an error |
When completed:
{
"status": "completed",
"running": false,
"records": 540110,
"workouts": 1011,
"total_records": 540110,
"total_workouts": 1011,
"started_at": "2026-02-12T14:30:00+05:30",
"elapsed": "30.6s"
}
GET /api/health/{table}
Query health data as JSON.
Path parameters:
| Parameter | Description |
|---|---|
table | One of: heart-rate, steps, spo2, vo2max, sleep, workouts |
Query parameters:
| Parameter | Description | Default |
|---|---|---|
from | Filter records from this date (inclusive) | — |
to | Filter records to this date (inclusive) | — |
limit | Maximum records to return | 50 |
Response: 200 OK — JSON array of records
[
{
"id": 1,
"source_name": "Siddhartha's Apple Watch",
"start_date": "2026-02-12 19:11:31 +0530",
"end_date": "2026-02-12 19:11:31 +0530",
"value": 72,
"unit": "count/min",
"created_at": "2026-02-12 14:24:12"
}
]
Examples:
# Recent heart rate
curl "http://localhost:8080/api/health/heart-rate?limit=5"
# Steps in date range
curl "http://localhost:8080/api/health/steps?from=2024-01-01&to=2024-06-30&limit=100"
# All workouts
curl "http://localhost:8080/api/health/workouts?limit=0"
Tailscale + iPhone Shortcuts
The server is designed to receive uploads from iPhone over Tailscale:
- Run
healthsync serveron your Mac - Both devices on the same Tailscale network
- Create an iPhone Shortcut that:
- Exports Apple Health data
- Sends it via
POSTtohttp://<tailscale-ip>:8080/api/upload
- Run the Shortcut weekly for fresh data