PAR Sheets
A PAR sheet (Probability Accounting Report) is the mathematical blueprint for a slot game. It defines every possible symbol combination, its probability of occurring, and the payout for that combination. KINGSTONE uses PAR sheets to pre-compute outcome queues — the sequences of results that players receive when they spin.
Before you can register a game or execute spins, you need to upload at least one PAR sheet.
What a PAR Sheet Contains
A PAR sheet defines:
- Game metadata — title, manufacturer, number of reels, denomination
- Symbols — the icons that appear on each reel (e.g., Seven, Bar, Cherry)
- Prize tiers — groups of outcomes ranked by value (T0 = no win, T1-T6 = winning tiers)
- Combinations — every possible reel outcome with its probability, payout multiplier, and tier assignment
- Certified RTP — the expected Return-to-Player percentage (e.g., 92.5%)
PAR Sheet JSON Format
The upload endpoint accepts a JSON object with this structure:
{
"gameTitle": "Sandbox Classic 3-Reel",
"manufacturer": "Partner Test Studio",
"numReels": 3,
"virtualStopsPerReel": [32, 32, 32],
"certifiedRtp": 0.925,
"denominationUsd": 0.25,
"symbols": [
{ "name": "Seven", "display": "7" },
{ "name": "Bar", "display": "BAR" },
{ "name": "Cherry", "display": "CH" },
{ "name": "Plum", "display": "PL" },
{ "name": "Blank", "display": "BL" }
],
"tiers": [
{ "tierId": 0, "name": "No Win", "probability": 0.7, "payMultiplier": 0 },
{ "tierId": 1, "name": "Small Win", "probability": 0.15, "payMultiplier": 2 },
{ "tierId": 2, "name": "Medium Win", "probability": 0.08, "payMultiplier": 3 },
{ "tierId": 3, "name": "Large Win", "probability": 0.04, "payMultiplier": 4 },
{ "tierId": 4, "name": "Big Win", "probability": 0.02, "payMultiplier": 5 },
{ "tierId": 5, "name": "Huge Win", "probability": 0.008, "payMultiplier": 6 },
{ "tierId": 6, "name": "Jackpot", "probability": 0.002, "payMultiplier": 38.5 }
],
"combinations": [
{
"reelSymbols": ["Blank", "Blank", "Blank"],
"comboString": "BL|BL|BL",
"payMultiplier": 0,
"comboProbability": 0.7,
"tierId": 0,
"displayWeight": 1
},
{
"reelSymbols": ["Seven", "Seven", "Seven"],
"comboString": "7|7|7",
"payMultiplier": 38.5,
"comboProbability": 0.002,
"tierId": 6,
"displayWeight": 1
}
]
}A complete sample PAR sheet is available in the SDK repository at examples/sample-par-sheet.json.
Validation Rules
When you upload a PAR sheet, KINGSTONE validates the math:
- Tier probabilities must sum to 1.0. The total probability across all tiers must equal exactly 1.0 (within floating-point tolerance).
- Combination probabilities must match tier probabilities. The sum of
comboProbabilityfor all combinations in a tier must equal that tier'sprobability. - Certified RTP must match. The computed RTP (sum of probability times pay multiplier across all combinations) must match the declared
certifiedRtp. - Symbol references must be valid. Every symbol name in
combinations[].reelSymbolsmust match a symbol defined in thesymbolsarray. - Tier IDs must be valid. Every
tierIdin combinations must reference a tier defined in thetiersarray. - Reel count must be consistent. The length of
virtualStopsPerReeland everyreelSymbolsarray must equalnumReels.
If any validation fails, the API returns an error with details about what went wrong.
Uploading a PAR Sheet
With the SDK
import { KingstoneClient } from '@kingstone/sdk';
import parSheetData from './sample-par-sheet.json';
const client = new KingstoneClient({
apiKey: 'ks_sandbox_your_key_here',
sandbox: true,
});
const result = await client.uploadParSheet(parSheetData);
console.log(`PAR sheet created: ID ${result.parSheetId}`);
console.log(` Game: ${result.gameTitle}`);
console.log(` Reels: ${result.numReels}`);
console.log(` RTP: ${(result.certifiedRtp * 100).toFixed(2)}%`);
console.log(` Symbols: ${result.symbolCount}`);
console.log(` Tiers: ${result.tierCount}`);
console.log(` Combinations: ${result.combinationCount}`);With curl
curl -X POST https://sandbox.kingstone.dev/api/partner/v1/par-sheets \
-H "X-API-Key: ks_sandbox_your_key_here" \
-H "Content-Type: application/json" \
-d @sample-par-sheet.jsonListing PAR Sheets
After uploading, you can list all your active PAR sheets:
const { parSheets } = await client.listParSheets();
for (const sheet of parSheets) {
console.log(`${sheet.parSheetId}: ${sheet.gameTitle} (${sheet.numReels}-reel, RTP ${(sheet.certifiedRtp * 100).toFixed(2)}%)`);
}Next Steps
Once you have uploaded a PAR sheet, register a game to link it to a playable configuration with wager limits.
