The Gamopanda End User Display requires a signed access token to display a logged-in customer's streak and challenge progress. Your backend generates this token and passes it to the Javascript script during initialization — it is never fetched client-side.
The token is a JWT signed with your Gamopanda API secret and scoped to a single end user.
How it works
A customer loads your page and is identified by your platform (e.g. session, cookie, OAuth token).
Your backend looks up the customer's identity — typically their platform-specific user ID.
Your backend signs a JWT using your Gamopanda API key and API secret , embedding the customer's externalId.
Your backend returns the token to the frontend (in the page HTML, a cookie, or an API response).
The frontend passes the token to the widget via the accessToken field in the initialize call.
Token structure
The JWT payload must contain:
Field Description subYour Gamopanda accountId userData.externalIdYour system's unique identifier for this customer
The JWT must be signed with:
JWT field Value Secret (secretOrPrivateKey) Your Gamopanda API secret (x-api-secret) keyid headerYour Gamopanda API key (x-api-key) expiresIn30m (recommended)
Implementation
Node.js (jsonwebtoken)
import jwt from 'jsonwebtoken' ;
function generateGamopandaAccessToken ({ externalId , accountId , apiKey , apiSecret }) {
return jwt. sign (
{
userData: { externalId },
sub: accountId
},
apiSecret,
{
expiresIn: '30m' ,
keyid: apiKey
}
);
}
Call this on your backend when serving a page that embeds the widget:
const accessToken = generateGamopandaAccessToken ({
externalId: 'Your Customer Id' ,
accountId: process.env. GAMOPANDA_ACCOUNT_ID ,
apiKey: process.env. GAMOPANDA_API_KEY ,
apiSecret: process.env. GAMOPANDA_API_SECRET
});
// Pass accessToken to your frontend template / API response
Your API secret must only be used on your backend server. If your API secret is compromised, rotate it immediately via the API Keys page.
Python (PyJWT)
Install the library: pip install PyJWT
import jwt
import os
from datetime import timedelta
def generate_gamopanda_access_token (external_id: str ) -> str :
payload = {
"userData" : { "externalId" : external_id},
"sub" : os.environ[ "GAMOPANDA_ACCOUNT_ID" ],
}
token = jwt.encode(
payload,
os.environ[ "GAMOPANDA_API_SECRET" ],
algorithm = "HS256" ,
headers = { "kid" : os.environ[ "GAMOPANDA_API_KEY" ]},
# PyJWT accepts timedelta for expiry
options = { "exp" : int ((timedelta( minutes = 30 )).total_seconds())},
)
return token
A simpler form using exp directly:
import jwt
import os
import time
def generate_gamopanda_access_token (external_id: str ) -> str :
payload = {
"userData" : { "externalId" : external_id},
"sub" : os.environ[ "GAMOPANDA_ACCOUNT_ID" ],
"exp" : int (time.time()) + 1800 , # 30 minutes
"iat" : int (time.time()),
}
return jwt.encode(
payload,
os.environ[ "GAMOPANDA_API_SECRET" ],
algorithm = "HS256" ,
headers = { "kid" : os.environ[ "GAMOPANDA_API_KEY" ]},
)
Java (java-jwt)
Add the dependency to your pom.xml:
< dependency >
< groupId >com.auth0</ groupId >
< artifactId >java-jwt</ artifactId >
< version >4.4.0</ version >
</ dependency >
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.time.Instant;
import java.util.Date;
import java.util.Map;
public class GamopandaTokenService {
private final String accountId = System. getenv ( "GAMOPANDA_ACCOUNT_ID" );
private final String apiKey = System. getenv ( "GAMOPANDA_API_KEY" );
private final String apiSecret = System. getenv ( "GAMOPANDA_API_SECRET" );
public String generateAccessToken (String externalId ) {
Algorithm algorithm = Algorithm. HMAC256 (apiSecret);
return JWT. create ()
. withSubject (accountId)
. withKeyId (apiKey)
. withClaim ( "userData" , Map. of ( "externalId" , externalId))
. withIssuedAt (Date. from (Instant. now ()))
. withExpiresAt (Date. from (Instant. now (). plusSeconds ( 1800 ))) // 30 minutes
. sign (algorithm);
}
}
PHP (firebase/php-jwt)
Install the library: composer require firebase/php-jwt
use Firebase\JWT\JWT;
function generateGamopandaAccessToken(string $externalId): string {
$payload = [
'sub' => getenv('GAMOPANDA_ACCOUNT_ID'),
'userData' => ['externalId' => $externalId],
'iat' => time(),
'exp' => time() + 1800, // 30 minutes
];
return JWT::encode(
$payload,
getenv('GAMOPANDA_API_SECRET'),
'HS256',
getenv('GAMOPANDA_API_KEY') // keyid header
);
}
Ruby (ruby-jwt)
Install the gem: gem install jwt
require 'jwt'
def generate_gamopanda_access_token(external_id)
payload = {
userData: { externalId: external_id },
sub: ENV['GAMOPANDA_ACCOUNT_ID'],
iat: Time.now.to_i,
exp: Time.now.to_i + 1800 # 30 minutes
}
headers = { kid: ENV['GAMOPANDA_API_KEY'] }
JWT.encode(payload, ENV['GAMOPANDA_API_SECRET'], 'HS256', headers)
end
Last modified on April 12, 2026