Skip to content

html5-banner

PokiSDK - HTML5

1. Initialize the SDK

Add the following HTML within the <head> tags of your game HTML:

<script src="https://game-cdn.poki.com/scripts/v2/poki-sdk.js"></script>

Initialize the SDK at the start of your game with the following Javascript:

PokiSDK.init().then(() => {
    console.log("Poki SDK successfully initialized");
    // fire your function to continue to game
}).catch(() => {
    console.log("Initialized, something went wrong, load you game anyway");
    // fire your function to continue to game
});


2. Implement the game loading logic

In order to provide an accurate conversion to play metric for your game, please fire the following events when your loading has finished:

// fire loading function here
PokiSDK.gameLoadingFinished();


3. Implement the gameplay events

Use the  ๐ŸŽฎ gameplayStart()  event to describe when users are playing your game (e.g. level start and unpause).

Use the  โ˜  gameplayStop()  event to describe when users aren’t playing your game (e.g. level finish, game over, pause, quit to menu).

// first level loads, player clicks anywhere
PokiSDK.gameplayStart();
// player is playing
// player loses round
PokiSDK.gameplayStop();
// game over screen pops up


4. Implement commercialBreak

Commercial breaks are used to display video ads and should be triggered on natural breaks in your game. Throughout the rest of your game, we recommend you implement the  ๐ŸŽž commercialBreak()  before every  ๐ŸŽฎ gameplayStart() , i.e. whenever the user has shown an intent to continue playing.

// pause your game here if it isn't already
PokiSDK.commercialBreak(() => {
  // you can pause any background music or other audio here
}).then(() => {
  console.log("Commercial break finished, proceeding to game");
  // if the audio was paused you can resume it here (keep in mind that the function above to pause it might not always get called)
  // continue your game here
});

Important information about commercialBreaks

Not every single  ๐ŸŽž commercialBreak()  will trigger an ad. Poki’s system will determine when a user is ready for another ad, so feel free to signal as many commercial break opportunities as possible.


5. Implement rewardedBreak

Rewarded breaks allow for a user to choose to watch a rewarded video ad in exchange for a certain benefit in the game (e.g. more coins, etc.). When using  ๐ŸŽฌ rewardedBreak() , please make it clear to the player beforehand that they’re about to watch an ad.

// pause your game here if it isn't already
PokiSDK.rewardedBreak(() => {
  // you can pause any background music or other audio here
}).then((success) => {
    if(success) {
        // video was displayed, give reward
    } else {
        // video not displayed, should not give reward
    }
    // if the audio was paused you can resume it here (keep in mind that the function above to pause it might not always get called)
    console.log("Rewarded break finished, proceeding to game");
    // continue your game here
});

Optional parameters to the rewardedBreak function

You can pass the follow optional parameter as properties of an object to the rewardedBreak function:

size: The “size” of the reward. Accepted values are small, medium, large. Note: based on the size we can opt for showing more rewarded advertisements.

onStart: A callback function for the moment an advertisement is shown to the user

PokiSDK.rewardedBreak({
    size: 'medium',
    onStart: () => {},
}).then((success) => {});

About the rewardedBreak timer

 ๐ŸŽฌ rewardedBreak()  affects the timing of  ๐ŸŽž commercialBreak()  - When a user interacts with a rewarded break, our systemโ€™s ad timer is reset to ensure the user does not immediately see another ad.


6. User Accounts

The User Accounts feature allows games to prompt the user to log in, access logged-in user information and authentication tokens. This enables personalized experiences and secure communication between games and Poki User Accounts.


User Interface

The User Accounts module provides three main methods:

  •  ๐Ÿ’ฌ login() : Prompts the user to log in if they haven’t already
  •  ๐Ÿ‘ค getUser() : Returns information about the currently logged-in user
  •  ๐ŸŽซ getToken() : Returns a game specific JWT authentication token for the current user

User Data Structure

When a user is logged in, the getUser() method returns a User object with the following properties:

interface User {
  username: string;
  avatarUrl: string;
}

SDK Methods

Login

login(): Promise<void>

Prompts the user to log in if they are not already authenticated. If the user is already logged in, this method resolves immediately. Only call this in response to a user interaction that requires an account, avoid calling it automatically on game load.

  • If the user successfully logs in, a full page refresh will occur
  • If the user closes the authentication panel or takes too long (45 seconds), the promise will be rejected
try {
  await PokiSDK.login();
  // The page will reload if the user logs in.
  // In case the user is already logged in, the promise resolves instantly and you can continue from here.
  const user = await PokiSDK.getUser();
  console.log("User logged in:", user.username);
} catch (error) {
  console.log("Login failed:", error.message);
  // User closed auth panel or login timed out
}

Get User

getUser(): Promise<User | null>

Returns the current logged-in user information, or null if no user is logged in. Throws an exception if user accounts is not enabled or if the user has opted out of the feature.

Call this function after your game loads to handle all possible user states (logged in, logged out, or after a page refresh due to an authentication state change). This allows you to provide the appropriate user experience from the start.

try {
  const user = await PokiSDK.getUser();
  if (user) {
    console.log(`Welcome ${user.username}!`);
  } else {
    // User is not logged in, you can call PokiSDK.login() to prompt it
    console.log("User not logged in");
  }
} catch (error) {
  // user accounts is not available or user opted out of the feature
}

Debug Mode (Inspector)

When running with debug mode enabled, getUser() returns static mock data for local development and testing:

{
  username: 'TestUser',
  avatarUrl: 'https://a.poki-cdn.com/img/placeholder_gradient.png'
}

Get Token

getToken(): Promise<string | null>

Returns a JWT token for the current user, or null if no user is logged in. Throws an exception if user accounts is not enabled or if the user has opted out of the feature. This token can then be verified from your backend.

Important: The token expires in 1 minute for security purposes. Do not store this token or use it for anything other than verifying with the Poki endpoint to obtain the persistent user_id. Generate a new token each time you need to verify a user.

Token Generation
try {
  const token = await PokiSDK.getToken();
  if (token) {
    // Send the token to your backend and verify it to obtain the user_id
    fetch("/your/backend/service", ...);
  } else {
    console.log("No authentication token available");
  }
} catch (error) {
  // user accounts is not available or user opted out of the feature
}
Token Verification

You can verify the token from your backend using the Poki verification endpoint:

// Backend verification example
async function verifyPokiToken(token, teamApiKey) {
  const response = await fetch(
    "https://user-vault.poki.com/auth/verify-token",
    {
      method: "GET",
      headers: {
        Authorization: `Bearer ${token}`,
        "X-Poki-Team-Api-Key": teamApiKey,
      },
    },
  );

  if (response.ok) {
    const verificationResult = await response.json();
    console.log("Token is valid:", verificationResult); // { user_id: "unique-user-identifier" }
    return verificationResult.user_id;
  } else {
    console.log("Token verification failed");
    return null;
  }
}

The verification endpoint returns a user_id that is immutable and unique per game. This user_id should be used as the primary identifier for that user in your backend systems.

Note: You’ll need to obtain your X-Poki-Team-Api-Key from your account manager to use the verification endpoint.

Debug Mode (Inspector)

When running with debug mode enabled, getToken() returns a valid, long-lasting JWT token that works with the Poki verification endpoint. When decoded, this token resolves to the user_id: "debug-user-id". This allows you to test the full authentication flow, including backend token verification.


Cloud Gamesaves

When a user is logged in, the Poki SDK automatically syncs their game saves to the cloud. This is completely transparent โ€” no extra SDK calls or setup are required. Saves are tied to the logged-in user and restored across sessions and devices.

How it works

Every time a user plays a game, the SDK attempts to load their gamesave from the cloud and inject it into the game before it starts. During gameplay, the SDK monitors two browser storage APIs for changes, localStorage and IndexedDB, and batches any updates to sync them back to the cloud at a throttled interval to avoid excessive network activity and bandwidth usage.

Exclude data from your cloudsavegames

If you have data that should never be included in cloud gamesaves, prefix it with poki_ignore.

  • localStorage keys that start with poki_ignore are skipped
  • IndexedDB object stores that start with poki_ignore are skipped
  • IndexedDB row keys that start with poki_ignore are skipped

This is useful for caches, temporary state, analytics buffers, or any other local-only data that should not be restored across devices.

Storage limit

1MB Gamesave Limit

The gamesave payload must not exceed 1MB after gzip compression. If a player’s save exceeds this limit, cloud gamesaves will be automatically disabled for that player and their progress will no longer be synced. Design your save data to stay well within this limit.


7. Final Steps

Disable sound and input during ads

Make sure that audio and keyboard input are disabled during commercialBreaks, so that the game doesn’t interfere with the ad:

// gameplay stops (don't forget to fire gameplayStop)
// fire your mute audio function
// fire your disable keyboard input function
PokiSDK.commercialBreak().then(() => {
    console.log("Commercial break finished, proceeding to game");
    // fire your unmute audio function
    // fire your enable keyboard input function
    PokiSDK.gameplayStart();
    // fire your function to continue to game
});


Prevent page jump

When a player presses space or the arrow keys, the default browser behavior is to emulate scroll. But in a game, we don’t want that. It’s not noticeable in your development environment because your game is (probably) taking the full window. But on Poki, it will be inside a longer page that can scroll.

Here is a snippet that you can paste in your game to disable this behavior.

window.addEventListener('keydown', ev => {
    if (['ArrowDown', 'ArrowUp', ' '].includes(ev.key)) {
        ev.preventDefault();
    }
});
window.addEventListener('wheel', ev => ev.preventDefault(), { passive: false });


Shareable URLs & URL manipulation

Creating shareable urls and changing the Poki.com url

You can create a shareable url with the following function:

PokiSDK.shareableURL({}).then(url => {});

// example
const params = {
    id: 'myid',
    type: 'mytype',
    // ... any other param
}

PokiSDK.shareableURL(params).then(url => {
    console.log(url);
    // if run on e.g. https://poki.com/en/g/my-awesome-game it will return https://poki.com/en/g/my-awesome-game?gdid=myid&gdtype=mytype
});

// read further to see how to fetch these params easily from within your game
Reading Poki.com url params

As you might have noticed in the previous topic, the PokiSDK.shareableURL creates a url with parameters that are prefixed with gd. We have created a simple helper function that will easily allow you to read the params.

PokiSDK.getURLParam('<param name>');

// example
const id = PokiSDK.getURLParam('id');
// this will return either the gdid param set on poki.com or the id param on the current url


Moving the Poki Pill on mobile

On mobile, you can reposition the Poki Pill slightly to better fit your game UI using PokiSDK.movePill(topPercent, topPx).

  • topPercent is a number between 0 and 50 and sets the pill’s vertical position as a percentage from the top of the game area.
  • topPx is an additional pixel offset applied on top of topPercent (positive moves it down, negative moves it up).

You can’t move the pill lower than 50% of the game area (the game bar at the bottom is not included in this area).

The default position is PokiSDK.movePill(0, 24).

Poki Pill size

  • 46px ร— 62px on screens narrower than 1211px.
  • 92px ร— 64px on screens 1211px wide or wider.
// Move the pill 100 pixels above the center of the game.
PokiSDK.movePill(50, -100);


Upload and test your game in Poki for Developers

Congrats, youโ€™ve successfully implemented the PokiSDK! Now upload your game to the Poki Inspector and test it there. When you’re happy with the implementation, send us a review request and we’ll play the game. Feel free to contact us via Discord or developersupport@poki.com if you’re stuck.