Requirements & Limitations
Supported platforms, the conditions for a good measurement, and important limitations.
Platform requirements
iOS
| Requirement | Detail |
|---|---|
| OS | iOS 16.0+ |
| Toolchain | Swift 5.9+, distributed as a Swift Package |
| Camera | Front-facing camera |
Web
| Requirement | Detail |
|---|---|
| Browser | Recent Chrome, Edge, Firefox, or Safari |
| Context | Secure context — HTTPS or localhost (required for camera access) |
| Hardware | A webcam |
Cloud tier
| Requirement | Detail |
|---|---|
| Network | A sustained ~117 KB/s upstream for the whole measurement — a 60-second capture is roughly 7 MB |
| Transport | Outbound WebSocket (wss), or HTTPS PUT if you use batch delivery |
| Backend | A server that can HMAC-sign the session request; the secret must not be in the browser |
| Consent | consent: true on every session — see Cloud privacy |
| Third-party CDN | The browser loads @mediapipe/tasks-vision from jsDelivr — see below |
Corporate firewalls that block WebSockets, and mobile networks that cannot hold
the upstream rate, are the two common failures. delivery: 'auto' turns both
into a slower measurement rather than a failed one — see
Cloud overview.
The face tracker comes from jsDelivr
Face detection runs in the browser in both tiers, and the tracker it uses —
Google's @mediapipe/tasks-vision — is loaded from
https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.21/, not from our
domain. This is the one third-party origin the SDK touches; everything else (the
model files, the ONNX and LiteRT runtimes, the engine itself) is served from
neccessory.com.
Two consequences worth knowing before you ship:
- A locked-down network must allow
cdn.jsdelivr.net. Blocked, the measurement fails while loading models. - A page with a Content-Security-Policy must allow it too. Its workers are same-origin and inherit the document's policy, so a policy that omits jsDelivr kills the import with no useful error.
If you self-host the library, point mediapipeBase at your own copy — it must
serve the package's +esm entry and its wasm/ directory. See
Configuration.
A CSP that works
Merge these directives into your policy. Nothing here is optional for the cloud tier:
script-src 'self' 'wasm-unsafe-eval' https://cdn.jsdelivr.net;
connect-src 'self' https://cdn.jsdelivr.net https://neccessory.com wss://infer.neccessory.com;
worker-src 'self' blob:;
img-src 'self' blob: data:;What each line is for:
| Directive | Why |
|---|---|
script-src … cdn.jsdelivr.net | The @mediapipe/tasks-vision ES module and its wasm loader |
'wasm-unsafe-eval' | The tracker compiles WebAssembly; without it nothing starts |
connect-src … cdn.jsdelivr.net | The wasm binary is fetched, not <script>-loaded |
connect-src … neccessory.com | The two model files, and the batch-fallback endpoints |
connect-src wss://… | The streaming socket. Use the host from your session's wsUrl |
worker-src 'self' blob: | The measurement pipeline runs in workers |
img-src blob: data: | Preview and overlay rendering |
Substitute your own host for neccessory.com if you were given a dedicated one,
and drop the wss:// entry if you only use batch delivery. Our own console runs
the same script-src, worker-src and jsDelivr connect-src in production,
which is how the list stays honest.
Do not put a CSP on the engine's own assets
This policy belongs on your page. If you proxy our assets and add a strict policy to the responses themselves, the engine's workers pick it up from their own script response and initialization hangs — silently, with no error and no event. Serve the engine assets without a CSP header.
Conditions for a good measurement
Measuring a pulse from a camera is a signal-recovery problem, so measurement quality depends on the capture conditions. For the best results, guide the user to:
- Sit still. Head motion is the single biggest source of error — the SDK discards frames with too much motion.
- Use even, adequate lighting. Avoid strong backlight, flickering light sources, and deep shadow on one side of the face.
- Fill the frame appropriately. Not too far away (face too small) and not too close.
- Keep the face unobstructed. Hair over the forehead, thick glasses frames, or masks reduce the usable signal.
- Hold for the full window. HRV, breathing, and blood pressure need many clean beats — HRV typically needs ~15 s of clean signal before a first estimate; a full measurement runs roughly 30–35 s.
The SDK surfaces the current signal quality in real time, so you can prompt the user to fix the problem while they measure.
Known limitations
- Blood pressure and SpO2 are experimental estimates, not replacements for a cuff or oximeter. Treat them as coarse wellness indicators only.
- HRV over a camera is inherently noisier than an ECG or chest strap and may be unavailable in a short or noisy session.
- Skin tone, camera sensor, and white balance all affect the color signal. Quality gating and confidence compensate, but extreme conditions still reduce accuracy.
- Movement, talking, and facial expressions during capture corrupt the pulse signal.
Medical & regulatory disclaimer
Not a medical device
neccessory is intended for wellness and informational purposes only. It is not a medical device and has not been cleared or approved by any regulatory authority. Its outputs — including heart rate, HRV, breathing rate, stress, blood pressure, and SpO2 — must not be used to diagnose, treat, cure, monitor, or prevent any disease or medical condition. Users with health concerns should consult a qualified healthcare professional. See the full disclaimer.
Next: Getting started.