Integrate
Reporting API
Turnover, GGR, per-game performance and one player's position, for your own systems.
Turnover, GGR, per-game performance and one player's position — the same numbers the dashboard shows, for your own BI stack. Authenticated with an ordinary API credential.
iAvailable on Growth and above
403 here means your plan does not include the reporting API, and the message names the plan that does. Everything on this page is also visible in the dashboard on every plan — this is about getting it into your own systems.There is no environment parameter
A credential is issued for sandbox or for live, and that is the environment its reports cover. Taking it from the query string would let a sandbox key read live figures, which is a data leak dressed up as a filter. Use the credential for the environment you want.
Windows
Every endpoint takes from and to, defaults to the last 30 days, and echoes back the window it actually used — a report whose period you have to infer cannot be reconciled against anything. Windows are capped at 366 days; a longer request is refused rather than silently clamped, because a total quietly missing half its rows is worse than an error.
Summary
curl https://api.casinoapipro.com/v1/reports/summary \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"window": { "from": "2026-08-01T00:00:00.000Z", "to": "2026-08-31T00:00:00.000Z" },
"environment": "SANDBOX",
"total_bets": "4918.60",
"total_wins": "4199.92",
"ggr": "718.68",
"round_count": 562,
"active_players": 44,
"currency_breakdown": [{ "currency": "USD", "bets": "4918.60", "ggr": "718.68" }]
}Per game
GET /v1/reports/games. Each row carries the return players actually got alongside what the game advertises.
{
"data": [{
"slug": "dice",
"rounds": 225,
"total_bet": "81.30",
"ggr": "-8.23",
"realised_rtp": "110.12",
"advertised_rtp": "97.000"
}]
}!Expect these to differ, and do not alert on it
Daily series
GET /v1/reports/daily — one row per UTC day with rounds, active players, turnover and GGR. Bucketed in UTC so a day means the same thing in every report you reconcile it against.
Every day in the window is returned, including the ones on which nothing happened. A series that omits its quiet days cannot be told apart from one with rows missing, and anything charting it will draw a straight line through the gap.
Bucketed series
GET /v1/reports/series — the same figures grouped by granularity=day|week|month. Omit it and the bucket is chosen from the length of the window; either way the response says which was used, so a caller never has to infer it.
{
"window": { "from": "2024-01-01T00:00:00.000Z", "to": "2026-09-21T00:00:00.000Z" },
"currency": "GHS",
"granularity": "month",
"data": [{ "date": "2024-01-01", "bets": "0.00", "wins": "0.00", "ggr": "0.00", "rounds": 0 }]
}Weeks start on Monday, in UTC. This endpoint is capped at 400 buckets rather than at 366 days: a monthly series over five years is sixty rows and costs less to serve than a year of daily ones, so a day limit would have refused the cheap request and allowed the expensive one.
How far back the data goes
GET /v1/reports/bounds — the first and last settled activity for the credential’s environment, as first and last, or null on an account that has not traded yet. It is what “all time” means: without it, asking for everything means guessing a start date, and guessing early means asking us to scan years that never existed.
One player
GET /v1/reports/players/:playerId, addressed by your own player id — the one you supplied when you created the session, not ours. Requiring you to store and map our uuid to call your own reporting would be a join we imposed on you for no reason.
curl "https://api.casinoapipro.com/v1/reports/players/player-42?include_rounds=true&limit=100" \
-H "Authorization: Bearer $ACCESS_TOKEN"With include_rounds, every round carries the mathematics it was settled on:
{
"position": { "rounds": 101, "total_bet": "50.00", "ggr": "-2.49", "realised_rtp": "104.98" },
"rounds": {
"total": 101,
"data": [{
"round_id": "rnd_buj5wurfbuh6kkqzvjrf",
"game": "dice",
"bet": "40.00",
"win": "42.80",
"release": "1.0.0",
"release_rtp": "97.000",
"server_seed_hash": "24728ed9fc41…",
"played_at": "2026-08-31T01:45:59.000Z"
}]
}
}release and server_seed_hash are what make a disputed round answerable: the first says which certified parameter set paid it, the second lets the player verify the draw themselves.
Money is strings
Every amount is a decimal string, never a float. These numbers go into ledgers and invoices; handing back a value that has already lost precision, for you to parse into another float, is how two systems end up disagreeing by a cent and neither can say which is right. Parse them with a decimal type.
Your account’s audit log
GET /v1/reports/audit — every recorded action on your account, newest first: sign-ins, role changes, key rotations, invitations, plan activations. action is a prefix, so team. returns the whole family and dashboard.login returns just the sign-ins. Each row carries who did it, what they did it to, the source address, and a metadata object holding the before and after.
Secrets are redacted where each entry is written rather than on the way out — a password change records that it happened and never what it became — so what you read here is the whole record, not a filtered view of one.
curl "https://api.casinoapipro.com/v1/reports/audit?action=team.&limit=20" \
-H "Authorization: Bearer $ACCESS_TOKEN"Throughput
- 60 requests a minute, well under the transaction endpoints — a runaway BI job must not crowd out live play.
- Reports are aggregates over your whole history. Cache them; do not poll them per page view.