Skip to content

KYC sessions, contact email & re-verification

Three endpoints back the KYC verification flow: one mints the hosted verification URL your page opens in a popup, one refreshes the contact email on a verification that’s already underway, and one sends an already-confirmed player back through verification. Outcomes come back asynchronously via the kyc_status_changed webhook.

Create a verification session

POST https://{operator}.app.lootboxsolutions.com/api/s2s/kyc/sessions
{
"playerExternalId": "u_8431",
"email": "player@example.com",
"locale": "en",
"returnOrigin": "https://casino.example"
}
FieldRequiredNotes
playerExternalId✅Your stable opaque player id (1–190 chars).
email✅Where the player’s verification emails land (see player emails). Held privately; never appears in URLs or webhooks.
locale✅BCP-47-ish code (e.g. en, pt-BR). Language of the hosted verification page.
returnOrigin—The exact origin (scheme + host + port) that receives the popup’s completion postMessage. Omit it and the popup posts nothing — you rely on the webhook.

Response — 201

{
"kycUrl": "https://{operator}.app.lootboxsolutions.com/kyc?token=kt_…&locale=en",
"expiresAt": "2026-07-07T12:30:00Z"
}
  • Open kycUrl in a popup window (window.open) — the page refuses framing, so it cannot go in an iframe.
  • The URL is valid for 30 minutes (expiresAt) and single-use — the embedded token is consumed the moment the player opens the page. Mint a fresh one per click; an expired or reused link shows the player a “link expired” screen, not an error of yours.
  • Minting is idempotent-friendly by design: if the player already has an open PENDING request, that request is reused (its contact fields refresh to what you just sent) and a new link is issued — any earlier link stops working. If their latest request was decided (or they never had one), a fresh request opens, which emits its own PENDING webhook.

Errors

codeHTTPwhen
KYC_DISABLED403KYC is not enabled for the operator
KYC_ALREADY_SUBMITTED409the player’s verification is already submitted and awaiting review — nothing for them to redo
validation error422malformed input

Update the contact email

Call this when a player changes their account email while a verification is open, so decision emails keep landing in the right inbox.

POST https://{operator}.app.lootboxsolutions.com/api/s2s/kyc/email
{
"playerExternalId": "u_8431",
"email": "new-address@example.com"
}
FieldRequiredNotes
playerExternalId✅Same id the session was minted for.
email✅The new contact address.

Response — 200

{ "ok": true }

Errors

codeHTTPwhen
KYC_NO_OPEN_REQUEST404the player has no open (PENDING/SUBMITTED) verification — decided requests are immutable history

KYC_NO_OPEN_REQUEST is a benign outcome, not a failure: it just means there was nothing to update. Fire this call on every email change without checking KYC state first and ignore the 404.

Re-verify a confirmed player

Call this when your side decides a confirmed player must pass verification again — a risk review, a changed circumstance, whatever your compliance process demands. It re-opens verification the same way every other re-verification does: a fresh request is created, becoming the player’s latest, and its PENDING event arrives on the kyc_status_changed webhook like any other. Your side should treat that as “no longer verified” until the new request is confirmed.

POST https://{operator}.app.lootboxsolutions.com/api/s2s/kyc/reverify
{
"playerExternalId": "u_8431",
"reason": "Periodic review — verified identity is over 12 months old."
}
FieldRequiredNotes
playerExternalId✅Your stable opaque player id (1–190 chars).
reason✅3–500 chars. Read by the platform reviewer who picks the re-verification up — tell them what to look at. It is never shown to the player.

Response — 201 (review opened)

{ "status": "opened", "requestId": 977 }

A new request now exists and its own PENDING webhook is on the way. requestId is the new request’s id.

Response — 200 (already open)

{ "status": "already_open", "requestId": 977 }

The player already has an open re-verification — this call created nothing and the earlier request (and its stated reason) stands. This is what makes the call safe to repeat: a double-click or a retried job cannot open a second review.

Errors

codeHTTPwhen
KYC_DISABLED403KYC is not enabled for the operator
KYC_NOT_CONFIRMED409the player has no confirmed verification to re-open — to verify someone for the first time (or after a rejection), mint a session instead
validation error422malformed input

Two things this endpoint deliberately does not do:

  • It never contacts the player. No email is sent and nothing changes in any UI they can see, beyond whatever your own site does with the PENDING status. If and when the player should be asked to act is your call — when they are, mint a session and the open request is reused.
  • It never explains itself downstream. The webhook your re-verification produces is indistinguishable from any other new request — the reason you pass lives with the platform’s review desk only.