NeccessoryNeccessory
Web SDK

Configuration

The small set of public options for the Web SDK.

The Web SDK keeps configuration deliberately small. You provide the elements to render into, pick a tier with mode, and pass whatever authorizes that tier — a model grant for on-device, or a session object for cloud. Everything about the measurement pipeline itself is handled internally and is not configurable in either tier.

Shared options

These apply in both modes and all go to createMeasurement:

OptionDefaultMeaning
videoEl—The <video> element the camera is attached to. Required.
previewEl—Canvas for the camera preview. Omit to render nothing.
overlayEl—Canvas for the face-tracking overlay. Omit to render nothing.
mode'on-device''on-device' or 'cloud'. Everything downstream is identical.
assetOriginhttps://neccessory.comWhere our assets are served from. Pass it only if you were given a dedicated host.

On-device options

const m = createMeasurement({
  videoEl: document.getElementById('cam'),
  previewEl: document.getElementById('preview'),
  overlayEl: document.getElementById('overlay'),
  mode: 'on-device',
  modelGrant,
});

m.init({ keyId: 'nk_live_sRwG9z2hK2hdV4Il83J7Cw', secret: '…' });
OptionDefaultMeaning
modelGrant—Short-lived grant from POST /sdk/v1/models/grant, minted by your backend with your key secret. Without it the browser cannot fetch the model key.
init fieldMeaning
keyIdYour public key id. Stamped onto the result the SDK derives locally.
secretYour key secret. Required only if you call submit() from the browser.

Cloud options

const m = createMeasurement({
  videoEl: document.getElementById('cam'),
  mode: 'cloud',
  session,              // the whole `data` from POST /sdk/v1/cloud/sessions
  delivery: 'auto',
});
OptionDefaultMeaning
session—The whole data object from POST /sdk/v1/cloud/sessions. Carries sessionToken, sessionId, wsUrl, maxDurationSec and frameSpec at once. This is the option you normally use.
sessionTokenfrom sessionThe token on its own. Overrides session.sessionToken.
sessionIdfrom session, else the token's sid claimAddresses the session on the batch-fallback endpoints.
wsUrlfrom sessionWhere to stream. Not recoverable from the token: without it, anything but delivery: 'batch' fails with no_ws_url.
delivery'auto''stream', 'batch' or 'auto' — see below.
aux'buffer'The optional 448×448 crop: 'stream' sends it live, 'buffer' keeps it locally and includes it only if the measurement falls back to a batch upload, 'off' never captures it.
maxDurationSecfrom session, else the token's dur claim, else 60Caps capture length and sizes the local fallback buffer.
apiOriginhttps://neccessory.comWhere the batch-fallback endpoints live.
mediapipeBasejsDelivr — see RequirementsWhere @mediapipe/tasks-vision and its wasm are loaded from.
modelBasePathassetOrigin + /mediapipe/Where the two face-tracking model files are served from.

Credentials do not go through `init` in cloud mode

There is no init({ keyId, secret }) in the cloud tier, and there must not be: the session token is the authorization, your backend minted it with the secret, and the secret never reaches the page. Nor is there anything to submit() — the inference service stores the measurement before you see it. init exists for the on-device tier, where the result is computed in the browser and has to be sent somewhere.

delivery

ValueBehaviour
'stream'WebSocket only. Live metrics. A dropped socket loses the measurement.
'batch'No socket at all: frames are buffered locally and uploaded at the end. No live metrics, and wsUrl is not needed.
'auto'Streams and keeps the local buffer. If the socket never opens or dies mid-capture, the buffer is uploaded and the measurement still produces a result.

With auto the live metrics stop the moment the fallback kicks in, so drive your UI from onStage — you get 'uploading' and then 'processing' instead of a frozen pulse. See Cloud overview.

The camera

The SDK opens the front camera itself when you call start() and releases it on stop(). There is no option to feed frames from your own stream: the frame rate, resolution and timing of the capture directly determine signal quality, so the SDK controls them.

If you need the video for your own UI, read it from the same videoEl — the SDK attaches the stream there and does not clear it until stop().

Keeping the secret safe (on-device)

The secret is reachable by anyone who can inspect your page. If that is unacceptable, call init({ keyId }) without a secret, run the measurement in the browser, and submit the result from your own backend so the secret stays server-side. See Authentication. The cloud tier sidesteps the question entirely — there is no secret in the page to protect.

Next: Browser support & performance.