PickBits SDK Reference

Drop-in JavaScript SDK for games and apps on *.pickbits.ai. Handles authentication, cross-subdomain single sign-on, saved progress, achievements, leaderboards, and premium entitlements. Version 1.x.

// jump install init auth sso progress achievements leaderboards premium analytics

Install

Add a single <script> tag. The SDK is served from the main site, exposes window.PickBits, and self-loads the Supabase JS client from CDN.

<script src="https://pickbits.ai/sdk/pickbits-sdk.js"></script>

Initialise

Call PickBits.init() once with a gameSlug matching the slug registered in the achievements table.

PickBits.init({
  gameSlug: 'remme',
  economy: {                          // optional
    type:        'coins',
    name:        'Remme Credits',
    icon:        'fa-coins',
    getBalance:  () => game.getCoins(),
    storeUrl:    '/store'
  }
});
The SDK reads ?pb_token= from the URL on init. If present, it exchanges the relay token for a Supabase session and strips the query param via history.replaceState. This is how cross-subdomain SSO lands the user automatically — see SSO.

Auth

MethodReturnsNotes
PickBits.isAuthenticated()booleanSync.
PickBits.getUser(){ id, email, username, display_name, avatar_url, level } | nullSync. Populated after fetchProfile resolves.
PickBits.onAuthChange(cb)voidFires on sign-in / sign-out. Passes the current user object or null.
PickBits.promptLogin()voidRedirects to pickbits.ai/dashboard?login=1&redirect=<returnURL>.

Cross-subdomain SSO

Main-site → subdomain sign-in flow (Phase 1, pb_sso_phase1):

  1. User is signed in on pickbits.ai.
  2. Main site calls window.pbAuth.linkTo('https://feedrunner.pickbits.ai/') — this mints an HMAC-signed relay token (60s TTL, single-use via consumed_relay_tokens) via the relay-token edge function and redirects with ?pb_token= appended.
  3. Destination subdomain loads the SDK, sees ?pb_token=, POSTs action: "exchange" to relay-token, receives an OTP token hash, and calls supabase.auth.verifyOtp. A native Supabase session materialises in local storage — no additional credential entry.
Global sign-out. window.pbAuth.signOut() on the main site calls the revoke-sessions edge function, which invokes supabase.auth.admin.signOut(jwt, "global"). Refresh tokens invalidate immediately; access tokens across subdomains expire within their 1h lifetime. No per-device session UI in v1.

Integrators on subdomains don't need to wire anything for SSO — just include the SDK and the token exchange is automatic. To initiate a cross-domain link from the main site, use pbAuth.linkTo().

Saved progress

MethodDescription
PickBits.saveProgress(data)Upserts a JSONB blob into game_progress.save_data for (user_id, game_slug).
PickBits.loadProgress()Returns { save_data, high_score, playtime_seconds, last_played_at } | null.
// Autosave
setInterval(async () => {
  if (PickBits.isAuthenticated()) {
    await PickBits.saveProgress({ level: 7, inventory: game.getInventory() });
  }
}, 30_000);
Phase 3 adds { slot } parameters and transparent routing to Vercel Blob for saves > 100 KB. Today's single-slot JSONB call is forward-compatible — calling saveProgress(data) without slot continues to write to slot 0.

Achievements

MethodDescription
PickBits.unlockAchievement(slug)Idempotent — calls claim-achievement edge function. Safe to replay.
PickBits.getAchievements()Returns this user's unlocks for this game + global achievements.
PickBits.unlockAchievement('first-win').then(res => {
  if (res.ok) toast(`+${res.xp_awarded} XP — ${res.achievement.title}`);
});

Leaderboards

PickBits.submitScore(score) posts to the submit-score edge function, which enforces "only update if higher" on the server. No client-side check required.

PickBits.submitScore(gameOverScore);

Premium entitlements

Phase 4 surface. Call on feature gates to check whether the signed-in user has an active experimenter subscription.

MethodReturns
PickBits.isPremium()Promise<boolean> — cached 60s in-memory.
PickBits.getTier()Promise<'free' | 'experimenter' | null>
Client-side isPremium() is a UX optimisation — server-side edge functions re-check via the is_user_premium(uuid) SQL function for anything that costs real money (e.g. premium AI calls).

Analytics bridge

PickBits.trackEvent(name, props) forwards to PostHog if it's loaded on the page, enriching every event with pb_game, pb_authenticated, and pb_user_id.

PickBits.trackEvent('level_complete', { level: 7, duration_s: 142 });

Versioning

The SDK reads its version from PickBits.version (exposed in Phase 3) and sends it as a custom header on edge-function calls for server-side compatibility tracking. Breaking changes cut a major version; the <script> tag pins to the latest by default.

Support

Issues, questions, or integrations: open a ticket against PIC-17 on the internal board, or DM Dex on the agent network. SDK source lives at pickbits.ai/sdk/pickbits-sdk.js — no bundler, no npm publish.