Health Connect with Python on your server
Python on a server cannot read Android Health Connect directly. An Android app must upload permitted records first; Python can then read them through the HC Sync REST API using requests. The examples cover paginated records and a Flask receiver that checks webhook signatures before accepting events from the service.
Last updated: 2026-11-04. The Python example uses a 30-second request timeout. Source for the 2026 service details: HC Sync page details.
How do device access and server access differ?
Your user needs an Android app that reads permitted Health Connect data and uploads it. Choose the native Android SDK or the React Native wrapper. Installing a Python package on a cloud server does not replace that app, grant Android permissions or connect a wearable account. Your server sees only records that have already reached HC Sync.
Create a project, save its credentials, and mint user tokens on your authenticated backend. Each phone receives a token scoped to its user id. Use a stable pseudonymous id such as maya in these examples, replacing it with the id from your own login system. Keep the project secret and read key out of your mobile app and public notebooks.
How do you pull records with Python requests?
Install requests in your Python environment and set HCSYNC_READ_KEY to the project's read key. This example fixes the time range for all pages, checks HTTP errors and follows next_cursor until exhausted. Replace the dates with the interval your feature needs; to is exclusive. Reading a period before your user has uploaded data returns no records.
import os
import requests
BASE = "https://hcsync.dev"
headers = {"Authorization": "Bearer " + os.environ["HCSYNC_READ_KEY"]}
params = {"user_id": "maya", "type": "steps", "limit": 1000,
"from": "2026-10-01T00:00:00Z", "to": "2026-11-01T00:00:00Z"}
while True:
response = requests.get(BASE + "/v1/records", headers=headers, params=params, timeout=30)
response.raise_for_status()
page = response.json()
for record in page["records"]:
print(record["id"], record["start_time"], record["value"])
cursor = page.get("next_cursor")
if not cursor:
break
params["cursor"] = cursorRecords include id, type, start_time, end_time, value and source. Steps use value.count; do not assume every data type has that field. Raw steps from different apps may overlap. GET /v1/summary?user_id=maya&days=7&tz=Europe/London returns daily aggregates if you need a chart rather than individual source records. Keep user_id and the time filters unchanged while following a cursor.
How do you receive signed events with Flask?
Install Flask, save the following as receiver.py, and set HCSYNC_WEBHOOK_SECRET to your project's webhook secret. Mount it behind your own public HTTPS endpoint and configure that URL with PUT /v1/webhook. Flask's local development server is for local testing; it is not a public production webhook deployment.
import hashlib, hmac, os, re, time
from flask import Flask, request, abort
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 1_000_000
SECRET = os.environ["HCSYNC_WEBHOOK_SECRET"].encode()
def verify(ts, sig, raw):
if not re.fullmatch(r"[0-9]+", ts) or not re.fullmatch(r"[a-f0-9]{64}", sig):
return False
try:
fresh = abs(time.time() - int(ts)) <= 300
except (ValueError, OverflowError):
return False
expected = hmac.new(SECRET, ts.encode() + b"." + raw, hashlib.sha256).hexdigest()
return fresh and hmac.compare_digest(sig, expected)
@app.post("/hcsync")
def webhook():
raw = request.get_data(cache=True)
if not verify(request.headers.get("x-hcsync-timestamp", ""), request.headers.get("x-hcsync-signature", ""), raw):
abort(401)
event = request.get_json(force=True, silent=True)
if not isinstance(event, dict):
abort(400)
# Durably enqueue here; deduplicate event["id"] when present.
# Return 2xx only after your queue accepts it. Handle deletions too.
return "", 204
# Run with: flask --app receiver run --port 3000This receiver validates the timestamp and original request bytes before parsing JSON. The enqueue comment is your application integration point: replace it with durable storage before acknowledging real events. Persist event ids to deduplicate retries, and process records.deleted and user.deleted as well as records.synced. The signed test event has no event id. See the docs for the Express equivalent and retry limits.
How do you verify the full integration?
Create a free project and save the secret key, read key, webhook secret and recovery code somewhere secure. The secret key belongs on your backend. A user token authorizes writes for one user; it is not a credential for reading records. Your own authenticated endpoint must select the user id from the signed-in session rather than accepting an arbitrary id from the app.
Start with sample data to test server reads without a phone. The sample user proves that your API credentials and parsing work; it does not prove Health Connect permissions or a device integration. Next test a real Android phone, grant only the permissions your feature uses, and confirm that a source app actually wrote those records into Health Connect. An empty response can mean no source data, denied permission, an incorrect user id or a time window that misses the records.
How should you handle consent, deletion and operations?
Before uploading health data, show a separate explicit consent choice with an unticked control, your purpose, the requested data types, US storage through HC Sync, and a way to withdraw. Android permission approval alone does not explain your server processing. Match your privacy notice and Play declarations to the actual types you collect. The consent and publishing checklist gives sample copy to adapt.
Keep your own downstream storage consistent with deletion events. Deleting a user with the secret-key API removes their server records and revokes existing device tokens. Stop local sync on withdrawal as well. Reads expose current records, not a permanent history of deletions. Webhook delivery can fail, so monitor attempts in the dashboard, retain event ids for deduplication, and handle retries without duplicating side effects. The API documentation describes queue limits and replay.
What are the common integration questions?
Is there an official Health Connect Python cloud SDK?
Health Connect access runs on Android. These Python examples call the HC Sync REST API after an app uploads permitted data.
Can I use Python without an Android app?
You can test server code with sample data, but real Health Connect records require an Android app on the user’s phone.
React Native Health Connect backend · Expo Health Connect · Health Connect Python · Health Connect REST API
How do I delete a user’s data?
DELETE /v1/users/{id} removes everything for that user immediately.