The challenge
Research teams can learn a great deal from the devices participants already wear. The hard part is getting that data out of a consumer app and into a research system in a form study teams and monitors can rely on. Each wearable provider has its own authorisation flow, data format and rate limits, and OAuth tokens expire, so a connection that worked on day one can quietly stop delivering data.
Volume and timing add to the problem. Webhooks arrive whenever a provider sends them, and data for the same day can arrive more than once as it is updated. If that processing runs inside the web application, a burst of incoming data slows the screens participants use to connect their devices. And a research system such as REDCap needs one clean record per subject per day, not a stream of partial updates.
- Onboarding participants’ devices without a fragile, manual setup
- Keeping OAuth tokens valid so data keeps flowing
- Absorbing webhook bursts and provider rate limits without slowing the app
- Delivering consolidated daily metrics into REDCap Cloud, with a trail monitors can review
What I built
I designed and built NPhase Health as a Flask application with a clear split between what participants see and the heavy work behind it. Device onboarding runs through the Terra API, which handles connections to providers such as Fitbit and Strava through secure widget sessions. Because a lost token means lost data, I built OAuth token refresh to recover on its own rather than wait for someone to notice a gap in the record.
Data arrives by webhook and is normalised into PostgreSQL, so readings from different devices land in one consistent shape. Celery and Redis take the heavy sync and stream processing off the Flask application thread. That keeps the participant-facing side responsive, lets work fan out asynchronously, and allows calls to be paced to stay within each provider’s rate limits.
On the research side, schedulers push consolidated metrics to REDCap Cloud (RCC) at configurable intervals. The merge logic is UPSERT-friendly: activity and sleep data for each subject and day is merged into a single record, so a late or repeated update corrects that record instead of creating a duplicate. Monitors can pull CSV exports for review, and audit logs record webhook and API activity, so there is a record of what arrived and what was sent.
Participants link their devices through a responsive, glass-style device-connect screen, which sits on the fast path while the heavy processing stays in the background.
- Terra-backed onboarding with resilient OAuth token refresh
- Webhook ingestion into normalised PostgreSQL storage
- Celery and Redis for async sync and stream processing, isolated from Flask
- Scheduled REDCap Cloud sync with UPSERT-friendly daily merges
- CSV exports for monitors and audit logs for webhook and API activity
- Design tuned for provider rate limits and async fan-out
Architecture and stack
- Application
- Python · Flask
- Data
- PostgreSQL · Redis
- Background processing
- Celery · Schedulers
- Integrations
- Terra API · Fitbit · Strava · Webhooks · OAuth · REDCap Cloud (RCC)
- Reporting & audit
- CSV exports · Audit logs
Outcome
NPhase Health turns consumer wearable data into something a research team can use: consolidated daily metrics in REDCap Cloud, CSV exports for monitors, and audit logs showing what arrived and what was sent.
Separating ingestion and sync from the web application means bursts of webhook traffic and provider rate limits are handled in the background rather than slowing participants down, and automatic token refresh keeps device connections alive. UPSERT-based daily merges keep the REDCap data free of duplicates when providers resend or update data.
The same design applies to most health-data and device integrations I work on: treat every third-party connection as fragile, process data asynchronously, make writes safe to repeat, and keep a trail of every exchange so questions about the data can be answered later.
Last updated 2026-10-03
