# 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 ```bash 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" }' ``` ```json { "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 | ```tryit { "method": "POST", "path": "/session/create", "title": "creates a sandbox session with a test key", "body": "{\n \"platform\": \"web\",\n \"clientReference\": \"user_4821\",\n \"simulate\": \"pass\"\n}" } ``` ## 2. Browser: run the check Hand the session to the widget. See [Embedding](/docs/embedding). ## 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](/docs/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](/docs/verification-links) instead. ## Reading results ```bash 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.