Skip to content
KismetKismetDevelopers
llms.txt

Start branded email verification

View .md

POST /v1/developer/guest-auth/challenges

Operation ID: challengeDeveloperGuestAuth

Creates an email OTP challenge bound to this installation, collection, exact Kismet identity anchor (kidSid), and an authorized branded host. Requires a server credential and a same-origin BFF CSRF proof. By default, registered TEST recipients receive a deterministic code in the server response and other TEST addresses receive a generic accepted response without delivery. An unexpired manager-enabled real-email-sign-in staging policy instead sends a random single-use code with a [STAGING] subject, never returned by the API. That challenge is bound to the exact verified staging origin; verification rechecks the origin and policy. Signing in does not enroll membership, subscribe to marketing or request an offer email.

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
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": [
"email",
"kidSid"
],
"properties": {
"email": {
"type": "string",
"minLength": 3,
"maxLength": 254
},
"emailLinkMode": {
"type": [
"string",
"null"
],
"enum": [
"portable",
null
],
"description": "Opt in to cross-browser email verification. Requires emailLinkReturnUrl."
},
"emailLinkContinuation": {
"type": [
"string",
"null"
],
"maxLength": 1024,
"description": "Opaque application intent retained server-side and returned only after portable verification. Never include credentials or personal data."
},
"emailLinkReturnUrl": {
"type": [
"string",
"null"
],
"maxLength": 2048,
"description": "Optional HTTPS callback on the exact authorized Origin, without query or fragment. Sends a single-use link instead of an OTP. The token is in the URL fragment; never log it. TEST link delivery requires active real-email-sign-in staging permission. With emailLinkMode=portable, verification may use another browser; otherwise the original identity anchor is required."
},
"kidSid": {
"type": "string",
"pattern": "^kid_[A-Za-z0-9]{8}$"
}
}
}

Minimal example:

{
"email": "[email protected]",
"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" \
--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 '{"email":"[email protected]","kidSid":"kid_Ab12Cd34"}'
Status Meaning
202 Accepted for processing. See the response body for the current state.
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.
429 Rate limit or quota exceeded; inspect response metadata before retrying.
503 A required Kismet dependency is temporarily unavailable.
{
"accepted": true,
"challengeId": "66666666-6666-4666-8666-666666666666",
"expiresAt": "2026-08-18T18:05:00.000Z",
"testVerificationCode": "042817",
"branding": {
"displayName": "Sandbox Vacation Rentals",
"logoUrl": "https://cdn.kismet.travel/sandbox/logo.svg",
"faviconUrl": "https://cdn.kismet.travel/sandbox/favicon.ico",
"supportEmail": "[email protected]",
"policyLinks": {
"termsUrl": "https://example.invalid/terms",
"privacyUrl": "https://example.invalid/privacy"
},
"accountProvider": "Kismet"
}
}

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

View complete response schema
{
"type": "object",
"additionalProperties": false,
"required": [
"accepted",
"challengeId",
"expiresAt",
"branding"
],
"properties": {
"accepted": {
"type": "boolean",
"enum": [
true
]
},
"challengeId": {
"type": "string",
"format": "uuid"
},
"expiresAt": {
"type": "string",
"format": "date-time"
},
"testVerificationCode": {
"type": "string",
"pattern": "^\\d{6}$",
"description": "TEST only, and only for an address registered on this installation. Never returned in LIVE."
},
"branding": {
"type": "object",
"additionalProperties": false,
"required": [
"displayName",
"logoUrl",
"faviconUrl",
"supportEmail",
"policyLinks",
"accountProvider"
],
"properties": {
"displayName": {
"type": "string"
},
"logoUrl": {
"type": [
"null",
"string"
]
},
"faviconUrl": {
"type": [
"null",
"string"
]
},
"supportEmail": {
"type": [
"null",
"string"
]
},
"policyLinks": {
"type": "object",
"additionalProperties": false,
"required": [
"termsUrl",
"privacyUrl"
],
"properties": {
"termsUrl": {
"type": [
"null",
"string"
]
},
"privacyUrl": {
"type": [
"null",
"string"
]
}
}
},
"accountProvider": {
"type": "string",
"enum": [
"Kismet"
]
}
}
}
}
}