Skip to content
KismetKismetDevelopers
llms.txt

Verify a branded guest authentication challenge

View .md

POST /v1/developer/guest-auth/challenges/{challengeId}/verify

Operation ID: verifyDeveloperGuestAuth

Consumes a single-use challenge only from an authorized branded host and returns guest session tokens to the host BFF. OTP and legacy links require the original kidSid. Portable links require the exact stored callback and authenticate the destination browser’s canonical kidSid, returning only the original server-retained continuation. Source session identity is not transferred. The BFF must set its own branded HttpOnly cookie; session tokens must never enter browser JavaScript.

Field Value
Maturity beta
Required capability guest_auth.write
Freshness class sandbox-write
Quota cost 1

All operations require a Kismet Developer Bearer credential. Collection and resource authority is resolved from the credential’s installation grants; identifiers in the URL never grant access.

Name In Type Required Description
challengeId path string yes
x-kismet-csrf header string yes Opaque CSRF proof validated by the same-origin host BFF before it calls Kismet. Never a Kismet credential.
origin header string no Original branded browser origin forwarded by the same-origin BFF. Must match Collection.authorizedDomains.
x-forwarded-host header string no Original branded host fallback for server route handlers that do not forward Origin. Must match Collection.authorizedDomains.

The request body is JSON. The canonical schema is:

{
"type": "object",
"additionalProperties": false,
"required": [
"code",
"kidSid"
],
"properties": {
"code": {
"type": "string",
"pattern": "^(?:\\d{6}|[A-Za-z0-9_-]{43})$"
},
"emailLinkReturnUrl": {
"type": [
"string",
"null"
],
"maxLength": 2048,
"description": "Exact server-configured callback used to start a portable email link. Never accept this value from browser input."
},
"kidSid": {
"type": "string",
"pattern": "^kid_[A-Za-z0-9]{8}$"
}
}
}

Minimal example:

{
"code": "042817",
"kidSid": "kid_Ab12Cd34"
}

Set KISMET_API_ORIGIN=https://api.ksmt.app and configure KISMET_DEVELOPER_API_KEY in your environment. Run server-credential requests from your backend, not browser code.

Guest access tokens come from the signed-in guest session held by your backend. Forward a CSRF proof only after your same-origin backend validates it. If shown, KISMET_SITE_ORIGIN is the authorized origin of your site. Do not substitute a guest ID or an invented token.

Terminal window
curl --request POST \
"$KISMET_API_ORIGIN/v1/developer/guest-auth/challenges/CHALLENGE_ID/verify" \
--header "Authorization: Bearer $KISMET_DEVELOPER_API_KEY" \
--header "Accept: application/json" \
--header "x-kismet-csrf: $VALIDATED_CSRF_TOKEN" \
--header "origin: $KISMET_SITE_ORIGIN" \
--header "Content-Type: application/json" \
--data '{"code":"042817","kidSid":"kid_Ab12Cd34"}'
Status Meaning
200 Success.
400 Invalid request parameters or body.
401 Missing, invalid, expired, or inappropriate credential/session.
403 Credential lacks the required grant/capability, or an origin/CSRF check failed.
409 Request conflicts with the installation environment or current state.
410 The single-use authentication challenge is no longer valid.
429 Rate limit or quota exceeded; inspect response metadata before retrying.
503 A required Kismet dependency is temporarily unavailable.
{
"kidSid": "kid_AbCdEf12",
"guest": {
"id": "77777777-7777-4777-8777-777777777777",
"email": "[email protected]",
"guestProfileId": "88888888-8888-4888-8888-888888888888"
},
"session": {
"accessToken": "<server-only-access-token>",
"refreshToken": "<server-only-refresh-token>",
"expiresAt": "2026-09-17T18:00:00.000Z"
}
}

Content type: application/json. Required fields, nullable values, and nested structures are defined below.

View complete response schema
{
"type": "object",
"additionalProperties": false,
"required": [
"kidSid",
"guest",
"session"
],
"properties": {
"emailLinkContinuation": {
"type": "string",
"maxLength": 1024,
"description": "Original application intent for a successfully consumed portable link. Absent for legacy authentication."
},
"kidSid": {
"type": "string"
},
"guest": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"email",
"guestProfileId"
],
"properties": {
"id": {
"type": "string"
},
"email": {
"type": "string"
},
"guestProfileId": {
"type": "string"
}
}
},
"session": {
"type": "object",
"additionalProperties": false,
"required": [
"accessToken",
"refreshToken",
"expiresAt"
],
"properties": {
"accessToken": {
"type": "string"
},
"refreshToken": {
"type": "string"
},
"expiresAt": {
"type": "string",
"format": "date-time"
}
}
},
"emailLinkAttributionProof": {
"type": "string",
"maxLength": 256,
"description": "Server-only, 15-minute proof for preserving source offer attribution after portable email verification. Keep in the sealed server session; never expose it in browser JSON, URLs or logs. Does not authenticate a guest or grant consent."
}
}
}