Skip to content

Mint a client token

POST
/v1/auth/session-tokens
curl --request POST \
--url https://api.keliplay.com/v1/auth/session-tokens \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "channelId": "0192f3a1-0000-7000-8000-00000000c001", "participantRef": "user_48213", "origin": "https://www.example.com", "ttlSeconds": 900 }'

Mints a client token for one player on one channel. Call this from your backend each time a player opens the page, and pass the token to the embed.

The token is for whichever campaign is live on the channel right now. When nothing is live, the response is 200 with clientToken: null and the channel’s between-campaigns message. Pass the null token to the embed anyway: it shows that message.

origin must be one of your allowed origins. If the player has used all their plays, the response is 409 with a message you can show them.

Permission: tokens.mint. Rate limit: 600 requests per minute.

Media typeapplication/json
object
channelId
required

The channel the player is about to play.

string
>= 1 characters
participantRef
required

Your own id for the player. Winners and rewards are reported against it.

string
>= 1 characters <= 200 characters
origin
required

Where the game will be shown: a site’s origin, such as https://www.example.com, or an app as android:<application id> or ios:<bundle id>, such as android:com.example.app. Must be registered under allowed origins.

string
<= 300 characters
ttlSeconds

How long the token lasts, in seconds. Defaults to 900.

integer
>= 60 <= 3600
Example
{
"channelId": "0192f3a1-0000-7000-8000-00000000c001",
"participantRef": "user_48213",
"origin": "https://www.example.com",
"ttlSeconds": 900
}

Nothing is live on the channel. No token is issued.

Media typeapplication/json
object
clientToken
required
null
betweenCampaigns
required
One of:

What the channel shows when no campaign is live.

object
title
string
<= 120 characters
body
string
<= 600 characters
imageUrl

An https URL, or a file from your media library.

string
<= 2048 characters
Example
{
"clientToken": null,
"betweenCampaigns": {
"title": "Back soon",
"body": "Our next game starts on Monday."
}
}
X-RateLimit-Limit
integer

Requests allowed in the current window.

X-RateLimit-Remaining
integer

Requests left in the current window.

A token for the live campaign.

Media typeapplication/json
object
clientToken
required

Pass this to the embed as clientToken.

string
expiresAt
required
string format: date-time
jti
required

A unique id for this token, useful in your own logs.

string
Example
{
"clientToken": "eyJhbGciOiJIUzI1NiJ9.eyJleGFtcGxlIjp0cnVlfQ.c2lnbmF0dXJl",
"expiresAt": "2026-10-05T12:15:00.000Z",
"jti": "0192f3a1-0000-7000-8000-0000000000a1"
}
X-RateLimit-Limit
integer

Requests allowed in the current window.

X-RateLimit-Remaining
integer

Requests left in the current window.

The request is not valid. details lists each field that failed, where there is one.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "invalid_request",
"message": "Invalid request json.",
"details": [
{
"path": "name",
"message": "Too small, expected string to have >=1 characters"
}
]
}
}

The API key is missing, malformed or revoked.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "unauthorized",
"message": "Invalid or revoked API key."
}
}

The API key does not carry the permission this needs, or the request is not allowed.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "forbidden",
"message": "Your role does not allow this (draws.run)."
}
}

Nothing with that id exists in your account.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "not_found",
"message": "Channel 0192f3a1-0000-7000-8000-00000000c009 not found."
}
}

The request clashes with the current state. The message says what to change.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "conflict",
"message": "An archived campaign cannot be edited. Restore it first, then make the change."
}
}

Rate limit exceeded. Wait for Retry-After seconds.

Media typeapplication/json
object
error
required
object
code
required

Stable and safe to branch on.

  • invalid_request (400): the request is not valid.
  • unauthorized (401): missing, malformed or revoked API key.
  • upgrade_required (402): not in your plan, or a plan limit is reached.
  • forbidden (403): the key lacks a permission, or the action is not allowed.
  • not_found (404): nothing with that id in your account.
  • conflict (409): clashes with the current state.
  • confirmation_required (409): repeat with confirm=true. Folder deletion only.
  • rate_limited (429): wait for Retry-After seconds.
  • internal_error (500) and service_unavailable (503): try again later.
string
Allowed values: invalid_request unauthorized upgrade_required forbidden not_found conflict confirmation_required rate_limited internal_error service_unavailable
message
required

Written for a person. May change; do not parse it.

string
details
One of:
Array<object>
object
path
required

The failing field, dot separated, such as prize.label.

string
message
required
string
Example
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded: 30 requests per 60s."
}
}
Retry-After
integer

Seconds to wait before trying again.