v2 Saphere Scan — one script tag, ten languages

Vital signs, from a camera.

Thirty seconds of video. No cuff, no strap, no wearable. Saphere reads the pulse in a face and turns it into the physiological data your product needs — on hardware your users already carry.

Web, iOS, Android and hybrid apps. Embeddable in a WebView.

The Saphere Scan widget explaining the measurement to a user

Output

Ten variables from one video

A single thirty-second capture yields cardiac, respiratory and morphological indicators, each returned with the signal it was derived from.

Heart rate
bpm
Breathing rate
cpm
Heart rate variability
ms
Stress level
scale
Blood pressure
mmHg
Blood pressure risk
scale
Visual age
years
Body mass index
kg/m²
BMI from face
kg/m²
Cardiovascular score
0–100

Which variables a given client receives is set on their account. Some require the user’s height, weight, age and sex.

The principle

Remote photoplethysmography, in four steps

Blood absorbs light. With every heartbeat the volume under the skin changes, and so does the colour reflected back — by an amount far too small for the eye, but not for a sensor.

An ordinary camera films the face

A front-facing phone camera or a laptop webcam. Nothing to plug in, nothing to wear, nothing to calibrate.

The skin's reflected light is isolated

A face-landmark model tracks the regions where the skin is thin and still, and the widget samples them frame by frame — never the whole image.

The pulse signal is reconstructed

Those minute colour variations, accumulated over thirty seconds, form a waveform whose rhythm is the cardiac cycle.

Variables are derived from the signal

Rate, variability, respiration and the morphological indicators are computed from the waveform. Each one comes back either with its value, or with the reason it could not be produced.

How remote photoplethysmography worksAn ordinary camera films the face; ambient light reflected by the skin varies with each heartbeat; those variations are extracted as a pulse signal, from which the vital signs are derived.An ordinary cameraLight reflected by the skinThe extracted pulse signalHeart rateBreathingStressand more

Why Saphere

Built to be embedded, not admired

One script, one call

SaphereScan.create(root, options) then bootstrap(). The widget owns its container, its camera and its shadow DOM — it cannot leak styles into your page, and your page cannot break its layout.

Yours, down to the wording

Every screen, every string, every colour is an option. Change a label, swap a palette, drop a screen from the journey entirely — without forking anything.

Ten languages, both directions

Arabic, German, English, Spanish, French, Italian, Polish, Portuguese, Brazilian Portuguese and Turkish. The layout mirrors itself for right-to-left, from the toolbar to the chevrons.

Secrets stay on your server

The widget never holds your API key. It asks your endpoint for a short-lived, single-use access token at the start of every measurement.

Honest about the camera

Five distinct refusal screens — denied, no device, in use, unsupported, aborted — each reported to your code with a stable error code, not a generic failure.

Forty lifecycle events

Every screen entered, every camera state, every transport hiccup and every measurement phase is reported to your handler. Hooks let you refuse a transition.

Integration

From nothing to a running measurement

The widget is a single ES module served from the CDN. It mounts into a div you own and takes over from there.

<div id="scan" style="height: 100dvh"></div>

<script type="module">
    // The host decides the environment: cdn.test.saphere.ai reaches Test,
    // and the widget follows it all the way to the measurement API.
    import SaphereScan from "https://cdn.saphere.ai/saphere-scan/v2/main.js"

    const instance = SaphereScan.create("#scan", {
        lang: "en",
        // The widget never holds your API key: it asks your server for a
        // short-lived token at the start of each measurement.
        proxy: {
            retrieveAccessToken: {
                strategy: "delegate",
                url: "/api/saphere-token"
            }
        },
        onEvent: event => {
            if (event.type === "measure:result")
                console.log(event.result.variables)
        }
    })

    await instance.bootstrap()
</script>

Runs where your users are

A browser, a React Native WebView, an Ionic/Capacitor shell. The widget only needs a camera and a container.

Nothing to host

The bundle, the face-detection model and the assets are all served from the CDN. You ship a script tag.

Fails in the open

A camera refusal, a token your endpoint would not issue, a network that drops — each surfaces as a named event, so your support team can read what happened.

Who it is for

Wherever a body needs measuring without touching it

Insurance

Underwriting and wellness programmes, without a clinic visit.

Telemedicine

Vitals collected before the consultation, from the patient's own device.

Corporate wellbeing

Voluntary check-ins that need no hardware to distribute.

Fitness & wellness

Recovery and stress indicators inside an app people already open.

Clinical research

Longitudinal collection at a scale hardware cannot reach.

Connected health

A vitals layer for products that have a camera and no sensor.

Public kiosks

Pharmacy and workplace terminals, contactless by construction.

Automotive & industry

Driver and operator alertness, from a camera already fitted.

Read the docs, or talk to us

The quickstart takes a working measurement end to end in about ten minutes, on the Test environment.