Authentication

Cognau uses four credentials, and exactly one of them belongs on your server. Confusing them is the most common integration mistake, so it is worth two minutes.

Credential Looks like Lives Grants
API key cgn_sk_live_… / cgn_sk_test_… your server, only full account access
Session token cgn_st_… the browser one WebSocket, once
Document token returned beside it the browser upload to one session
Link token cgn_vl_… an email or URL one session, then spent

API keys

Send as a bearer token:

curl https://machine.cognau.com/api/v1/cockpit/sessions \
  -H "Authorization: Bearer cgn_sk_live_…"

The key decides both who you are and which environment you are in. A test key cannot create live sessions and a live key cannot create sandbox ones, so a misconfigured deployment fails loudly instead of quietly billing you.

Never put an API key in a browser. It grants read access to every session on your account. Only the hash is stored on our side, so a key is shown in full exactly once, at creation; if you lose it, issue another and revoke the old one.

Multiple active keys per environment are allowed on purpose, so rotation is create → deploy → revoke, with no window where your integration is down.

There is no publishable key

If you have integrated Stripe or a similar SDK you will go looking for a cgn_pk_… to put in your frontend. There isn't one, and you don't need one.

A publishable key exists so a browser can start something before any server object exists. Here the session already exists before the browser is involved, so the session token covers it — and it is strictly narrower than a publishable key:

a publishable key our session token
Scope the whole account one session
Lifetime until you rotate it expires with the session
If leaked works until you notice already spent

So no account-level credential of any kind reaches the browser. The only thing your page ever holds is a token for the single verification it is running. Controlling where the widget may be embedded is a separate, server-side setting: see restricting who can embed you.

Session tokens

Returned by POST /session/create and handed to the browser. A session token authorizes exactly one WebSocket connection and nothing else. It is single-use: once a socket opens, the token is spent, which is why a dropped connection ends the session rather than resuming it.

A session that also collects a document returns a second token, documentToken. The session token is spent the moment the liveness socket opens, so it is gone before the document screens are reached, and a capture is inherently several calls: front, back, a retake. The document token can do exactly one thing, submit a document side to that one session, and there is no read path that accepts it. Pass the whole session object to the widget and it uses both.

The credential inside a verification URL. Weaker than an API key by construction: it can create the one session it is scoped to, and cannot read verdicts, list sessions, or see anything about your account.

Treat the URL itself as the secret. Anyone holding it can run one verification that you are billed for, which is why links default to a single use, always expire, and can be revoked instantly.


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