API Reference

The Health Data AI Analyzer Mac app exposes a read-only localhost API on http://127.0.0.1:8765. Use it to build OpenClaw integrations, Claude Code workflows, Mac Shortcuts, and custom scripts that read your selected health data locally. A connected client may send that data onward to a cloud provider.

This API only works after installing Health Data AI Analyzer (Mac app). The localhost API is not a public cloud API.

Download on the Mac App Store

  1. Install the Mac app.
  2. Open the app.
  3. Import and analyze data, select the saved dataset to share, and explicitly enable the local API. Opening the app alone does not start sharing.

Also see Apple Health MCP and OpenClaw.

The API is read-only. Tools can query your health summaries but cannot write, delete, or modify your data.

OpenAPI specification. A machine-readable OpenAPI 3.1 spec for this API is available at /openapi.yaml and /openapi.json (identical content, YAML and JSON). Use it to auto-generate client bindings and adapters.

Overview

The Mac app reads your imported Apple Health dataset and serves compact summaries over 127.0.0.1. The API uses the app's selected integration dataset. Once you import data or choose Use for Integrations on a saved analysis, the dataset stays available across app relaunches.

Base URL http://127.0.0.1:8765
Protocol HTTP (localhost only)
Format JSON
Access Read-only

Authentication

Send the X-Health-Analyzer-Token header for every health-data request. Read the real token file location from GET /status (token_path); do not assume an example path exists on your Mac.

In the redesigned preview, only GET /status and GET /openclaw/status are exempt. All three OpenClaw data endpoints require the token. Older released builds may accept those endpoints without it; clients should send the token regardless. Keep the token private and leave the server on localhost.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" http://127.0.0.1:8765/summary

Endpoints

GET /openclaw/status

Readiness endpoint for OpenClaw and local AI integrations. Returns app version, whether a dataset is loaded, last import and sync timestamps, and available metrics. No authentication required.

curl http://127.0.0.1:8765/openclaw/status

Example response:

{
  "ok": true,
  "success": true,
  "summary": "Health Data AI Analyzer is ready and has an analyzed health dataset loaded.",
  "data": {
    "app": "Health Data AI Analyzer",
    "app_version": "1.4.2",
    "server_version": "v1",
    "dataset_loaded": true,
    "last_imported_at": "2026-03-19T10:30:00Z",
    "last_synced_at": "2026-03-19T10:35:00Z",
    "available_metrics": [
      "steps", "sleep", "workouts",
      "heart_rate", "hrv"
    ]
  }
}

GET /openclaw/daily-brief?date=YYYY-MM-DD

Compact Apple Health daily summary for AI assistants and scripts. Returns steps, sleep, workouts, heart rate, HRV, signals, sync metadata, and a human-readable context summary. If date is omitted, the most recent available day is used. Send the token header; see version-specific authentication.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" "http://127.0.0.1:8765/openclaw/daily-brief?date=2026-03-19"

Example response:

{
  "ok": true,
  "success": true,
  "summary": "Daily Apple Health brief from Health Data AI Analyzer.",
  "data": {
    "date": "2026-03-19",
    "steps": {
      "value": 2444,
      "baseline_7d": 10004.57,
      "delta_vs_baseline": -7560.57
    },
    "sleep": {
      "hours": null,
      "baseline_7d": 6.47
    },
    "workouts": {
      "count": 0,
      "total_minutes": 0
    },
    "signals": ["activity_below_baseline"],
    "context_summary": "Daily brief for 2026-03-19, steps 2444"
  }
}

GET /openclaw/recent-trends?days=N

Recent step and sleep trends for the last N days (default 7, minimum 1). Returns average, best, and latest values plus a per-day series for each. Send the token header; see version-specific authentication.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" "http://127.0.0.1:8765/openclaw/recent-trends?days=7"

Example response:

{
  "ok": true,
  "success": true,
  "summary": "Recent Apple Health step and sleep trends from Health Data AI Analyzer.",
  "data": {
    "days": 7,
    "steps": {
      "average": 8576.0,
      "best": 12045.0,
      "latest": 2444.0,
      "series": [
        { "date": "2026-03-13", "value": 11204.0 },
        { "date": "2026-03-19", "value": 2444.0 }
      ]
    },
    "sleep": {
      "average": 6.72,
      "best": 8.0,
      "latest": null,
      "series": [
        { "date": "2026-03-13", "value": 7.2 },
        { "date": "2026-03-19", "value": null }
      ]
    }
  }
}

GET /openclaw/weekly-summary?days=N

Rolled-up summary over the last N days (default 7, minimum 1): step and sleep averages, total workout minutes and count, average heart rate, plus step and sleep day series. Send the token header; see version-specific authentication.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" "http://127.0.0.1:8765/openclaw/weekly-summary?days=7"

Example response:

{
  "ok": true,
  "success": true,
  "summary": "Weekly Apple Health summary from Health Data AI Analyzer.",
  "data": {
    "days": 7,
    "steps_average": 8576.0,
    "sleep_average": 6.72,
    "workout_minutes_total": 202.0,
    "workout_count_total": 5,
    "heart_rate_average": 72.5,
    "steps_series": [
      { "date": "2026-03-13", "value": 11204.0 },
      { "date": "2026-03-19", "value": 2444.0 }
    ],
    "sleep_series": [
      { "date": "2026-03-13", "value": 7.2 },
      { "date": "2026-03-19", "value": null }
    ]
  }
}

GET /status

General local API status endpoint for host tools and debugging. Returns app and server version, dataset state, import/sync timestamps, and the token path for protected endpoints. No authentication required on loopback.

curl http://127.0.0.1:8765/status

Example response:

{
  "ok": true,
  "success": true,
  "data": {
    "app_version": "1.4.2",
    "server_version": "v1",
    "dataset_loaded": true,
    "last_imported_at": "2026-03-19T10:30:00Z",
    "last_synced_at": "2026-03-19T10:35:00Z",
    "token_path": "/Users/you/Library/Containers/.../local-api-token.txt"
  }
}

Use the absolute path from token_path to read the token. In examples on this page we abbreviate it as ~/.health-analyzer/token.

GET /summary

Compact human-readable summary of the selected integration dataset. Requires X-Health-Analyzer-Token.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" http://127.0.0.1:8765/summary

GET /steps/daily?start=YYYY-MM-DD&end=YYYY-MM-DD

Normalized daily step counts for a date range. Requires X-Health-Analyzer-Token. Each day exposes its count under value.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" \
  "http://127.0.0.1:8765/steps/daily?start=2026-03-13&end=2026-03-19"

Example response:

{
  "ok": true,
  "success": true,
  "data": {
    "unit": "count",
    "days": [
      { "date": "2026-03-13", "value": 11204 },
      { "date": "2026-03-14", "value": 8930 },
      { "date": "2026-03-15", "value": 12045 },
      { "date": "2026-03-16", "value": 9512 },
      { "date": "2026-03-17", "value": 10321 },
      { "date": "2026-03-18", "value": 7576 },
      { "date": "2026-03-19", "value": 2444 }
    ]
  }
}

GET /sleep/summary?start=YYYY-MM-DD&end=YYYY-MM-DD

Normalized daily sleep summaries for a date range, plus range-level averages. Requires X-Health-Analyzer-Token.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" \
  "http://127.0.0.1:8765/sleep/summary?start=2026-03-13&end=2026-03-19"

Example response:

{
  "ok": true,
  "success": true,
  "data": {
    "avg_hours": 6.72,
    "avg_bedtime": "23:41",
    "avg_wake_time": "06:58",
    "days_detected": 6,
    "days": [
      { "date": "2026-03-13", "hours": 7.2, "asleep_hours": 6.6, "in_bed_hours": 7.2 },
      { "date": "2026-03-18", "hours": 6.7, "asleep_hours": 6.1, "in_bed_hours": 6.7 },
      { "date": "2026-03-19", "hours": null, "asleep_hours": null, "in_bed_hours": null }
    ]
  }
}

GET /workouts/summary?start=YYYY-MM-DD&end=YYYY-MM-DD

Workout totals, a per-type breakdown, and per-session summaries for a date range. Requires X-Health-Analyzer-Token.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" \
  "http://127.0.0.1:8765/workouts/summary?start=2026-03-13&end=2026-03-19"

Example response:

{
  "ok": true,
  "success": true,
  "data": {
    "count": 5,
    "total_minutes": 202,
    "by_type": [
      { "type": "Running", "count": 3, "minutes": 127 },
      { "type": "Strength Training", "count": 2, "minutes": 75 }
    ],
    "workouts": [
      {
        "date": "2026-03-13T18:00:00Z",
        "type": "Running",
        "duration_minutes": 45,
        "energy_burned_kcal": 420
      }
    ]
  }
}

GET /heart-rate/trends?start=YYYY-MM-DD&end=YYYY-MM-DD

Average heart rate, resting heart rate, and HRV (SDNN) day series for a date range. Requires X-Health-Analyzer-Token. Each metric is returned as its own array of { date, value } points.

curl -H "X-Health-Analyzer-Token: YOUR_TOKEN" \
  "http://127.0.0.1:8765/heart-rate/trends?start=2026-03-13&end=2026-03-19"

Example response:

{
  "ok": true,
  "success": true,
  "data": {
    "average_heart_rate": [
      { "date": "2026-03-13", "value": 72 },
      { "date": "2026-03-18", "value": 73 }
    ],
    "resting_heart_rate": [
      { "date": "2026-03-13", "value": 58 },
      { "date": "2026-03-18", "value": 58 }
    ],
    "hrv_sdnn": [
      { "date": "2026-03-13", "value": 42 },
      { "date": "2026-03-18", "value": 41 }
    ]
  }
}

Error Handling

When a request fails, the server still responds with HTTP 200 and a JSON body where ok and success are false. The human-readable message is in error; a machine-readable code is nested under errorDetail. (Genuinely malformed HTTP requests are the exception and return HTTP 400.)

{
  "ok": false,
  "success": false,
  "error": "No imported health dataset is available.",
  "errorDetail": {
    "code": "dataset_unavailable",
    "message": "No imported health dataset is available."
  }
}

Common error codes:

Code Description
unauthorized Missing or invalid X-Health-Analyzer-Token header on a protected endpoint.
dataset_unavailable The Mac app is running but no Apple Health dataset has been imported or selected for integrations.
not_found Unknown endpoint path.
method_not_allowed A non-GET method was used. The API is read-only and only supports GET.
timeout The request exceeded the server's internal processing timeout.

Rate Limits and Limitations

  • No formal rate limit -- the API runs on localhost, so there is no external throttling. However, the Mac app processes requests on its main thread, so extremely rapid polling (e.g., multiple requests per second) may cause brief UI lag.
  • Read-only -- there are no POST, PUT, PATCH, or DELETE endpoints. The API cannot modify your health data.
  • Localhost only -- the API binds to 127.0.0.1 and is not accessible from other devices on your network.
  • Mac app must be running -- the API is served by the Mac app process. If the app is closed, requests will fail with a connection refused error.
  • Data freshness -- the API reads from the app's selected integration dataset. To get updated data, import or sync newer data and select the right dataset for integrations when needed.

Use Cases

OpenClaw

Install the apple-health-export-analyzer ClawHub skill to give OpenClaw access to the /openclaw/ endpoints: /openclaw/status, /openclaw/daily-brief, /openclaw/recent-trends, and /openclaw/weekly-summary. See the OpenClaw Integration guide for setup steps and example prompts.

Claude Code

Use curl from Claude Code to read health data directly into your development workflow:

curl -s -H "X-Health-Analyzer-Token: $(cat ~/.health-analyzer/token)" \
  "http://127.0.0.1:8765/steps/daily?start=2026-03-13&end=2026-03-19" | jq .

Mac Shortcuts

Use the Get Contents of URL action in Shortcuts to call any endpoint. Pass the token in the X-Health-Analyzer-Token header and parse the JSON response to build notifications, widgets, or automations.

Custom Scripts

Any language that can make HTTP requests works with this API. Python, Node.js, shell scripts, and Swift are all supported. Example in Python:

import requests

token = open("~/.health-analyzer/token").read().strip()
resp = requests.get(
    "http://127.0.0.1:8765/steps/daily",
    params={"start": "2026-03-13", "end": "2026-03-19"},
    headers={"X-Health-Analyzer-Token": token}
)
data = resp.json()
for day in data["data"]["days"]:
    print(f"{day['date']}: {day['value']} steps")
Made by VividSites