Skip to main content

Authentication

Every call to the Wiselook public API carries a bearer token. There are two token types, for two different callers.

Client-credentials token (your backend)

Your server-to-server integration uses an OAuth2 client-credentials token, minted from the client you created on the API credentials page.

curl -X POST https://<WISELOOK_HOST>/auth/application/o/token/ \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<YOUR_CLIENT_ID>' \
--data-urlencode 'client_secret=<YOUR_CLIENT_SECRET>' \
--data-urlencode 'scope=<space-separated scopes>'

The response contains an access_token (a JWT) and expires_in. Send it on every API call:

Authorization: Bearer <access_token>

Request only the scopes your client was granted — requesting a scope the client doesn't hold causes the token request to fail.

Available scopes

Scopes are named <resource>:<verb>. You select which ones a client may request when you create it on the API credentials page.

ScopeGrants
widget_sessions:writeMint visitor session JWTs for your widget (POST /v1/widgets/{id}/sessions). This is the scope the widget embed flow uses.
methodologies:readRead methodologies and their structure (GET /v1/methodologies, …/{id}, …/{id}/ecos).
competencies:readRead competencies (GET /v1/competencies).
ecos:readRead ECOs and their questions (GET /v1/ecos/{id}, …/{id}/questions).
evaluations:readRead assessment runs and results (GET /v1/evaluations, …/{id}).
evaluations:writeStart an assessment run directly via the API (POST /v1/evaluations).
chat:writeDrive an assessment conversation (POST /v1/chat/messages, voice sessions).
transcripts:readRead an assessment transcript (GET /v1/transcripts/{id}).

Most integrations only need widget_sessions:write — the widget handles the conversation itself once a visitor session is minted (see Mint a visitor session). The remaining scopes are for building directly against the assessment API instead of the widget.

Visitor JWT (the widget, in the browser)

Browsers can't safely hold a client secret, so the widget uses a short-lived visitor JWT instead. Your backend mints one per visitor session by calling the public mint endpoint with your client-credentials token (scope widget_sessions:write):

curl -X POST https://<WISELOOK_HOST>/v1/widgets/<WIDGET_ID>/sessions \
-H "Authorization: Bearer <CLIENT_CREDENTIALS_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"external_user_id": "<your-stable-user-id>"}'

The response contains the visitor JWT. Hand it to the widget; the widget sends it as its bearer for the assessment surface (/v1/chat/*, /v1/evaluations, /v1/transcripts/{id}). The JWT is Ed25519-signed, expires in ~15 minutes, and is bound to the widget's allowed origins.

See Mint a visitor session for the full flow.

What your token can access

  • Your tenant only. Every token is scoped to your organisation. You cannot read another tenant's data — guessing or supplying another tenant's IDs returns nothing.
  • Only your granted scopes. A token can only do what its scopes allow; a call beyond them is rejected.
  • The public API surface. Every endpoint documented in this site (the /v1/* paths) is available to you with the right token and scope.