Casino Api Pro

Reference

Run it from your own servers

Everything the console can do, driven by an API key: catalogue, tournaments, promotions, risk, chat, the operational record, currencies and support — and the four things that deliberately stay behind a person.

Everything your team does in the console, your servers can do with an API key. Not a parallel implementation — the same code, with your credential recorded as the actor instead of a person, so the two cannot validate different things or audit differently.

Use the same bearer token as the rest of the API: see Authentication. Everything on this page is scoped to the account the key belongs to, so no endpoint takes an operator id.

Your catalogue

GET/v1/catalogueapi key

Your games rather than the public list: what is enabled, the release each game is pinned to, and the return that release actually pays. POST /v1/catalogue/{gameId}/rtp retunes the return, and PATCH /v1/catalogue/{gameId} takes everything the console does:

PATCH body

enabled
booleanoptional
Whether players can launch it at all.
min_bet / max_bet
string | nulloptional
Your stake limits. Null clears the override and returns the game to the platform's own limit; absent leaves it alone.
max_win
string | nulloptional
The most a single round may pay. Can only narrow the platform cap, never widen it — that ceiling is our risk budget rather than yours, so raising it stays an admin action.
release_id
uuid | nulloptional
Which certified release your players get. Must belong to this game and not be retired. Null returns you to the platform default.
thumbnail_url
string | nulloptional
Your own artwork. Must be https:// — the tile renders on a TLS page, so a plain-http image is blocked as mixed content and shows blank.
chat_enabled
booleanoptional
Whether the room has chat.
demo_players
integeroptional
Ambient players on the shared-round feed. Presentation only; 0–400.
feedback_enabled
booleanoptional
Whether players can rate the game.
limits
objectoptional
Per-currency limits, keyed by ISO 4217 — see below. A currency mapped to null clears its override.

Limits on a multi-currency account

min_bet, max_bet and max_win above carry no currency: they are compared directly against the stake. On a single-currency account that is exactly right. On an account holding two currencies two orders of magnitude apart it is not — a floor of "0.50" means 0.50 in both, and no single value is sensible for either.

So limits sets them per currency. Fields are independent: an entry with only min_bet leaves the game's own maximum in force for that currency. A currency with no entry behaves exactly as it always has.

bash
curl -X PATCH https://api.casinoapipro.com/v1/catalogue/$GAME_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "limits": {
      "GHS": { "min_bet": "0.50", "max_bet": "5000" },
      "NGN": { "min_bet": "500",  "max_bet": "50000" },
      "USD": null
    }
  }'

GET /v1/catalogue returns them under the same key, so you can read back what we hold rather than infer it from what you sent.

!These narrow, and a ceiling above ours is still a conversation

A per-currency limit is bounded by the same platform figures as the flat one, and that ceiling does not itself vary by currency yet. So you can raise a floor in a large-denomination currency freely — which is the half that was missing — but a maximum above the platform's own is refused, because it spends our exposure rather than yours. Ask us and we will look at it.

iNothing is converted

We do not hold a rate and never will: an exchange rate in the bet path is a number that goes stale and then silently moves every limit on your account. These are the figures you set, in the currency you set them in.

!Limits are checked against the release you are moving to

If you change release_id and the stake limits in one request, the limits are validated against the incoming release, not the one you are leaving. A minimum above the maximum, or a maximum win below the maximum bet, is refused rather than clamped — silently clamping means the number you typed is not the number you got.

iThe rtp you get back is the one that pays

Asking for 94% builds a configuration and the response tells you what that configuration actually returns, which can differ once multipliers are floored. Advertise the number in rtp, not the one in asked.

It is /v1/catalogue and not /v1/games because the launcher already owns /v1/games with a player token. The name is better anyway: this is your catalogue, and /v1/public/games is the platform's.

Promotions on a schedule

POST/v1/promotions/cashback/{ruleId}/runapi key

A weekly cashback period is a cron job, not a button. Create the rule once with POST /v1/promotions/cashback, then run it from your own scheduler.

iSafe to call twice

The run claims its window before computing anything, so a retry over the same period answers already_run: true and pays nobody. This matters more from a machine than from a button, because a machine retries on a timeout.

Referrals are a single settings row: POST /v1/promotions/referrals. Rain drops free bets into a game's chat for anyone to claim — POST /v1/rain — and claims are race-safe, one per player with the total capped in the same transaction.

!Both pay in free bets, never cash

We do not hold your float, so a cash credit issued here would be money promised on your behalf with nothing behind it. Read the computed amounts and pay cash through your own wallet if that is what you want.

Tournaments

POST/v1/tournamentsapi key

Body

name
stringrequired
Shown to players on the leaderboard.
scoring
enumoptional
One of TOTAL_WAGERED, NET_WIN, BIGGEST_MULTIPLIER, WIN_COUNT.
starts_at / ends_at
timestamprequired
Must end after it starts, and must not already have ended.
game_ids
uuid[]optional
Empty means every game in your catalogue. Each must be in it.
prizes
object[]required
One entry per rank. Ranks must be distinct — see below.

!Two prizes at rank 1 is not a tie

It is a table where settlement pays whichever row it finds first, and you have no idea which until it happens. Duplicate ranks are refused.

Prizes are frozen at creation: they cannot change once players are competing for them. Cancel with POST /v1/tournaments/{id}/cancel, which works only while the tournament is unsettled — a finished tournament has already paid, and un-happening that would leave grants in players' accounts for a competition we claim never ran.

GET /v1/tournaments returns yours plus the network tournaments your players can enter; editable tells you which are yours.

GET/v1/tournaments/{tournamentId}/leaderboardapi key

Standings, ranked, with prize and awarded_at filled in once a tournament has settled. On a network leaderboard only your own players are named —is_yours marks them, and another operator's player ids and turnover are not ours to hand over.

The risk queue

GET/v1/risk/eventsapi key

Signals, sorted worst-first, so the thing most worth looking at is never on page three. Mark one reviewed or dismissed with PATCH /v1/risk/events/{eventId}.

iA signal is a prompt to look, not a finding

These are deterministic rules, not machine learning, and nothing on this surface blocks a player or moves money. Dismissals are audited against the credential that made them: “who decided this was fine, and when” is the question an investigation opens with.

Chat moderation

POST/v1/chat/mutesapi key

GET /v1/chat/messages?flagged=true is the review queue — the messages the filter acted on, with the reason it acted. Mute a player for a number of minutes, or pass minutes: 0 to unmute. player_id accepts your own id for the player, which is what GET /v1/players returns.

POST/v1/chat/messages/{messageId}/removeapi key

Takes one message out of the room. It is scoped to your account in the lookup itself, so a guessed id from another operator answers 404 rather than removing anything. Removal is recorded, not destructive — the message stays in the record marked removed.

The operational record

GET /v1/api-logs
endpoint
What we saw you send — the first thing to check against what you believe you sent.
GET /v1/rounds/{roundId}/wallet-calls
endpoint
The other direction: every call we made to your wallet on a round, with your own response body verbatim. See below.
GET /v1/webhook-deliveries
endpoint
Every delivery, its attempt count, response status and error.
POST /v1/webhook-deliveries/{id}/retry
endpoint
Delivers now and returns the result, so a script draining a backlog after an outage knows whether it worked.
GET /v1/sla
endpoint
Uptime and response times against your plan, with the platform-wide figure beside yours.
GET /v1/feedback
endpoint
Player ratings and comments on your games.
GET /v1/notifications
endpoint
Account-wide notices. A key has no inbox of its own, so anything addressed to one person stays theirs.
POST /v1/notifications/read
endpoint
Marks them read. Send ids to mark specific ones, or no body at all to mark everything.

Is the shared flight in the air

GET/v1/catalogue/{gameId}/flightapi key

For Goal Jet and anything else where one round is shared across your players. The flight sleeps after about two minutes with nobody playing and wakes on the next session, so idle is normal rather than a fault — idle_seconds says how long, and never_flown means no round has ever run on your account.

iReading this does not wake it

Which is the point. The only way to see a flight used to be to mint a session and look through it, which both spends a session you may not use and starts the thing you were trying to measure — so a stopped flight could not be observed without ending the outage you were trying to confirm.

Reconciling a round

GET/v1/rounds/{roundId}/wallet-callsapi key

/v1/api-logs is what you sent us. This is the reverse, and it is the one you want when a round is disputed: every movement we raised on it, the request as we put it to your wallet, and your wallet's response body exactly as it came back — including wallet_reference and the balance it reported.

Addressed by your own round id or by our reference, so you can start from whichever you are holding.

iattempts above 1 is a retry, not a second movement

We retry a call that gave us no usable answer — a timeout, a 502 — always with the same transaction_id. That is what makes the retry safe, and why your wallet should answer the second one with duplicate: true and move no money. A round showing attempts: 3 and one movement is that working.

Currencies

PATCH/v1/businessapi key

A session in a currency your account does not hold is refused with CURRENCY_NOT_SUPPORTED, and this is how you add one without asking us.

bash
curl -X PATCH https://api.casinoapipro.com/v1/business \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"currencies":["USD","NGN","GHS"]}'

!Removing a currency players are registered in is refused

It would strand them: their sessions would start failing and there is no way back. Refused rather than cascaded — these are your players, and we do not get to decide which of them to break.

Sandbox wallets

POST/v1/sandbox/playersapi key

Play money, with no relationship to real funds. This is what makes an automated integration test possible: set a known balance, play, assert on the result.

Support

POST/v1/ticketsapi key

Useful from a monitor: the alert that noticed the problem can open the ticket about it. The ticket is labelled with the key that raised it, and we reply to your account owner — a credential has no address of its own.

GET/v1/tickets/{ticketId}api key

One ticket and its conversation in order. Our internal notes are never included: those are support talking to support, and they do not belong on your side of the thread.

POST/v1/tickets/{ticketId}/replyapi key

Adds a message and moves the ticket back to AWAITING_SUPPORT. A closed ticket is refused — open a new one rather than reviving a thread we have finished with.

What a key deliberately cannot do

Four things stay behind a person who has signed in. The test is not whether something is tedious in a browser — it is what an attacker gets if the key escapes.

  • Issuing, rotating or revoking credentials. A key that can mint keys turns one leak into permanent access, and one that can revoke them can lock you out of your own account.
  • Creating or repointing webhook endpoints. Where your events go is worth stealing. Reading the delivery log and retrying a delivery is on this side of the line; changing the destination is not.
  • Configuring your wallet. This is the outbound money path. A key that can change the base URL can redirect every debit and credit on the account.
  • Team and billing. Who may act on your account is a people decision, and a key that can promote a member could promote itself to owner.

iThis list is enforced by a test, not by a promise

A test reads both surfaces out of the source and fails if a console capability has no API counterpart and no stated reason. A new console feature that forgets the API is a broken build rather than a support ticket six months later.