Complete reference for the bz2api.js library.
Include the library in your project:
<script src="https://cdn.jsdelivr.net/gh/sevsunday/bz2api.js@1.0.0/bz2api.min.js"></script>
<script src="bz2api.js"></script>
const BZ2API = require('./bz2api.js');
// Basic usage - fetch all sessions
const result = await BZ2API.fetchSessions();
console.log(result.sessions);
// With enrichment options
const enriched = await BZ2API.fetchSessions({
enrichMaps: true, // Fetch map images/names
enrichVsrMaps: true // Add VSR map metadata
});
// Access session data
enriched.sessions.forEach(session => {
console.log(session.name, session.state);
console.log(session.players.map(p => p.name));
});
Fetches and parses all active multiplayer sessions.
| Option | Type | Default | Description |
|---|---|---|---|
enrichMaps |
boolean | false | Fetch map metadata (images, descriptions, team names) |
enrichVsrMaps |
boolean | false | Add VSR map data (pools, loose scrap, author) |
vsrMapData |
array | undefined | Custom VSR map data to override/merge with built-in data |
vsrMapDataMode |
string | undefined | Required with vsrMapData: 'replace' or 'merge' |
corsProxies |
array | Built-in list | Custom CORS proxy URLs (browser only) |
{
sessions: Session[], // Parsed session objects
timestamp: "ISO string", // Fetch timestamp
rawResponse: Object, // Original API response
dataCache: Object, // Consolidated player/mod data
enrichedMaps: boolean, // Whether map enrichment was used
enrichedVsrMaps: boolean // Whether VSR enrichment was used
}
Fetches raw API data without parsing. Useful for debugging or custom parsing.
const raw = await BZ2API.fetchRaw();
console.log(raw.GET); // Array of raw session objects
Fetches metadata for a specific map from the external assets API.
const mapData = await BZ2API.fetchMapData('rckcnynvsr', '1325933293');
// Returns: { name, description, image, teamNames, modNames }
Each session in the sessions array contains these fields:
| Field | Type | Description |
|---|---|---|
id | string | RakNet session ID |
guid | string | Decoded session GUID (hex) |
name | string | Session name |
version | string | Game version |
state | string | "PreGame", "InGame", or "PostGame" |
stateDetail | string | "waiting", "playing", "loading" |
gameType | string | "DM" or "STRAT" |
gameTypeName | string | "Deathmatch" or "Strategy" |
gameMode | string | "DM", "STRAT", or "MPI" |
gameModeName | string | Full mode name (e.g., "Team Strategy") |
isTeamGame | boolean | Whether teams are used |
mapFile | string | Map filename without extension |
mapName | string | Enriched map title (if available) |
mapImageUrl | string | Enriched map preview image URL |
players | Player[] | Array of player objects |
playerCount | number | Current player count |
maxPlayers | number | Maximum allowed players |
commanders | string[] | Names of commanders in the game |
hiddenPlayers | string[] | Names of hidden/lurking players |
mods | Mod[] | Array of mod objects |
primaryMod | string | Main mod ID |
isStock | boolean | Whether using stock (no mods) |
gameBalance | string | "Stock" or "VSR" |
hasPassword | boolean | Password protected |
isLocked | boolean | Session locked |
nat | object | NAT type info (id, name, canDirectConnect) |
steamJoinUrl | string | Steam protocol join URL |
tps | number | Ticks per second |
maxPing | number | Maximum allowed ping (ms) |
gameTimeMinutes | number | Game time elapsed |
timeLimitMinutes | number | Time limit (null if none) |
killLimit | number | Kill limit (null if none) |
VSR-specific fields (when enrichVsrMaps: true):
| Field | Type | Description |
|---|---|---|
vsrPools | number|null | Number of biometal pools |
vsrLoose | number|null | Amount of loose scrap |
vsrAuthor | string|null | Map author |
vsrMapSize | number|null | Map dimensions |
vsrBaseToBase | number|null | Distance between bases |
| Field | Type | Description |
|---|---|---|
name | string | Player display name |
rawId | string | Raw ID from API (e.g., "S76561198...") |
steamId | string|null | Steam ID (if Steam user) |
gogId | string|null | GOG Galaxy ID (if GOG user) |
platform | string | "Steam" or "GOG" |
profileUrl | string|null | Link to player's profile |
kills | number|null | Kill count |
deaths | number|null | Death count |
score | number|null | Score |
team | number|null | Team number (1 or 2) |
isHost | boolean | Is the session host |
isTeamLeader | boolean | Is a team leader |
isCommander | boolean | Is the commander |
isHidden | boolean | Is hidden/lurking |
The dataCache object consolidates unique players and mods across all sessions:
{
players: {
"76561198...": {
steamId: "76561198...",
profileUrl: "https://..."
}
},
mods: {
"1325933293": {
id: "1325933293",
name: "Vet Strat Recycler Variant",
workshopUrl: "https://..."
}
}
}
All options can be passed to fetchSessions() or fetchRaw():
const result = await BZ2API.fetchSessions({
// Map enrichment (external API calls)
enrichMaps: true,
// VSR map metadata (built-in data)
enrichVsrMaps: true,
// Custom VSR data (must specify mode)
vsrMapData: myCustomData,
vsrMapDataMode: 'merge', // or 'replace'
// Custom CORS proxies (browser only)
corsProxies: [
'https://myproxy.com/?url='
]
});
In browsers, the library automatically handles CORS by trying direct fetch first, then falling back to public proxies:
// Default proxies (used in order)
const CORS_PROXIES = [
'https://corsproxy.io/?',
'https://api.allorigins.win/raw?url=',
'https://api.codetabs.com/v1/proxy?quest='
];
// Override with custom proxies
BZ2API.fetchSessions({
corsProxies: ['https://my-proxy.com/?url=']
});
The library works in Node.js 18+ (native fetch) or with a fetch polyfill.
const BZ2API = require('./bz2api.js');
(async () => {
const result = await BZ2API.fetchSessions();
console.log(`Found ${result.sessions.length} sessions`);
result.sessions.forEach(s => {
console.log(`- ${s.name}: ${s.playerCount} players`);
});
})();
The library generates profile URLs for Steam and GOG players, but does not fetch avatars, nicknames, or other profile data. This is intentional:
The recommended architecture is to run bz2api.js on your server, enrich with Steam/GOG APIs, and expose your own endpoint:
[Rebellion API] → [Your Server] → [Your Client]
↓
[Steam API]
const express = require('express');
const BZ2API = require('./bz2api.js');
const STEAM_API_KEY = process.env.STEAM_API_KEY;
async function getSteamPlayerSummaries(steamIds) {
if (steamIds.length === 0) return {};
const url = `https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=${STEAM_API_KEY}&steamids=${steamIds.join(',')}`;
const response = await fetch(url);
const data = await response.json();
const players = {};
for (const player of data.response.players || []) {
players[player.steamid] = {
nickname: player.personaname,
avatar: player.avatarfull
};
}
return players;
}
const app = express();
app.get('/api/sessions', async (req, res) => {
try {
// Fetch and parse sessions
const result = await BZ2API.fetchSessions({ enrichMaps: true });
// Collect all unique Steam IDs
const steamIds = new Set();
for (const session of result.sessions) {
for (const player of session.players) {
if (player.steamId) steamIds.add(player.steamId);
}
}
// Fetch Steam data in bulk and enrich players
const steamData = await getSteamPlayerSummaries([...steamIds]);
for (const session of result.sessions) {
for (const player of session.players) {
if (player.steamId && steamData[player.steamId]) {
Object.assign(player, steamData[player.steamId]);
}
}
}
res.json(result);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(3000, () => console.log('Server running'));
const http = require('http');
const BZ2API = require('./bz2api.js');
const STEAM_API_KEY = process.env.STEAM_API_KEY;
async function getSteamPlayerSummaries(steamIds) {
if (steamIds.length === 0) return {};
const url = `https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=${STEAM_API_KEY}&steamids=${steamIds.join(',')}`;
const response = await fetch(url);
const data = await response.json();
const players = {};
for (const player of data.response.players || []) {
players[player.steamid] = {
nickname: player.personaname,
avatar: player.avatarfull
};
}
return players;
}
const server = http.createServer(async (req, res) => {
if (req.url === '/api/sessions' && req.method === 'GET') {
try {
const result = await BZ2API.fetchSessions({ enrichMaps: true });
// Collect and fetch Steam data
const steamIds = new Set();
for (const session of result.sessions) {
for (const player of session.players) {
if (player.steamId) steamIds.add(player.steamId);
}
}
const steamData = await getSteamPlayerSummaries([...steamIds]);
for (const session of result.sessions) {
for (const player of session.players) {
if (player.steamId && steamData[player.steamId]) {
Object.assign(player, steamData[player.steamId]);
}
}
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(result));
} catch (err) {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: err.message }));
}
} else {
res.writeHead(404);
res.end('Not Found');
}
});
server.listen(3000, () => console.log('Server running'));
bz2api.js library handles complex parsing including Windows-1252 character decoding, RakNet GUID unpacking, game mode bit fields, and team slot mapping. Using Node.js lets you leverage all this parsing directly. Other languages would require reimplementing this logic.
The library exports several constants for advanced use:
BZ2API.API_URL // Rebellion API endpoint
BZ2API.CORS_PROXIES // Default proxy list
BZ2API.MAP_API_BASE // Map assets API base URL
BZ2API.VSR_MOD_ID // VSR mod Steam ID
BZ2API.VSR_MAP_DATA_RAW // Built-in VSR map data array