# Reporting API > Turnover, GGR, per-game performance and one player's position, for your own systems. Source: https://casinoapipro.com/docs/reports 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. > **Available on Growth and above** > > A `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 ```bash curl https://api.casinoapipro.com/v1/reports/summary \\ -H "Authorization: Bearer $ACCESS_TOKEN" ``` ```json { "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. ```json { "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** > > A month is a small sample for a high-variance game. The advertised figure is a long-run expectation, not a promise about any particular month — a game running 110% over 225 rounds is ordinary. If it persists across tens of thousands of rounds, that is worth a ticket. ## 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. ```json { "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. ```bash 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: ```json { "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. ```bash 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.