Round replay
An operator can request a link (POST /v1/operator/rounds/replay, documented in the operator docs) that opens a page replaying one of your game's rounds — reels spinning, balance updating, in the sequence the player originally saw. The platform brokers the link and verifies the operator actually owns the round; everything about recording and rendering the replay itself is your responsibility. The platform never sees your game's visual outcome, only the money movements (BET/WIN/ROLLBACK) you submit — there's nothing for it to replay from.
This means replay support is opt-in, and only rounds played after you add recording are replayable — there's no way to retroactively reconstruct a round whose visual data was never captured.
What you need to build
- Record, at spin time, an ordered event timeline for the round, keyed by the same
roundIdyou submit transactions under. Persist it (a DB table, object storage, ...) — not just in memory, unless you're fine with replay links only working until your process restarts. - Configure a replay page base URL for your game with the platform team (
GameSummary.replayBaseUrl) — the same waylaunchBaseUrlis configured. A game with noreplayBaseUrlconfigured makes the operator's replay-link request fail with400. - Implement a
GETroute at that URL. It receives a?replay=query parameter — resolve it withverifyReplay, look up the resultingroundIdin your own storage, and render a page that plays the recorded timeline back.
Resolving the token
import { ProviderClient } from '@moosehq/provider-sdk'
const client = new ProviderClient({
baseUrl: process.env.PLATFORM_URL!,
tenantId: 'acme-studio',
secret: process.env.PLATFORM_SECRET!,
})
app.get('/replay', async (req, res) => {
const replayToken = req.query.replay as string
let verified
try {
verified = await client.verifyReplay(replayToken)
} catch (err) {
// PlatformApiError with status 401 (unknown/expired token) or 403
// (token minted for a different provider — shouldn't happen in
// practice, but don't trust the token blindly either way).
return res.status((err as { status?: number }).status ?? 502).send('replay link invalid or expired')
}
const log = await replayStore.get(verified.roundId)
if (!log) return res.status(404).send('replay not found')
res.send(renderReplayPage({ roundId: verified.roundId, locale: verified.language, log }))
})verifyReplay is a signed, retried call just like verifySession — see the ProviderClient reference. A 401 means the token is unknown or past its expiry window (15 minutes by default) — surface that as "this replay link has expired," not a generic error, since it's an expected outcome for an old link, not a bug.