Crédito disponível para abrir sessões de jogo.
- Saldo dos jogadores
- —
- Jogadores
- 0
Resumo da sua conta
Crédito disponível para abrir sessões de jogo.
últimos 14 dias
— no período
| Dia | Sessões |
|---|
Últimas ações registradas na sua conta
| Quando | Ação | Detalhe |
|---|
Crédito disponível para distribuir entre os jogadores.
Disponível apenas para administradores — um agente não pode creditar a própria conta.
| Quando | Tipo | Jogador | Valor | Saldo após | Referência |
|---|
O saldo acompanha as partidas: ao abrir uma sessão, o jogo carrega este valor e o devolve atualizado a cada rodada.
| Código | Nome | Moeda | Saldo | Status | Transferir |
|---|
Use-o para conferir o cabeçalho X-Webhook-Signature,
que é o HMAC-SHA256 do corpo recebido. Ele não será exibido de novo.
Enviamos eventos por POST em JSON. O endereço precisa usar HTTPS — sem TLS, o corpo e a assinatura trafegariam em claro.
Cada evento leva um eventId no corpo e no cabeçalho
X-Webhook-Id. Como reenviamos após falha, use-o para
descartar repetições. As tentativas se afastam progressivamente:
30s, 2min, 10min, 1h e 6h.
| Criado | Evento | Identificador | Status | Tentativas | Detalhe |
|---|
Catálogo
O RTP só pode ser ajustado nos jogos cujo motor já o utiliza. Os demais mostram o valor oficial do fabricante como referência.
A capa é cadastrada pelo administrador e vale para toda a
instalação: ela sai no catálogo público, em coverUrl,
para todos os operadores integrados. Clique na miniatura para
enviar um arquivo — PNG, JPEG, WebP ou GIF, até
512 KB.
| Capa | Jogo | Provedora | Oficial | RTP (%) | Ativo |
|---|
Apenas as sessões criadas com as suas credenciais.
| Jogo | Jogador | Moeda | Modo | Criada |
|---|
Ela não será exibida novamente — o servidor guarda apenas o resumo.
Use no cabeçalho Authorization: Bearer … ao criar sessões.
| Nome | Prefixo | Criada | Último uso |
|---|
A integração é uma API HTTP com corpo em JSON. Todo o fluxo cabe em
três passos: gerar uma chave, criar uma sessão de jogo para o seu
jogador e abrir a launchUrl devolvida.
agk_…. Ela aparece uma única vez.
POST /api/v1/sessions e abra a
launchUrl em um iframe ou em uma nova aba.
Endereço base de todas as chamadas:
{{origem}}
Só HTTPS é aceito em produção. As respostas de erro sempre trazem
error e, quando ajuda, message.
Toda rota /api/v1 que envolve sessão ou jogador exige a
chave no cabeçalho Authorization. O catálogo é público.
Authorization: Bearer agk_sua_chave_aqui
Content-Type: application/json
A chave pertence ao agente que a criou: sessões, jogadores e
transações de outro agente respondem 404, nunca
403 — assim a API não confirma a existência de tokens
alheios. Revogar a chave em Credenciais derruba
imediatamente as integrações que a usam.
Confere a credencial sem criar sessão. Útil no seu deploy.
curl -H "Authorization: Bearer agk_sua_chave_aqui" \
{{origem}}/api/v1/auth/me
{
"authenticated": true,
"type": "agent-api-key",
"agent": {
"id": 2,
"code": "operadora-x",
"name": "Operadora X",
"role": "agent",
"status": "active"
}
}
Rotas públicas, sem chave. Um jogo é identificado sempre pelo par
provider + gameId — o mesmo número pode
existir em provedoras diferentes.
Resposta de um jogo:
{
"provider": "popok",
"gameId": 332,
"code": "fortune_empire",
"name": "Fortune Empire",
"currency": "BRL",
"languages": ["pt-BR"],
"enabled": true,
"matrix": { "rows": 5, "columns": 6 },
"coverUrl": "{{origem}}/game-covers/popok/332?v=9f2c…"
}
currency e languages são fechados: a
criação da sessão recusa qualquer valor fora dessa lista.
A capa do jogo, para o lobby. Vem em coverUrl já
como endereço absoluto, e o campo só aparece nos jogos que têm
uma capa cadastrada — quem monta a vitrine não precisa de uma
segunda chamada. A rota é aberta, aceita
/{gameId}.png como sinônimo e responde a
If-None-Match.
O ?v= é a impressão digital do arquivo: quando a
capa é trocada no painel, o endereço muda junto e o cache do
navegador não tem como devolver a antiga. Guardar a URL sem ele,
ou copiar a imagem para o seu servidor, é abrir mão dessa troca.
| Jogo | provider | gameId | Situação |
|---|
POST /api/v1/sessions —
requer a chave. Responde 201 com a URL de lançamento.
curl -X POST {{origem}}/api/v1/sessions \
-H "Authorization: Bearer agk_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{
"provider": "popok",
"gameId": 332,
"playerId": "usuario-123",
"currency": "BRL",
"language": "pt-BR",
"mode": "demo",
"returnUrl": "https://seu-site.com/lobby"
}'
| Campo | Tipo | Descrição |
|---|---|---|
provider obrigatório |
string | Código da provedora, como popok ou pgsoft. |
gameId obrigatório |
inteiro | Identificador do jogo dentro da provedora. |
playerId obrigatório |
string (até 128) | Seu código de jogador. Se ele existir em Jogadores, o saldo cadastrado prevalece. |
currency |
string | Precisa ser a moeda do jogo. Padrão: a do catálogo. |
language |
string | Precisa constar em languages. Padrão: a primeira. |
mode |
demo | real |
Padrão demo. real exige carteira seamless. |
startingBalance |
número |
Saldo inicial em modo demo. Padrão 1000;
ignorado quando o jogador tem saldo no painel.
|
expiresInSeconds |
inteiro | Validade do token. Padrão 3600; limitado entre 60 e 86400. |
returnUrl |
URL | Para onde o jogo devolve o jogador ao sair. |
wallet |
objeto |
{"mode":"internal"} (padrão) ou a configuração
seamless descrita abaixo.
|
metadata |
objeto | Campos livres guardados na sessão. Algumas provedoras aceitam aqui uma URL de lançamento própria para diagnóstico; sem ela, o servidor gera a sua. |
201{
"sessionToken": "0hV4v0Nn…",
"game": { "provider": "popok", "gameId": 332, "name": "Fortune Empire" },
"playerId": "usuario-123",
"mode": "demo",
"launchUrl": "{{origem}}/play/0hV4v0Nn…?mode=demo&lang=pt-BR",
"expiresAt": "2026-08-10T21:00:00+00:00",
"walletMode": "internal"
}
Abra a launchUrl em um iframe ou redirecione
o jogador para ela. Não monte essa URL à mão e não reaproveite o
mesmo sessionToken para outro jogador: cada sessão é
amarrada ao jogo, ao jogador e à validade que você pediu.
<iframe src="LAUNCH_URL" allow="autoplay; fullscreen"
allowfullscreen width="100%" height="720"></iframe>
Você não precisa enviar nada disso: sem
metadata, o servidor monta o lançamento sozinho. Estes
campos existem para diagnóstico, quando você já tem uma URL emitida
pela provedora e quer usá-la. Se enviar uma fora do padrão, a sessão
é recusada em vez de abrir um jogo que não é o pedido.
Regras válidas para qualquer uma dessas URLs:
https, no máximo 8192 caracteres.https://user:senha@…).
O caminho tem de ser /{gameId}/index.html do próprio
jogo da sessão e a query precisa trazer o token ot.
Recusa: invalid_pg_launch_url.
{
"provider": "pgsoft",
"gameId": 2100928,
"playerId": "usuario-123",
"metadata": {
"pgLaunchUrl": "https://m.exemplo.com/2100928/index.html?ot=…&l=pt"
}
}
A resposta de sessões PG Soft traz também localUrl,
que abre o cliente servido daqui em vez do remoto.
Nos jogos que sabemos lançar sozinhos, deixe o campo de fora: o
servidor pede um lançamento novo à vitrine a cada sessão, porque a
URL expira em minutos. Se a vitrine não responder, a criação falha
com 502 evolution_launch_failed — repita a chamada.
Quando você mesmo informa a URL, ela é conferida contra o jogo e a
mesa da sessão; apontar para outra mesa, outro jogo ou outro host
devolve invalid_evolution_launch_url. Para o Bac Bo ao
vivo, o endereço tem de estar em
betconstructlatam.evo-games.com/frontend/evo/r2/ com
provider=evolution, game=bacbo,
table_id=BacBo00000000001 e um
ua_launch_id no fragmento.
Aceita apenas o Gem Roulette em modo fun, em
static-fun-stable.isoftbet.com, com
identifier=pulse_gem_roulette,
licenseId=1015 e funmode=true. Recusa:
invalid_isoftbet_launch_url.
Chicken Road 2, em
chicken-road-two.inout.games/api/modes/game, com
gameMode=chicken-road-two, o operatorId
da integração, um authToken e
currency igual à moeda da sessão — uma URL em outra
moeda abriria o jogo com valores que não batem com a carteira.
Recusa: invalid_inout_launch_url.
Opcionais no Aviator; sem eles a sessão usa as credenciais da demo. Não passam por validação de formato e não geram erro próprio.
Devolve os dados da sessão. O segredo da carteira nunca é exposto —
apenas mode e baseUrl.
Extrato das chamadas de carteira daquela sessão, para conciliação.
limit vai de 1 a 500 (padrão 100).
Diagnóstico do protocolo binário, disponível nas sessões PG Soft e Pragmatic. Campos sensíveis já vêm mascarados.
As três rotas exigem a chave e só enxergam sessões da sua própria conta.
internal: o saldo vive aqui e você o acompanha em
Jogadores. seamless: cada aposta e
prêmio bate na sua carteira em tempo real — obrigatório em
mode: "real".
{
"provider": "popok",
"gameId": 332,
"playerId": "usuario-123",
"mode": "real",
"wallet": {
"mode": "seamless",
"baseUrl": "https://seu-site.com/api/wallet/",
"token": "segredo-do-operador"
}
}
A baseUrl precisa ser HTTPS (HTTP só é aceito quando
aponta para localhost, em teste). O token volta para
você em Authorization: Bearer a cada chamada.
| Rota | Quando | Campos além dos comuns |
|---|---|---|
POST {baseUrl}balance |
Ao abrir o jogo e ao sincronizar | — |
POST {baseUrl}bet |
Débito da aposta | transactionId, roundId, amount |
POST {baseUrl}win |
Crédito do prêmio | transactionId, roundId, amount |
POST {baseUrl}rollback |
Rodada desfeita | transactionId, originalTransactionId, roundId |
Campos comuns a todas: sessionToken,
playerId, provider, gameId e
currency.
POST https://seu-site.com/api/wallet/bet
Authorization: Bearer segredo-do-operador
{
"sessionToken": "0hV4v0Nn…",
"playerId": "usuario-123",
"provider": "popok",
"gameId": 332,
"currency": "BRL",
"transactionId": "b7f1…",
"roundId": 4821,
"amount": 0.20
}
{ "success": true, "balance": 999.80 }
balance é obrigatório e é o saldo depois da
operação. Para recusar, responda
{"success": false, "code": "insufficient_funds", "message": "…"}
— a rodada é cancelada com essa mensagem. Um HTTP 5xx é tratado
como indisponibilidade temporária e pode ser repetido.
Cada transactionId é gravado e reenviado de forma
idempotente: se o mesmo chegar duas vezes, devolva o resultado da
primeira em vez de debitar de novo.
Configure a URL em Integração → Webhook. Enviamos
POST em JSON e guardamos a fila de entrega, com
reenvios em 30s, 2min, 10min, 1h e 6h.
Content-Type: application/json
X-Webhook-Event: session.created
X-Webhook-Id: 5f3c9a…
X-Webhook-Signature: sha256=9d2b…
{
"eventId": "5f3c9a…",
"event": "session.created",
"agentCode": "operadora-x",
"sentAt": "2026-08-10T20:31:00+00:00",
"data": { }
}
| Evento | Quando | data |
|---|---|---|
session.created |
Sessão de jogo criada com a sua chave |
sessionToken, playerCode,
provider, gameId,
gameCode, currency,
mode, balance
|
player.balance |
Saldo do jogador mudou durante a partida |
playerCode, sessionToken,
previousBalance, balance,
amount, kind
(bet ou win)
|
ping |
Botão Enviar teste do painel | message |
X-Webhook-Signature é o HMAC-SHA256 do corpo
exato que chegou, com o segredo do webhook.
Calcule sobre os bytes crus, antes de qualquer parse — reserializar
o JSON muda a assinatura.
// Node.js / Express
const bruto = req.body; // Buffer, via express.raw()
const esperado = "sha256=" + require("crypto")
.createHmac("sha256", SEGREDO_WEBHOOK)
.update(bruto)
.digest("hex");
const recebido = req.get("X-Webhook-Signature") || "";
if (!crypto.timingSafeEqual(Buffer.from(esperado), Buffer.from(recebido))) {
return res.sendStatus(401);
}
// PHP
$bruto = file_get_contents('php://input');
$esperado = 'sha256=' . hash_hmac('sha256', $bruto, SEGREDO_WEBHOOK);
if (!hash_equals($esperado, $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
Responda 2xx assim que receber e processe depois.
Como reenviamos após falha, o mesmo eventId pode
chegar duas vezes — guarde-o e descarte repetições.
{ "error": "seamless_wallet_required",
"message": "Sessões real exigem wallet.mode=seamless" }
| HTTP | error | Causa |
|---|---|---|
| 400 | invalid_request |
provider, gameId ou playerId ausente. |
| 400 | invalid_player_id |
Código vazio ou com mais de 128 caracteres. |
| 400 | unsupported_currency |
Moeda diferente da que o jogo opera. |
| 400 | unsupported_language |
Idioma fora de languages. |
| 400 | unsupported_mode |
Use demo ou real. |
| 400 | seamless_wallet_required |
Sessão real sem wallet.mode=seamless. |
| 400 | invalid_wallet_url |
baseUrl sem HTTPS fora de localhost. |
| 400 | invalid_metadata |
metadata enviado como algo que não é objeto. |
| 400 | invalid_pg_launch_url |
PG Soft
metadata.pgLaunchUrl fora do padrão descrito
acima.
|
| 400 | invalid_evolution_launch_url |
Evolution
metadata.evolutionLaunchUrl aponta para outro
jogo, outra mesa ou outro host.
|
| 400 | invalid_isoftbet_launch_url |
iSoftBet
metadata.isoftbetLaunchUrl fora do Gem
Roulette em modo fun.
|
| 400 | invalid_inout_launch_url |
InOut Games
metadata.inoutLaunchUrl sem
authToken, com outro operatorId
ou com moeda diferente da sessão.
|
| 401 | invalid_api_key |
Chave ausente, revogada ou de conta suspensa. |
| 403 | player_blocked |
Jogador bloqueado em Jogadores. |
| 404 | provider_not_found |
Provedora inexistente ou desativada. |
| 404 | game_not_found |
Jogo inexistente ou desativado. |
| 404 | session_not_found |
Token inválido, expirado ou de outro agente. |
| 502 | evolution_launch_failed |
Evolution A vitrine da provedora não devolveu um lançamento. Tente de novo; é uma falha temporária, não de payload. |
agk_… fica só no seu servidor — nunca no
navegador nem em aplicativo distribuído.2xx
rápido, guardando o eventId contra repetições.transactionId de forma
idempotente e devolve sempre balance.expiresInSeconds curto o bastante para a sua
operação.A troca encerra todas as sessões abertas do painel, inclusive esta.
| Quando | Agente | Ação | Detalhe | Origem |
|---|
| Código | Nome | Papel | Status | Último acesso |
|---|