Summary
Syntropy Health is a patient-facing, self-hosted personal health record. A person runs it on their own computer or home server. Using the SMART App Launch standalone patient launch, it retrieves that person's own records from their healthcare organizations and stores them in a local database, where they can view trends, prepare visit summaries and export their data. There is no Syntropy-operated backend that receives patient data.
| Intended users | Patients and caregivers (parents, or adult children managing a parent's records with proxy access). |
|---|---|
| Launch type | Standalone patient launch, public client, authorization code with PKCE (S256). |
| Ongoing access | offline_access where the server supports it. On Epic, each instance registers its own signing key (dynamic client registration) and renews access with a signed JWT assertion. |
| FHIR version | R4 (US Core / USCDI). |
| Access | Read-only, per-resource patient/*.read scopes, trimmed to what each server supports. |
| Redirect URI | https://health.syntropylabs.io/callback |
Architecture
Patient portal (Epic, Oracle Health, athenahealth, ...)
| OAuth 2.0 authorization code (+ PKCE), TLS
v
health.syntropylabs.io/callback static page, runs in the browser only
| browser navigation to the instance named in "state"
v
Your Syntropy Health instance localhost, home network or Tailscale
| token exchange with PKCE verifier, FHIR R4 API calls (TLS)
v
Local database records, normalized trends, encrypted tokens
The callback page
OAuth requires a fixed HTTPS redirect URI, but every Syntropy Health instance has its own private address. The callback page bridges that gap:
- It is a static file with a strict Content-Security-Policy. It loads nothing from anywhere and makes no network requests.
- It reads the destination from the
stateparameter and accepts only loopback, private-network, Tailscale and.localhosts, so it cannot redirect to the public internet. - The only sensitive value it handles is the one-time authorization code, which cannot be redeemed without the PKCE verifier held by the instance.
Wearable sign-in
Oura, WHOOP and Google Health (Fitbit and Pixel Watch) don't support PKCE-only public clients and require a client secret.
For these, an edge worker at syntropy-auth-relay.syntropylabs.workers.dev performs the code exchange, then hands
the tokens to your instance in the URL fragment (never sent to any server) and keeps no copy. Renewals go through the
same worker. The worker:
- has request logging turned off and is rate-limited per IP address;
- requests only sleep, activity, heart and workout scopes, not email or profile;
- never calls the wearable data APIs itself.
To keep tokens off the worker entirely, register your own Oura, WHOOP or Google developer app, enter its client ID and secret in Settings → Wearables, and set the wearable redirect URI in Settings → Developer to the one you registered. Sign-in and renewals then go straight from your instance to the provider. Google Health currently always works this way, with your own Google Cloud app.
Data handled
| Category | FHIR resources |
|---|---|
| Demographics | Patient |
| Problems, allergies | Condition, AllergyIntolerance |
| Medications | MedicationRequest, Medication |
| Results and vitals | Observation (laboratory, vital-signs, social-history), DiagnosticReport |
| Care history | Encounter, Procedure, Immunization, DocumentReference, Binary |
| Care coordination | CareTeam, CarePlan, Goal, Device, Coverage |
Security
- A password is required (scrypt). Sessions are opaque, hashed server-side, HttpOnly and SameSite, and repeated failed sign-ins are slowed down.
- A new instance can only be set up from the same computer or the home network, so no one on the internet can claim it first.
- The database and data folder are readable only by the account that runs Syntropy Health.
- OAuth tokens, signing keys and secrets are encrypted at rest with a per-instance key that never leaves the machine.
- Phones sign in with the password or a single-use code and receive individually revocable device tokens; the password is never stored on the phone.
- Every sign-in, sync and export is written to a local activity log the user can review.
- The built-in assistant is optional. Before a provider outside the user's network answers for the first time, the app asks the user to confirm that it will see their questions and the records it looks up. Connected AI apps get read-only access.
Run it yourself
curl -fsSL https://raw.githubusercontent.com/EnriqueNeyra/syntropy-health/main/scripts/install.sh | sudo sh # or, with Docker: git clone https://github.com/EnriqueNeyra/syntropy-health && cd syntropy-health && docker compose up -d
Step-by-step instructions are on the Get started page.