Sessions

The production shape. Your backend creates a session with your secret key; the browser receives only a single-use session token.

1. Server: create the session

curl -X POST https://machine.cognau.com/api/v1/session/create \
  -H "Authorization: Bearer $COGNAU_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "web",
    "clientReference": "user_4821"
  }'
{
  "success": true,
  "data": {
    "sessionId": "6a7de599a5244ea6a3e65109",
    "sessionToken": "cgn_st_…",
    "environment": "live",
    "livemode": true,
    "challengeSequence": [{ "type": "headTurn", "index": 0, "params": {} }],
    "wsEndpoint": "/api/v1/ws/session/6a7de599a5244ea6a3e65109",
    "expiresAt": 1760000000000
  }
}

clientReference

Your own identifier for whoever is being verified: a user id, an application id, an order number. It is opaque to us, never parsed and never matched across accounts, and it comes back on the webhook. Without it you must store our sessionId at create time to know whose result arrived later.

Other options

Field Effect
riskHint low shortens the sequence to 3 challenges; anything else uses 4
simulate sandbox only: pass or fail, chooses the fake verdict
enablePersonId opt-in re-recognition; requires you to have collected consent
deviceId your own device identifier, if you have one
trainingConsent the user agreed their video may be retained for training
POST/session/createcreates a sandbox session with a test key

Kept in this page only. Never stored, never sent anywhere but the API.

2. Browser: run the check

Hand the session to the widget. Two shapes, both ending in the same place.

Let the widget fetch it. Give it your own route and it POSTs there when it is ready, which keeps the session from being created until someone actually reaches the step:

<script src="https://verify.cognau.com/embed.js"></script>
<script>
  const v = Cognau.open({
    sessionEndpoint: '/api/start-verification',
    onVerdict: r => { v.close(); showPending(); },
  });
</script>

Your route just proxies POST /session/create with your secret key. Return our response verbatim if you like: the widget accepts the raw session or the { success, data } envelope.

Or hand it over yourself, if you already created the session:

const session = await fetch('/api/start-verification', { method: 'POST' })
  .then(r => r.json());

const v = Cognau.open({ session, onVerdict: r => { v.close(); showPending(); } });

Pass the whole session object, not just the token: a session that also collects a document carries a second credential the widget needs.

Whichever you use, the token is delivered to the iframe over postMessage after it signals readiness, never as a query parameter. A session token in a URL would land in browser history, in the Referer of anything the page loads next, and in the access log of whatever served it.

There is no publishable key to add. Nothing account-level goes to the browser; the session token is the only credential your page holds. See Authentication.

More on mounting, sizing and events: Embedding.

The optional document check

A session can also collect an identity document. It is a separate check, switched on per account, and it is metered separately from liveness, so a session that runs both is billed for both. A composite session reaches the document step only if liveness passes.

Be precise about what it does, because the name invites the wrong assumption.

It does It does not
Store the submitted image, encrypted Read anything printed on it
Check the sides submitted match the declared type Parse an MRZ or run OCR
Judge blur, glare, resolution and framing Check an expiry date
Produce a recommendation for a reviewer Compare the portrait against the liveness capture
Extract a name, date of birth or address
Decide the outcome on its own, unless the account opts in

There is no text extraction anywhere in this stack. If you need parsed identity fields, expiry checking, tampering analysis, or AML screening, this is not the tool for that part of the job, and it pairs with one rather than replacing it.

The decision is made by a person reviewing the submission, and the automated signal is a recommendation shown to them. An account can opt in to having a sufficiently clear-cut recommendation applied automatically; that is off unless you ask for it.

Accepted types are passport, id_card, residence_permit and drivers_license. A document image is kept on its own retention schedule, separate from liveness frames: see the biometric data policy.

3. Server: trust the webhook

The verdict the browser sees is convenient for UX, but it arrives over a channel the end user controls. Make decisions from the webhook, which is signed and server-to-server. See Webhooks.

Sessions expire

A session is short-lived by design, measured in minutes. Create one when the user is about to verify, not when the page is built. If you need something that survives an email, use a verification link instead.

Reading results

curl "https://machine.cognau.com/api/v1/cockpit/sessions?clientReference=user_4821" \
  -H "Authorization: Bearer $COGNAU_SECRET_KEY"

Filtering by your own reference is the point of setting it: you can answer "did user 4821 ever pass?" without having kept our identifiers.


Reading this as an agent? The raw Markdown is at /docs/sessions.md.