Private Beta Limited cohort, applications open

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.

Validated against gold-standard spirometers
Raw video never retained
UK GDPR and HIPAA aligned
Live 30s session
14
br/min
Resp. rate
3.42
L
FEV1
412
L/min
Peak flow
Regular
Pattern
14
br/min
Resp. Rate
3.42
L
FEV1
412
L/min
Peak Flow
Regular
Pattern

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
Full quickstart →

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.

r=0.98

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 →
iOS & Android

Broad device support

Built for modern smartphones across iOS and Android. Compatibility matrix published with each SDK release.

See device support →
Inclusive

Validated across diverse cohorts

Our validation set spans age, sex, and skin tone. Demographic performance reporting forms part of every release.

Demographic reporting →
No retention

Raw video never retained

Video frames are processed and discarded. Only derived metrics persist, and only if you explicitly request result sync.

Privacy architecture →

From zero to measurement in 5 minutes

  1. 1
    Install the SDKOne package. No native dependencies to configure.
  2. 2
    Initialise with your API keyOne line at app start. Keys are scoped per-environment.
  3. 3
    Start a session30-second measurement, raw frames never retained.
  4. 4
    Read resultsTyped result object: FEV1, RR, peak flow, confidence.
Full quickstart →
// 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.

The private beta is open to a limited cohort this quarter.

If you are shipping a health or wellness app and want to add breath monitoring, tell us about it.

Apply for early access →