Collector API

The collector exports four functions. With npm, import them from @octetproof/collector. With the script tag, they are properties of the global octet.

import { start, ready, settled, verify } from '@octetproof/collector';

start(config)

start(config: CollectorConfig): void

Begins a collection in the background and returns at once. Call it at page load. Calling start() again replaces the configuration, discards any stored result, and begins a new collection.

Throws at once if config.challenge is missing, if config.apiUrl is not a valid https:// URL, or if config.mode is not 'full', 'lite' or 'passive'. See CollectorConfig.

ready()

ready(): Promise<ReadyResult>

Resolves once your edge has passed the latest collection to Octet, which means your backend can fetch the verdict. Call it at the moment of action.

  • If the collection that start() began is still running, ready() waits for it.
  • If that collection finished less than 90 seconds ago, ready() resolves at once with its result.
  • Otherwise, ready() needs a new collection. The challenge from start() has already been sent, so ready() rejects with octet: this challenge was already used. Get a new challenge from your backend and call start() with it.

With the early verdict, ready() resolves once the first of the collection's two reports is in, and your backend can fetch the provisional verdict. Call settled() before the page navigates away.

Rejects if start() was never called, if the POST to your edge fails, or if the collection was aborted. A failed collection is not stored. If the collection finished, its challenge counts as used, even if the POST never started, so call start() with a new challenge before the next ready().

settled()

settled(): Promise<void>

Resolves once the collector has finished sending the latest collection, whether it succeeded or failed, or at once if it already finished. It carries no result and starts nothing. Using it is optional. If your page navigates away soon after a collection, for example when the login form submits, await settled() first so the browser doesn't cancel a report still on its way. It matters most for a license with the early verdict, where the second report is sent after ready() resolves. Since v1.9.1.

Rejects with octet: call start() before settled() if start() was never called. verify() resolves after everything is sent, so it doesn't need settled().

verify(config)

verify(config: CollectorConfig): Promise<EdgeReply>

Runs one collection and resolves with your edge's reply. With the early verdict, it resolves after both reports. It stores nothing, so each call collects again and needs a new challenge. Use it where there is no separate moment of action. It rejects at once for a missing challenge or an invalid apiUrl or mode, and later if the challenge was already used, if the POST to your edge fails, or if the collection is aborted.

CollectorConfig

Field Type Required Description
apiUrl string Yes Your edge's origin, for example https://octet.example.com. Must be https://. http:// is accepted only for localhost, 127.0.0.1 and [::1].
sessionRef string Yes The unguessable reference your backend created for this page view. Your backend fetches the verdict with it.
challenge string Yes The one-time challenge your backend got from Octet for this sessionRef with POST /v1/challenge. Each challenge works for one collection, within 10 minutes. See Get a challenge.
mode 'full' \| 'lite' \| 'passive' No How much network measurement to do. The default is 'full'. See Modes.
wsUrl string No The WebSocket URL for your edge. The default is apiUrl with https replaced by wss, plus /v1/ws. Set it only if your edge's WebSocket has a different address.
signal AbortSignal No Cancels the collection. See Cancelling.
cspNonce string No Your page's CSP nonce, if your script-src uses one. Base64 or base64url characters, at most 256. Without it, or if the value isn't valid, the collector uses the nonce of a script already on the page. Since v1.8.0. See Network and CSP.

Modes

Mode What it does Network requests beyond your edge
full Everything, for the strongest results HTTPS and UDP 3478 to three Octet network hosts
lite Skips the HTTPS requests to the Octet network hosts UDP 3478 to three Octet network hosts
passive No network measurement and no WebRTC None

No mode shows a permission prompt. The hosts are listed in Network and CSP.

ReadyResult

Field Type Description
response EdgeReply Your edge's reply to the POST.
issuedAtMs number When the edge replied, in milliseconds since the Unix epoch.
expiresAtMs number When ready() stops reusing this result, in milliseconds since the Unix epoch. issuedAtMs plus 90 seconds.
elapsedMs number Milliseconds from the start of collection to the edge's reply.

EdgeReply

In production your edge always replies with:

{ "ok": true }

The reply never contains the verdict. Your backend fetches it. See Fetch the Verdict. Only the testing setting EDGE_EXPOSE_VERDICT changes this reply. See Edge Configuration.

Cancelling

Pass an AbortSignal in the configuration. Aborting stops the collection and cancels the POST to your edge if it has started. ready() or verify() then rejects with the signal's abort reason, which is a DOMException named AbortError unless you pass your own reason to abort(). If the abort comes before the POST reaches your edge, no verdict is produced for that collection.

const controller = new AbortController();
octet.start({ apiUrl: 'https://octet.example.com', sessionRef, challenge, signal: controller.signal });
window.addEventListener('pagehide', () => controller.abort());

Errors

Thrown or rejected with When
Error: octet: `challenge` is required. … challenge is missing or empty. Thrown by start(), rejected by verify().
Error: octet: this challenge was already used. … The collector already sent this challenge. Rejected by ready() or verify(). Get a new challenge and call start() or verify() with it.
Error: octet: invalid apiUrl "…" apiUrl is not a URL. Thrown by start(), rejected by verify().
Error: octet: apiUrl must be https://… apiUrl uses another scheme. Thrown by start(), rejected by verify().
Error: octet: unknown mode "…" mode is not 'full', 'lite' or 'passive'. Thrown by start(), rejected by verify().
Error: octet: the collector needs a secure context (https) for crypto.subtle The page isn't served over HTTPS or from localhost, 127.0.0.1 or [::1].
Error: octet: call start() before ready() ready() was called before start().
Error: octet: call start() before settled() settled() was called before start().
Error: signal report failed: <status> Your edge answered the POST with an error status. See Errors.
TypeError from fetch The POST to your edge failed at the network level, for example because of CORS or DNS.
DOMException named AbortError, or your own abort reason The collection was aborted.

A measurement that fails or is blocked never causes an error. The collector leaves it out and sends the rest.

TermsPrivacy© 2026 Understone, Inc. d/b/a Octet