Skip to content

Features and Modes

Eric Slutz edited this page Aug 12, 2026 · 8 revisions

Features and Modes

PumpSync has one iOS app and one backend API that supports hosted service, real self-hosting, and synthetic demo/App Review flows.

iOS App Features

  • Stores Tandem Source credentials in the device Keychain with device-only accessibility.
  • Validates Tandem credentials through the configured backend.
  • Writes Tandem insulin and carbohydrate samples to Apple Health after the user grants HealthKit permission.
  • Uses local sync metadata and a rolling external-ID ledger to avoid duplicate Apple Health samples.
  • Lets users choose PumpSync through StoreKit or enter a self-hosted backend URL.
  • Provides settings, sync, privacy/data handling, diagnostics, and support surfaces.
  • Lets users start a sync manually at any time.
  • Refreshes automatically when the app opens after initial setup and uses iOS background refresh opportunities to target data that is less than four hours old. iOS controls when background work runs, so the app also provides a manual sync action and shows the last successful sync time.
  • Supports App Intents shortcuts for PumpSync flows.

PumpSync does not read unrelated Apple Health data and does not use HealthKit data for advertising, marketing, or data mining.

Access Modes

Mode User experience Backend behavior Storage
PumpSync User subscribes or restores the PumpSync auto-renewable subscription in the iOS app. Backend validates the signed App Store transaction and issues a short-lived PumpSync service token. Azure Table Storage for hosted operational state.
Self-hosted User enters their own backend base URL in app settings. Backend deployed in SelfHosted mode issues a service token without App Store subscription verification. SQLite by default.
Synthetic demo/App Review User enters the public demo backend URL and demo Tandem credentials. Backend runs SelfHosted + SyntheticDemo; no Tandem network calls are made. SQLite by default.

Sign in with Apple is intentionally not part of the current access flow.

Service tokens are 12-hour JWTs stored in the device Keychain; the app silently creates a new session when one expires. Rotating a self-hosted backend's signing key therefore invalidates outstanding sessions only until the app next reconnects.

The backend reports its data source on the wire — capabilities and session responses carry dataSourceMode (tandemSource or syntheticDemo) — and the app labels a demo backend's connection status accordingly, so synthetic data cannot silently masquerade as pump data.

Backend Modes

The backend uses ASP.NET Core configuration binding. Environment variables use double underscores.

Mode PumpSync__BackendMode PumpSync__DataSourceMode PumpSync__StorageProvider
Hosted service Hosted TandemSource AzureTableStorage
Real self-hosting SelfHosted TandemSource Sqlite
Demo/App Review SelfHosted SyntheticDemo Sqlite

The same API, contracts, services, and normalization code are used in all three modes.

Route Contract

Hosted, demo, and self-host app-entered URLs include /api. PumpSync appends /v1/... endpoint paths, so the backend exposes API routes under /api/v1/....

Main routes:

  • GET /api/v1/capabilities
  • POST /api/v1/subscription/session
  • POST /api/v1/self-host/session
  • POST /api/v1/app-store/notifications
  • GET /api/v1/status
  • POST /api/v1/tandem/credentials/validate
  • POST /api/v1/sync/tandem

status, tandem/credentials/validate, and sync/tandem require the bearer token returned by subscription/session or self-host/session.

Data Handling

The Privacy Policy is the canonical statement of what is handled, stored, and retained. Implementation notes:

  • Credential-bearing requests are limited to the validate and sync endpoints; nothing credential-bearing is written to durable storage.
  • The iOS app discards raw and normalized Tandem payloads after Apple Health confirms the write.
  • Hosted and self-host deployments persist the same operational tables; self-host uses SQLite in the configured database.
  • Sync attempts and rate-limit buckets accumulate until a data-deletion request removes the user's rows; there is no automatic time-based cleanup.

Clone this wiki locally