Skip to content

Compliance & RTP

KINGSTONE provides built-in compliance tools for monitoring Return-to-Player (RTP) accuracy and generating audit evidence. As a partner, you can track RTP for every game, verify audit chains, and download compliance certificates.

How RTP Compliance Works

Every game has a certified RTP defined by its PAR sheet (for example, 92.5%). KINGSTONE pre-computes outcome queues that match this certified RTP. After outcomes are served to players, the actual RTP is calculated from real play data.

KINGSTONE compares actual RTP against certified RTP using a 2% tolerance. If the actual RTP is within 2 percentage points of the certified value, the game is marked as compliant.

Certified RTPActual RTPVarianceStatus
92.50%92.48%-0.02%Compliant
92.50%91.80%-0.70%Compliant
92.50%89.50%-3.00%Non-compliant

Per-Game RTP Tracking

Get detailed RTP data for a specific game:

typescript
import { KingstoneClient } from '@kingstone/sdk';

const client = new KingstoneClient({
  apiKey: 'ks_sandbox_your_key_here',
  sandbox: true,
});

const rtp = await client.getRtpCompliance(1); // gameId

console.log(`Game: ${rtp.displayName} (${rtp.configName})`);
console.log(`Certified RTP: ${(rtp.certifiedRtp * 100).toFixed(2)}%`);
console.log(`Actual RTP: ${rtp.latestActualRtp !== null ? (rtp.latestActualRtp * 100).toFixed(2) + '%' : 'No data yet'}`);
console.log(`Variance: ${rtp.latestVariance !== null ? (rtp.latestVariance * 100).toFixed(4) + '%' : 'N/A'}`);
console.log(`Compliant: ${rtp.isCompliant ? 'Yes' : 'NO'}`);
console.log(`Total plays: ${rtp.totalPlays}`);
console.log(`Total blocks: ${rtp.totalBlocks}`);

The response also includes a blocks array with per-block RTP history:

typescript
for (const block of rtp.blocks) {
  console.log(`  Block ${block.blockSequenceNumber}: RTP ${(block.rtpActual * 100).toFixed(2)}% (variance ${(block.rtpVariance * 100).toFixed(4)}%) — ${block.blockStatus}`);
}

Compliance Summary

Get a high-level overview of all your games:

typescript
const summary = await client.getComplianceSummary();

console.log(`Total games: ${summary.totalGames}`);
console.log(`Compliant: ${summary.compliantGames}/${summary.totalGames}`);

for (const game of summary.games) {
  const status = game.isCompliant ? 'OK' : 'ALERT';
  const actualStr = game.latestActualRtp !== null
    ? (game.latestActualRtp * 100).toFixed(2) + '%'
    : 'No data';
  console.log(`  [${status}] ${game.displayName}: certified ${(game.certifiedRtp * 100).toFixed(2)}%, actual ${actualStr}`);
}

Compliance Certificates

For regulatory submissions, you can generate a compliance certificate for any game. The certificate includes all RTP data, block history, and a deterministic certificate ID.

typescript
const cert = await client.getComplianceCertificate(1); // gameId

console.log(`Certificate ID: ${cert.certificateId}`);
console.log(`Issued: ${cert.issuedAt}`);
console.log(`Issuer: ${cert.issuer}`);
console.log(`Game: ${cert.displayName}`);
console.log(`Certified RTP: ${(cert.certifiedRtp * 100).toFixed(2)}%`);
console.log(`Actual RTP: ${cert.actualRtp !== null ? (cert.actualRtp * 100).toFixed(2) + '%' : 'No data'}`);
console.log(`Compliant: ${cert.isCompliant}`);
console.log(`Tolerance: ${cert.rtpTolerancePercent}%`);
console.log(`Blocks analyzed: ${cert.totalBlocksAnalyzed}`);
console.log(`Total plays: ${cert.totalPlays}`);

The certificate ID is deterministic — the same game at the same point in time always produces the same certificate ID. This makes it suitable for regulatory record-keeping.

Audit Trail Verification

Every spin creates a SHA-256 hash-chained audit record. You can verify the integrity of the entire chain to confirm that no records have been modified or deleted.

typescript
const verification = await client.verifyAuditChain(1); // gameId

console.log(`Chain valid: ${verification.isValid}`);
console.log(`Sessions verified: ${verification.sessionsVerified}`);
console.log(`Broken links: ${verification.brokenLinks.length}`);

if (!verification.isValid) {
  console.log(`Broken at indices: ${verification.brokenLinks.join(', ')}`);
}

You can also retrieve the raw audit log for your own analysis:

typescript
const { sessions } = await client.getAuditLog({
  gameConfigId: 1,
  page: 1,
  limit: 50,
});

for (const session of sessions) {
  console.log(`  Session ${session.sessionId}: SPP ${session.sppValue}, tier T${session.prizeTierId}, payout $${session.payoutUsd.toFixed(2)}`);
  console.log(`    Hash: ${session.auditHash.slice(0, 16)}...`);
}

Why This Matters for Partners

  • Regulatory submissions — Use compliance certificates and audit verification to demonstrate mathematical fairness to regulators.
  • Player trust — The deterministic, auditable system proves that outcomes are not manipulated.
  • Dispute resolution — If a player disputes an outcome, the audit trail provides complete evidence of what happened and why.
  • Continuous monitoring — Track RTP drift in real time and catch anomalies early.

Next Steps

KINGSTONE by Predigy Inc.