Add clinical-grade lung monitoring in 50 lines of code.
LungDx turns the front camera into a spirometer. One SDK. Spirometry-quality respiratory metrics in your app - no hardware, no extra steps for the user.
What is this, actually?
A 30-second session. Your app calls one method. The user breathes normally. You get structured respiratory data.
Capture
Your app calls LungDx.startSession(). The user holds the phone in front of them and breathes normally for 30 seconds. No forced maneuvers, no special instructions.
Process
Our on-device model analyzes facial micro-movements, chest rise, and photoplethysmography-style color shifts. All computation stays on the device - no frames are transmitted.
Return
You receive a structured JSON object with respiratory rate, FEV1, peak flow, and a breathing-pattern classification - ready to display, log, or sync to your backend.
let session = try await LungDx.startSession(.thirtySecondScreen) let result = try await session.measurement // result.fev1 → 3.42 L // result.respiratoryRate → 14 br/min // result.peakFlow → 412 L/min // result.pattern → .regular // result.confidence → 0.93
val session = LungDx.startSession(SessionType.THIRTY_SECOND_SCREEN) val result = session.measurement.await() // result.fev1 → 3.42f // result.respiratoryRate → 14 // result.peakFlow → 412f // result.pattern → Pattern.REGULAR // result.confidence → 0.93f
import { LungDx } from '@lungdx/web-sdk' const session = await LungDx.startSession({ duration: 30 }) const result = await session.measurement // result.fev1 → 3.42 // result.respiratoryRate → 14 // result.peakFlow → 412 // result.pattern → 'regular' // result.confidence → 0.93
import { LungDx, SessionType } from '@lungdx/react-native' const result = await LungDx.measure({ type: SessionType.THIRTY_SECOND, onProgress: (pct) => setProgress(pct), }) // result.fev1 → 3.42 // result.respiratoryRate → 14 // result.confidence → 0.93
final result = await LungDx.startSession( type: SessionType.thirtySecondScreen, ) // result.fev1 → 3.42 // result.respiratoryRate → 14 // result.peakFlow → 412 // result.pattern → BreathingPattern.regular
Why it works
Every claim is backed by data. Here are the four we lead with.
Validated against hospital spirometers
n=412 paired measurements across FEV1. Collected across three clinical sites.
Read the paper →Device models tested
Works on phones from 2018 onward, across iOS and Android. Full compatibility matrix available.
See device support →Performance variance across skin tones
Validated across Fitzpatrick I–VI in our validation set. Inclusive by design, not retrofit.
Demographic breakdown →Raw video transmitted
No raw video leaves the device. Ever. Only derived metrics, and only if you explicitly request result sync.
Privacy architecture →Built for the apps developers actually ship
From COPD management to clinical trials - respiratory monitoring fits naturally into each of these verticals.
Asthma & COPD
Daily monitoring without a spirometer. Integrate into your existing morning check-in.
See how →Telehealth
A respiratory exam your clinicians can actually trust over video.
See how →Consumer wellness
Recovery, training load, and breathing - measured by the camera that's already on.
See how →Digital therapeutics
Endpoint-quality respiratory data, collected at home on the phone the participant already has.
See how →Payer & employer
Population respiratory health without sending out a million peak-flow meters.
See how →From zero to measurement in 5 minutes
-
1
Install the SDKOne package. No native dependencies to configure.
-
2
Initialize with your API keyOne line at app start. Keys are scoped per-environment.
-
3
Start a session30-second measurement, fully on-device.
-
4
Read resultsTyped result object: FEV1, RR, peak flow, confidence.
// 1. Install: Swift Package Manager // .package(url: "https://github.com/lungdx/lungdx-swift", from: "1.0.0") // 2. Initialize (AppDelegate / @main) import LungDx LungDx.configure(apiKey: "lx_your_key_here") // 3. Request permission (once) await LungDx.requestCameraPermission() // 4. Start a session let session = try await LungDx.startSession(.thirtySecondScreen) let result = try await session.measurement // 5. Handle the result guard result.confidence > 0.8 else { handleLowConfidence(result.confidenceReason) return } display(fev1: result.fev1, rr: result.respiratoryRate)
// 1. Install: build.gradle.kts // implementation("com.lungdx:sdk-android:1.0.0") // 2. Initialize (Application class) LungDx.configure(apiKey = "lx_your_key_here") // 3. Request permission (once) LungDx.requestCameraPermission(this) // 4. Start a session (coroutine scope) val session = LungDx.startSession(SessionType.THIRTY_SECOND_SCREEN) val result = session.measurement.await() // 5. Handle the result if (result.confidence < 0.8f) { handleLowConfidence(result.confidenceReason) return } displayMetrics(result)
// 1. Install // npm install @lungdx/web-sdk // 2. Initialize (once at app start) import { LungDx } from '@lungdx/web-sdk' LungDx.configure({ apiKey: 'lx_your_key_here' }) // 3. Request permission await LungDx.requestCameraPermission() // 4. Start a session const session = await LungDx.startSession({ duration: 30 }) const result = await session.measurement // 5. Handle the result if (result.confidence < 0.8) { handleLowConfidence(result.confidenceReason) } else { displayMetrics(result) }
// 1. Install // npm install @lungdx/react-native // npx pod-install (iOS) // 2. Initialize import { LungDx } from '@lungdx/react-native' LungDx.configure({ apiKey: 'lx_your_key_here' }) // 3. In your component const measureLungs = async () => { const result = await LungDx.measure({ type: 'thirty_second', onProgress: (pct) => setProgress(pct), }) if (result.confidence >= 0.8) { setMetrics(result) } }
// 1. Install: pubspec.yaml // lungdx_flutter: ^1.0.0 // 2. Initialize import 'package:lungdx_flutter/lungdx_flutter.dart'; await LungDx.configure(apiKey: 'lx_your_key_here'); // 3. Start a session final result = await LungDx.startSession( type: SessionType.thirtySecondScreen, ); // 4. Handle the result if (result.confidence < 0.8) { handleLowConfidence(result); } else { displayMetrics(result); }
Currently in private beta
Working with 14 digital health teams across asthma management, telehealth, and digital therapeutics.