Add validated breath monitoring in 50 lines of code.
lungDx turns the smartphone into a passive respiratory sensor. One SDK, lab-validated metrics, no hardware, no forced manoeuvres 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 manoeuvres, no special instructions — FEV1-equivalent metrics are inferred from natural tidal breathing.
Process
Our model interprets optical, biomechanical, and physiological signals captured via the smartphone. Video frames are not retained; only derived metrics are returned to your application.
Return
You receive a structured JSON object with respiratory rate, breath capacity, peak flow, and 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
Swift SDK in private beta · Kotlin, JavaScript, React Native, and Flutter in active development
Why it works
Every claim is backed by data. Here are the four we lead with.
Validated against gold-standard spirometers
n=644 across UK and Japan cohorts. Multi-site clinical and at-home validation. ATS 2026, Poster 8774.
Read the ATS abstract →Broad device support
Built for modern smartphones across iOS and Android. Compatibility matrix published with each SDK release.
See device support →Validated across diverse cohorts
Our validation set spans age, sex, and skin tone. Demographic performance reporting forms part of every release.
Demographic reporting →Raw video never retained
Video frames are processed and discarded. Only derived metrics persist, and only if you explicitly request result sync.
Privacy architecture →Built for the apps developers actually ship
Respiratory data sits naturally inside wellness, recovery, and digital health experiences. Here is where teams are integrating today.
Respiratory wellness
Daily breathing check-ins, integrated into the morning routine users already have.
See how →Telehealth
Supportive respiratory metrics that travel with the user, ready before the consultation begins.
See how →Recovery and training
Recovery, training load, and breathing patterns, measured by the camera that is already on.
See how →Digital therapeutics
Research-grade respiratory signals, collected at home on the device the participant already owns.
See how →Workplace wellness
Population-scale respiratory wellness programmes, delivered through the phones members already carry.
See how →From zero to measurement in 5 minutes
-
1
Install the SDKOne package. No native dependencies to configure.
-
2
Initialise with your API keyOne line at app start. Keys are scoped per-environment.
-
3
Start a session30-second measurement, raw frames never retained.
-
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); }
Swift SDK in private beta · Kotlin, JavaScript, React Native, and Flutter in active development
Currently in private beta
Working with select digital health and wellness partners on the first wave of integrations.