Skip to Content
NOTE: StarWatch is in beta. We're actively improving these docs - check back for updates!
Get StartedJavaScript SDK

JavaScript SDK

Integrating JavaScript with StarWatch is a two-part process. First, your StarWatch instance needs to be created within the StarWatch Manager. Then the StarWatch SDK needs to be installed and integrated into your project.

Collect credentials

  1. Go to the manager site. 
  2. Select your team.
  3. Select Manage on the instance.
  4. Click to copy your app key, secret key (needed for server-side integration) and API URL.

Have these items ready to use for the installation process.

Install

Install the SDK from npm:

npm install starwatch-sdk

The package resolves to the correct build automatically based on your environment (browser or Node.js), so the same import works from either side:

import { initialize } from 'starwatch-sdk';

Initialize

Browser (client-side)

Client-side initialization uses Open Identification, so no secret key is required. Automatic fields such as FPS, platform, and device language are collected for you.

import { initialize } from 'starwatch-sdk'; initialize({ authType: 'open', appKey: '[YOUR_APP_KEY]', serverURL: '[YOUR_API_URL]', getUsers: () => [ { // `currentUser` is a placeholder — supply your own locally tracked user object userID: currentUser.id, level: currentUser.levelName, position: currentUser.position, countryCode: currentUser.countryCode, }, ], });
Tip

getUsers is called on every reporting tick. Return the latest position, level, and ID for each locally tracked user.

Node (server-side)

Server-side initialization requires both the app key and secret key, and reports on behalf of every connected player.

import { initialize } from 'starwatch-sdk'; initialize({ appKey: '[YOUR_APP_KEY]', secretKey: '[YOUR_SECRET_KEY]', serverURL: '[YOUR_API_URL]', getUsers: () => // `connectedPlayers` is a placeholder — supply your own list of connected players connectedPlayers.map((player) => ({ userID: player.id, level: player.levelName, position: player.position, deviceLang: player.deviceLang, fps: player.fps, platform: player.platform, countryCode: player.countryCode, })), });
Note

On Node, getUsers must supply every automatic field (deviceLang, fps, platform) yourself, since there’s no browser to infer them from.

Restricted Identification (player-issued tokens)

For multiplayer games where user IDs must be authorized by your game server, generate a per-player token on the server and hand it to the client instead of initializing the client with an app key.

Server, mint a token for the player:

import { authenticatePlayer } from 'starwatch-sdk'; const authorization = await authenticatePlayer(player.id); // Send `authorization` to the client over your own connection

Client, initialize with that token:

import { initialize } from 'starwatch-sdk'; initialize({ authType: 'federated', authorization, // received from your server serverURL: '[YOUR_API_URL]', getUsers: () => [ { userID: currentUser.id, level: currentUser.levelName, position: currentUser.position, countryCode: currentUser.countryCode, }, ], });
Note

authenticatePlayer requires the server to already be authenticated, so the server’s own initialize call must complete first.

Refresh the federated token before it expires and hand the client the new one:

import { onAuthorizationExpiringSoon, updateAuthorization } from 'starwatch-sdk'; onAuthorizationExpiringSoon(async () => { const authorization = await requestFreshTokenFromServer(); updateAuthorization(authorization); });

Submit game state

Note

This content is optional for seeing users move around the map, but required for event-based features.

Submit events

Learn what events do.

import { submitEvent } from 'starwatch-sdk'; submitEvent({ event: 'player_jumped', level: currentUser.levelName, userID: currentUser.id, });

Attach extra metadata to an event with extraDetails:

submitEvent({ event: 'damage_taken', level: currentUser.levelName, userID: currentUser.id, extraDetails: { amount: 25 }, });

Submit chat events

StarWatch provides specialized tracking for chat messages:

import { submitChatEvent } from 'starwatch-sdk'; submitChatEvent({ message: 'Hello world!', level: currentUser.levelName, userID: currentUser.id, });

Chat events can also carry moderation flags and metadata:

submitChatEvent({ message: 'This might be inappropriate', level: currentUser.levelName, userID: currentUser.id, flagged: true, annotation: 'Flagged by moderation system', tag: 'moderated-message', });

All parameters besides message, level, and userID are optional. flagged defaults to false.

Set gauges

Learn what gauges do.

import { setGauge, removeGauge } from 'starwatch-sdk'; // Update gauges only when the value changes setGauge({ gauge: 'health', userID: currentUser.id, value: currentUser.health, }); // Remove a gauge once it no longer applies removeGauge({ gauge: 'health', userID: currentUser.id, });

First login tracking

Report and look up when a user first played, independent of ongoing event/gauge telemetry.

Report a first login

import { reportFirstLogin } from 'starwatch-sdk'; reportFirstLogin({ userID: currentUser.id, // Optional: defaults to now if omitted firstLoginTime: Date.now(), });

Each user’s first login is only ever reported once; later calls for the same userID are ignored.

Query a first login

Available on Node only:

import { queryFirstLogin } from 'starwatch-sdk'; const result = await queryFirstLogin(player.id); if (result?.data) { console.log('First played at', new Date(result.data.time)); }

Handle SDK lifecycle events

Register callbacks to observe what the SDK is doing internally.

import { onAuthorizationExpiringSoon, onAuthStateChanged, onErrorLog, onFlush, } from 'starwatch-sdk'; // Fires whenever the SDK transitions between authenticated and unauthenticated onAuthStateChanged((isAuthed) => { console.log('Starwatch authenticated:', isAuthed); }); // Fires on any internal SDK error (failed requests, bad responses, etc.) onErrorLog((message) => { console.error('Starwatch error:', message); }); // Fires right before each periodic flush (every ~2 seconds) onFlush(() => { // Good place to sync any state your `getUsers` callback depends on, or to // batch setGauge/removeGauge calls right before the values are sent instead // of on every change }); // Browser-only: fires ahead of a federated token expiring (see Restricted // Identification above) onAuthorizationExpiringSoon(() => { // Request a fresh token and call updateAuthorization with it });