NeccessoryNeccessory

Requirements & Limitations

Supported platforms, the conditions for a good measurement, and important limitations.

Platform requirements

iOS

RequirementDetail
OSiOS 16.0+
ToolchainSwift 5.9+, distributed as a Swift Package
CameraFront-facing camera

Web

RequirementDetail
BrowserRecent Chrome, Edge, Firefox, or Safari
ContextSecure context — HTTPS or localhost (required for camera access)
HardwareA webcam

Cloud tier

RequirementDetail
NetworkA sustained ~117 KB/s upstream for the whole measurement — a 60-second capture is roughly 7 MB
TransportOutbound WebSocket (wss), or HTTPS PUT if you use batch delivery
BackendA server that can HMAC-sign the session request; the secret must not be in the browser
Consentconsent: true on every session — see Cloud privacy
Third-party CDNThe 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:

DirectiveWhy
script-src … cdn.jsdelivr.netThe @mediapipe/tasks-vision ES module and its wasm loader
'wasm-unsafe-eval'The tracker compiles WebAssembly; without it nothing starts
connect-src … cdn.jsdelivr.netThe wasm binary is fetched, not <script>-loaded
connect-src … neccessory.comThe 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.