Frequently asked questions

The questions that come back most often when a team is deciding whether Saphere fits, and where the full answer lives.

What does Saphere measure, and from what?

A person’s face, filmed for about thirty seconds. From the light their skin reflects, Saphere rebuilds a pulse signal, and derives up to ten variables from it: heart rate, breathing rate, variability, stress, blood pressure, visual age, body mass index and a combined cardiovascular score. The full list, with what each one depends on, is on what is measured.

What are the ways to take a measurement?

Three. Saphere Scan runs a live, guided measurement in a browser or a WebView and hands you a result. The API takes a file you already recorded, a video or a set of images, and returns the same kind of result without any widget. Realtime, in alpha, measures a video source you already own while it plays, and hands back values as they come rather than a stored result. The first two share the same backend; teams that need several use several.

How long must a video be?

Thirty seconds, the length of a capture by the widget. A file under 10 seconds is refused, and only about the first 30 seconds are read, whatever the length of the file. Conditions for a good measurement lists the other requirements.

Do I need a server of my own?

For anything that reaches production, yes — a small endpoint that mints an access token for each measurement. The reason is not the widget’s convenience but yours: your API key opens every route of your account and has no expiry, so it must never reach a browser. The widget asks your endpoint for a short-lived, single-use token instead. Access tokens covers the three ways to wire it, including the one meant only for trials.

Where do I find my API key?

In the console, per environment. A Test key and a Production key are different keys and are not interchangeable — see environments.

Can I change the widget’s colours and screens?

Yes, both. You prepare them in the ops console, in the customisation workshop, and attach the result to the widget by its identifier. Nothing is copied into your code, and a change needs no deployment on your side. Customisation explains how.

Which languages does it speak?

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

Does it work inside a mobile app?

Yes, in a WebView — React Native, Ionic/Capacitor, or a native shell. The camera permission has to be granted by the host application, which is the step most integrations miss first. WebView integration has the per-platform details.

Why did a measurement come back with no variables?

Almost always an entitlement rather than a failure: the variables an account may receive are configured on the account, and a freshly created test client has been granted none. A result with a quality score and an empty returnedVariables is that signature.

Why did one variable fail while the rest succeeded?

Because it needed something it did not have — height and weight for body mass index, the demographic fields for the blood-pressure risk and the cardiovascular score, an externalId and a calibration for blood pressure. That variable comes back carrying an error code naming what was missing; the rest of the measurement is unaffected. What is measured lists what each one needs.

What conditions does a good measurement need?

Light on the face, a still person, an uncovered face, and correct framing at 40 to 60 cm with the upper chest visible. Conditions for a good measurement explains why each one is not negotiable and how the widget guides a person into position.

What happens after I upload a video?

The server processes it and returns the variables your account is entitled to, each with its value or the code saying why it could not be produced. Two routes exist: a single call that carries the file and the options together, or a two-step flow that creates the measurement first and uploads the file second. Both are on the measurements page.

Which video formats are supported?

.mp4, .avi, .mov and .webm, up to 100 MB, at 13 to 35 images per second. Only about the first 30 seconds are read.

How does the credit system work?

Each variable a measurement successfully computes consumes credits — the cost of that variable, as configured on your account. A measurement that returns four variables therefore costs the sum of those four, and a variable that could not be computed costs nothing. Credits are counted per calendar month: a fresh allowance each month, and what was not spent does not carry over.

What happens when credits run out?

A measurement still runs, but it is not charged and returns no value: each of its variables comes back with the code CREDIT_EXCEEDED, and the widget shows a message saying so rather than failing silently. That lasts until the next month’s allowance, or until the allowance is raised. If you expect a peak, ask for it to be raised before it rather than after.

Why did my measurement fail?

Where it failed tells you most of it.

When the measurement opens — the session could not be opened. Either your endpoint did not return a usable token, which token:error reports within seconds; or the server refused the token — already used, expired, minted for the other chain or for an inactive account. A refused token does not end the measurement at once: the widget keeps trying to connect, which transport:reconnecting reports attempt by attempt, and the measurement ends with WS_RESULT_TIMEOUT once its result delay has run out, about ten minutes after the capture.

During the capture — the session was interrupted:

  • the camera became unavailable — another application took it, or the permission was revoked;
  • the network did not let the images through;
  • the person cancelled.

After the capture — the measurement ended, but the conditions were not met. It still arrives as a result, and each variable it could not compute carries a code naming the reason:

  • no face found, or the face left the frame;
  • lighting too dim, too harsh, or backlit;
  • too much movement during the capture.

Conditions for a good measurement covers the ones that depend on the environment, code by code.

How do I debug a failed measurement?

Listen to the event stream. measure:aborted carries the reason the measurement was stopped on purpose, measure:failed the reason the system could not complete it, and each carries a code rather than a message — codes do not change with the display language. A measurement that ended in poor conditions is not among them: it arrives as measure:result, with a code on each variable it could not compute. The full list is in events.

How does Saphere protect personal data?

Processing is limited to producing the vital-sign indicators the measurement is for. Unless your account is set to keep them, the captured images are held only for as long as the computation needs them, and a measurement can be deleted through the API — which removes the stored objects as well as the record, in that order, so that no capture survives the record that addresses it.

Where is the data hosted?

In France, with OVHcloud. Everything that travels between the device and the platform is encrypted, and the connection to the database is authenticated as well as encrypted.

How can I send feedback or report a problem?

By email, at issue@i-virtual.ai. Include the measurement identifier if there is one — it is what lets the problem be traced.

Is there a way to try it before integrating?

Yes — the widget can be pointed straight at the API with your key, with no endpoint of your own, for exactly that purpose. It is named unsafe-api-key because that is what it is: it puts a permanent key in a page. Use it for a trial and never for production.