v1.0 — OEM SDK

ReflectOS Developer Docs

Integrate AI health scanning into your mirror firmware in under 15 minutes. This guide covers the full integration surface — auth, data schema, webhooks, and hardware requirements.

Quick Start

The SDK runs on-device and communicates with ReflectOS over HTTPS. You trigger a scan from your UI, receive results via callback or webhook.

1

Install the SDK

npm install @reflectos/oem-sdk
2

Initialize with your credentials

const { ReflectOS } = require('@reflectos/oem-sdk');

const mirror = new ReflectOS({
  apiKey: process.env.REFLECTOS_API_KEY,
  deviceId: 'your-mirror-serial',
  region: 'us-east-1' // or 'eu-west-1'
});

mirror.on('scanComplete', (results) => {
  console.log(results.vitals.heartRate); // e.g. 67
});
3

Trigger a 30-second scan

// User faces the mirror for 30 seconds.
// SDK handles camera capture, processing, and result delivery.

mirror.startScan({ durationMs: 30000 })
  .then(sessionId => console.log('Scan started:', sessionId))
  .catch(err => console.error('Camera unavailable:', err));
Tip: The scan requires ambient infrared or visible light. Mirrors in dark bathrooms need a brief illumination pulse — the SDK handles this automatically, or you can trigger it manually with mirror.enableIllumination(true).

Authentication

All API calls use a long-lived API key per device, plus a short-lived session token for scan submissions.

Step 1 — Provision a device

Call the ReflectOS provisioning endpoint once per device at first boot. It returns a device key stored securely on-device.

POST https://api.reflectos.ai/v1/devices/provision
Authorization: Bearer {OEM_API_KEY}
Content-Type: application/json

{
  "serial": "MIR-2024-ABC123",
  "model": "X1-Pro",
  "firmwareVersion": "2.4.1"
}

Response: { "deviceKey": "...", "deviceId": "dev_abc123" }

Step 2 — Scan session token

Before each scan, exchange the device key for a short-lived session token (TTL: 5 minutes).

POST https://api.reflectos.ai/v1/auth/session
Authorization: Device {DEVICE_KEY}

→ { "token": "tok_abc123", "expiresAt": "2026-06-12T12:05:00Z" }
Security: Device keys are device-specific and non-transferable. If a key is compromised, call DELETE /v1/devices/{id} to revoke immediately.

Vitals Data Schema

Scan results are returned as a JSON object conforming to the ReflectOS Health Schema (FHIR R4 compatible).

{
  "sessionId": "sess_abc123",
  "timestamp": "2026-06-12T06:45:00Z",
  "duration": 30000,
  "vitals": {
    "heartRate": {
      "value": 67,
      "unit": "bpm",
      "range": { "low": 60, "high": 100 },
      "status": "normal"
    },
    "bloodPressure": {
      "systolic": 118,
      "diastolic": 76,
      "unit": "mmHg",
      "status": "normal"
    },
    "hrv": {
      "value": 54,
      "unit": "ms",
      "range": { "low": 20, "high": 70 },
      "status": "normal"
    },
    "respiratoryRate": {
      "value": 14,
      "unit": "brpm",
      "range": { "low": 12, "high": 20 },
      "status": "normal"
    },
    "stressIndex": {
      "value": 42,
      "unit": "index",
      "range": { "low": 0, "high": 100 },
      "status": "low"   // low | moderate | elevated
    },
    "oxygenSaturation": {
      "value": 98,
      "unit": "%",
      "range": { "low": 95, "high": 100 },
      "status": "normal"
    }
  },
  "scanQuality": {
    "signalStrength": "strong",   // weak | moderate | strong
    "motionDetected": false,
    "confidenceScore": 0.94       // 0–1, exclude readings below 0.7
  }
}

Field definitions

FieldTypeDescription
sessionIdstringUnique scan session ID
durationintegerScan duration in ms (default 30000)
vitals.*.valuenumberMeasured value
vitals.*.statusstringnormal / elevated / critical
scanQuality.confidenceScorefloat0–1. Reject readings < 0.7
scanQuality.motionDetectedbooleanTrue = results may be unreliable

Webhooks

Register a webhook URL in the dashboard or via API to receive real-time scan events. Useful for syncing to your cloud backend or triggering downstream workflows.

Register a webhook

POST https://api.reflectos.ai/v1/webhooks
Authorization: Bearer {OEM_API_KEY}
Content-Type: application/json

{
  "url": "https://your-backend.example.com/reflectos-webhook",
  "events": ["scan.complete", "scan.low_quality", "device.offline"],
  "secret": "wh_secret_abc123"   // sign requests with HMAC-SHA256
}

Event payloads

scan.complete Fired when a scan finishes with high confidence
{
  "event": "scan.complete",
  "deviceId": "dev_abc123",
  "sessionId": "sess_xyz789",
  "timestamp": "2026-06-12T06:45:00Z",
  "vitals": { ... }
}
scan.low_quality Fired when confidence score is below 0.7
{
  "event": "scan.low_quality",
  "deviceId": "dev_abc123",
  "sessionId": "sess_xyz789",
  "timestamp": "2026-06-12T06:45:00Z",
  "reason": "motion_detected",
  "retryRecommended": true
}
device.offline Device hasn't connected in 48 hours
{
  "event": "device.offline",
  "deviceId": "dev_abc123",
  "lastSeen": "2026-06-10T06:45:00Z"
}

Verifying webhook signatures

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

Supported Hardware Specs

The SDK supports Android-based smart mirrors. iOS/macOS and bare-metal Linux are on the roadmap.

CPU

ARM64 (AArch64) or x86_64. Minimum Snapdragon 845 (or equivalent). The model runs entirely on-device — no cloud compute required for scan processing.

RAM

Minimum 4 GB. The SDK model occupies ~1.2 GB during active scanning; free RAM must exceed this during scan windows.

Camera

Minimum 1080p @ 30fps. Focal length 28–35mm equivalent. Infrared sensitivity preferred for low-light operation. SDK requires at least 25fps for stable signal extraction.

Lighting

Standard ambient room light (100+ lux). For dark bathrooms, the mirror must support a brief NIR pulse — the SDK triggers mirror.enableIllumination(true) if configured.

OS & Connectivity

Android 10+ (API 29+). Requires HTTPS outbound on port 443 to api.reflectos.ai. Local network permission required for device provisioning. No inbound ports needed.

Storage

SDK bundle: ~180 MB. No scan data stored locally by default. All vitals transmitted to your webhook endpoint; optionally cache locally with mirror.enableLocalCache(true).

Not on this list? If your hardware doesn't meet these specs, contact our OEM team — we work with some custom silicon configurations on a case-by-case basis.