Docs/Octet Browser/Guides/Early Verdict

Early Verdict

With the early verdict, your backend can read a provisional verdict as soon as the first part of a collection reaches Octet, and the final verdict a few seconds later. Use the provisional verdict to keep a low-risk step moving, and read the final verdict before a gated action.

The early verdict is turned on per license. To get it, ask Octet. There is no collector option for it. A license without it works as described in the rest of these docs: one report per session, and version 3 tokens.

What a provisional verdict means

A provisional verdict with alarm none means only that none of Octet's server-side checks fired. It never means the browser is clean. Its confidence is at most 0.7.

Verdict What you can do with it
Provisional Show a page or start a sign-up. Not enough on its own for a gated action, such as a first deposit, a withdrawal, or a KYC or geofencing gate. Read the final verdict first, with ?stage=final&waitMs=….
Final Your decision for that session.
Final and incomplete The last word for that session, but no stronger than a provisional verdict. The usual cause is a page that navigated away, so await settled() before navigating.

If you use Octet for geofencing, wait for the final verdict, or don't use the early verdict.

How it works

For a license with the early verdict, the collector sends each collection to your edge in two reports:

  1. ready() resolves once the first report is in. From then on, your backend can fetch the provisional verdict.
  2. The second report follows a few seconds later, and Octet then issues the final verdict.
  3. If the second report never arrives, Octet closes the session as final and incomplete 8 seconds after the first report, with the provisional verdict's values. A missing second report never makes the verdict calmer. The usual cause is a page that navigated away before the second report was sent. See Let the second report finish.

Which collector you run also matters:

  • In passive mode, a session has a single report and goes straight to a final verdict.
  • Collectors v1.6.0 to v1.8.x also send two reports for a license with the early verdict, but ready() resolves only after both, and they have no settled().
  • Collectors older than v1.6.0 send a single report.

verify() still resolves only after both reports.

Fetch the verdict

Before a gated action, fetch the final verdict with stage=final and a waitMs:

curl -s "https://geo.octetproof.com/v1/verdict/$SESSION_REF?stage=final&waitMs=5000" \
  -H "Authorization: Bearer $OCTET_READ_TOKEN"

To read the provisional verdict, use stage=provisional:

stage Returns
provisional The newest verdict for the session: the provisional verdict, or the final verdict once it exists. Read stage in the token to tell which.
final, or no stage The final verdict. While only the provisional verdict exists, Octet answers 404 with { "status": "pending" }. With a waitMs of up to 10000, Octet waits for the final verdict first, as for any verdict.
Error When
400 { "error": "stage_not_allowed" } You sent stage for a license without the early verdict.
400 { "error": "invalid_stage" } stage is not provisional or final.

The rest of the request and the responses are as in Fetch the Verdict.

Let the second report finish

The second report is sent after ready() resolves. If the page navigates away first, for example when the login form submits, the browser can cancel it, and the session closes as incomplete.

Call settled(), in collector v1.9.1 and later, before the page navigates away. It resolves once the collection has sent everything, and it doesn't reject for a failed collection. It rejects only if start() was never called:

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  try { await octet.ready(); } catch (err) { console.warn('octet', err); }
  try { await octet.settled(); } catch (err) { console.warn('octet', err); }
  form.submit();
});

The signed token

A license with the early verdict gets version 4 tokens, with typ octet-browser-verdict+jwt;v=4. They carry every version 3 claim with the same meaning, are signed with the same keys, and are checked the same way. They add three claims:

Claim Type Meaning
stage string provisional or final. In every version 4 token.
revision integer 1 or more, in every version 4 token. It counts up within one sessionRef, and a token with a higher revision replaces one with a lower revision.
incomplete boolean true when the second report never arrived. Only in a token with stage final, and absent otherwise.

A session produces one of these:

  • A provisional token, then a final one.
  • A provisional token, then a final one with incomplete true.
  • A single final token, in passive mode or from a collector older than v1.6.0.

Check stage before a gated action: a provisional token is not a final verdict. octet-verify 1.8.0 and later check version 4 tokens. See Verify the Signed Token.

Where to go next

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