Sandbox — Referência completa da Seamless Wallet
Documentação campo a campo dos 8 endpoints do sandbox, com exemplos de request e response, dicas de integração, erros esperados, headers obrigatórios e injeção de falhas. Se você consegue rodar contra este ambiente, sua integração vai passar em produção sem surpresa.
Base URL
https://sandbox.i-gaming.co/api/public/v1/sandbox/walletTodos os endpoints ficam sob este prefixo. É público, roda no edge global, certificado TLS válido — sem VPN, sem allowlist.
Authentication
Cada request POST requires the header x-signature = HMAC-SHA256 do body cru, usando SANDBOX_WALLET_HMAC_SECRET. Sem assinatura ou com body alterado ⇒ 401 invalid_signature.
Idempotency
debit, credit e rollback exigem x-idempotency-key. Repita o mesmo header com o mesmo body para receber a resposta original — não duplica saldo.
Required headers
Todo POST passes through HMAC signature. GET (/stats, /reset) não exige assinatura.
HTTP Headers
| Field | Type | Required | Description & hint |
|---|---|---|---|
| content-type ex.: application/json | string | sim | Sempre application/json. Body precisa ser JSON minificado. Se o servidor rejeitar com invalid_signature mesmo com secret certo, garanta que você está assinando o MESMO byte-for-byte do que enviou (sem re-serializar). |
| x-signature ex.: 9ef2c1...b7a4 | string (hex) | sim | HMAC-SHA256 of the raw body, lowercase hex, 64 chars. Assine ANTES de qualquer transformação do body. Se usar interceptors HTTP, assine no último passo. |
| x-idempotency-key ex.: bet_round_2026_07_14_001 | string | no | Unique key per financial operation. Required on /debit /credit /rollback. Use o round_id + tipo (ex.: bet_r_123, win_r_123). Se falhar timeout, reenvie o MESMO header — a resposta será a original, sem duplicar. |
| x-timestamp ex.: 1783996311137 | int (unix ms) | no | Request timestamp in Unix milliseconds. Optional in the sandbox, recommended in production. Ajuda a debugar clock skew. Se seu clock estiver > 5 min do real, a integração em produção pode rejeitar. |
Endpoints
/authenticateOpen player session
Valida o launch token, cria/recupera o jogador no sandbox e devolve currency + timestamp. Chame no primeiro contato do launch iframe.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/authenticateRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Unique player identifier on your platform. Pode ser numérico ou UUID. O sandbox aceita qualquer string; guarde o mesmo user_id nas próximas chamadas. |
| token ex.: launch_token_demo | string | sim | Launch token issued by your backend. In the sandbox any non-empty string is accepted. Em produção, este token é validado por HMAC e tem TTL curto (5-15 min). Gere no momento do launch, não guarde em cache. |
| currency ex.: BRL | string (ISO-4217) | no | Session currency. Defaults to BRL. Supported: BRL, USD, EUR, ARS, MXN, AUD, MYR, PHP, VND, IDR, THB, JPY, KRW, INR and 30+ more. A moeda define a divisão em unidades menores (BRL/USD = centavos; JPY/KRW/VND = inteiro). |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| ok | boolean | sim | true = session created. |
| user_id | string | sim | Ecoa o user_id recebido. |
| currency | string | sim | Currency the sandbox assigned to this player. |
| ts | int (unix ms) | sim | Server timestamp at the moment of the response. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/authenticate
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"user_id": "player_42",
"token": "launch_token_demo",
"currency": "BRL"
}HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"user_id": "player_42",
"currency": "BRL",
"ts": 1783996311137
}Erros possíveis
{
"ok": false,
"error": "invalid_signature"
}- Chame /authenticate uma vez por sessão. Depois use /balance pra ler saldo.
- user_id novo? O sandbox cria com saldo inicial de 10 000 (unidades menores).
- token no sandbox aceita qualquer string; em produção precisa ser HS256 válido.
/balanceCheck balance
Retorna o saldo atual do jogador na moeda pedida. Não altera estado.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/balanceRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Player whose balance will be queried. |
| currency ex.: BRL | string | no | Balance currency. Defaults to BRL. Se o jogador não existe ainda, o sandbox cria com saldo inicial de 10 000 (unidades menores da moeda). |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| user_id | string | sim | Player queried. |
| balance | int | sim | Balance in minor units (cents for BRL). SEMPRE trate como inteiro. Dividir por 100 só na UI. Guardar como float é bug garantido. |
| currency | string | sim | Balance currency. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/balance
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"user_id": "player_42",
"currency": "BRL"
}HTTP/1.1 200 OK
content-type: application/json
{
"user_id": "player_42",
"balance": 10000,
"currency": "BRL"
}- 10000 = R$ 100,00 (BRL usa 2 casas decimais).
- Não use /balance pra decidir se pode debitar. O /debit já valida atomicamente — usar /balance antes cria race condition.
/debitDebit bet
Retira amount do saldo do jogador de forma atômica. Idempotente por x-idempotency-key. Retorna insufficient_funds sem alterar saldo se não há fundos.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debitRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Player placing the bet. |
| amount ex.: 100 | int (>=0) | sim | Bet amount in minor units. Always a positive integer. Amount = 0 é aceito (rodada bônus). Amount negativo é rejeitado. |
| currency ex.: BRL | string | sim | Bet currency. It must match the player's balance. |
| round_id ex.: round_2026_07_14_001 | string | sim | Game round ID. One round = 1 debit + 0..N credits + 0..1 rollback. Use o mesmo round_id no /credit e /rollback correspondentes — é como o sandbox relaciona bet ↔ win. |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| status | "ok" | "insufficient_funds" | "duplicate" | sim | Result of the operation. |
| balance_after | int | sim | Player balance after the debit. |
| operator_tx_id | string | sim | Internal ID generated by the sandbox to track the transaction. Guarde este ID nos seus logs. Útil pra debugar reconciliação. |
| idempotency_key | string | sim | Echoes the call's x-idempotency-key. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: bet_round_2026_07_14_001
{
"user_id": "player_42",
"amount": 100,
"currency": "BRL",
"round_id": "round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 9900,
"operator_tx_id": "op_a7f3c9b1",
"idempotency_key": "bet_round_2026_07_14_001"
}Erros possíveis
{
"status": "insufficient_funds",
"balance_after": 50,
"operator_tx_id": "op_...",
"idempotency_key": "bet_..."
}{
"status": "duplicate",
"balance_after": 9900,
"operator_tx_id": "op_a7f3c9b1",
"idempotency_key": "bet_round_2026_07_14_001"
}- Ao receber timeout/5xx, reenvie o MESMO x-idempotency-key. Nunca gere uma nova.
- duplicate NÃO é erro — significa que a operação original foi aplicada e você está seguro.
- Se seu jogador clica 3x em spin, o mesmo idempotency-key protege de débito duplicado.
/creditCredit prize
Adiciona amount ao saldo do jogador (win, cashout, bônus). Idempotente. bet_id liga ao /debit original.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/creditRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Player who will receive the win. |
| amount ex.: 250 | int (>=0) | sim | Win amount in minor units. |
| currency ex.: BRL | string | sim | Win currency. |
| bet_id ex.: bet_round_2026_07_14_001 | string | sim | x-idempotency-key of the /debit that produced this win. Sem bet_id o sandbox aceita (retorna ok), mas em produção você quer sempre ligar win ↔ bet pra reconciliação. |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| status | "ok" | "duplicate" | sim | Resultado. |
| balance_after | int | sim | Player balance after the credit. |
| operator_tx_id | string | sim | Internal sandbox ID. |
| idempotency_key | string | sim | Ecoa o x-idempotency-key. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/credit
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: win_round_2026_07_14_001
{
"user_id": "player_42",
"amount": 250,
"currency": "BRL",
"bet_id": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 10150,
"operator_tx_id": "op_e2d4a8f0",
"idempotency_key": "win_round_2026_07_14_001"
}- amount = 0 é aceito (rodada sem prêmio ainda gera evento pra fechar contabilidade).
- Vários /credit no mesmo bet_id são permitidos (freespins, respins). Use idempotency-key distinta em cada.
/rollbackUndo operation
Reverte um /debit (devolve valor ao jogador) ou um /credit (retira valor do jogador). Só funciona uma vez por original_key.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/rollbackRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| original_key ex.: bet_round_2026_07_14_001 | string | sim | x-idempotency-key of the original operation you want to undo. Rollback só funciona uma vez por original_key. A segunda tentativa retorna status=already_rolled_back. |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| status | "ok" | "not_found" | "already_rolled_back" | sim | Rollback result. |
| balance_after | int | sim | Balance after the rollback (credit reversed, debit refunded). |
| reverted_amount | int | sim | Valor devolvido/removido. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/rollback
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: rb_bet_round_2026_07_14_001
{
"original_key": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 10000,
"reverted_amount": 100
}Erros possíveis
{
"status": "not_found",
"balance_after": 10000,
"reverted_amount": 0
}{
"status": "already_rolled_back",
"balance_after": 10000,
"reverted_amount": 0
}- Use rollback quando o motor de jogo confirmar que a rodada não completou (crash da RNG, timeout no client, disputa).
- Não use rollback pra reajustar prêmio — use um novo /credit ou /debit compensatório com bet_id/round_id auditáveis.
/queryConsult operation
Busca o status de qualquer operação pela sua idempotency_key. Use pra reconciliação, auditoria e recuperação de timeouts.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/queryRequest — body / query
| Field | Type | Required | Description & hint |
|---|---|---|---|
| idempotency_key ex.: bet_round_2026_07_14_001 | string | sim | Key of the operation you want to look up (bet, win or rollback). Use este endpoint como reconciliação diária: liste seus rounds locais, consulte cada um, compare status/amount. |
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| found | boolean | sim | false = no operation exists with that key. |
| kind | "debit" | "credit" | "rollback" | no | Operation type. |
| status | "ok" | "rolled_back" | no | Estado atual. |
| amount | int | no | Operation amount. |
| user_id | string | no | Affected player. |
| round_id | string | no | Rodada relacionada. |
| balance_after | int | no | Player balance right after the operation. |
| processed_at | ISO-8601 | no | When the operation was processed in the sandbox. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/query
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"idempotency_key": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"found": true,
"kind": "debit",
"status": "ok",
"amount": 100,
"user_id": "player_42",
"round_id": "round_2026_07_14_001",
"balance_after": 9900,
"processed_at": "2026-07-14T02:31:52.812Z"
}- Timeout no /debit? Chame /query com a mesma key: se found=true e status=ok, a aposta foi aplicada — não retente.
- Passe ?div_rate=1 pra forçar o sandbox devolver dados divergentes e treinar seu código de reconciliação.
/statsAggregated statistics
Retorna métricas agregadas do estado atual do sandbox (útil pra dashboards de load test).
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/statsRequest — body / query
Sem parâmetros — envie apenas os headers (HMAC não é exigido em GET).
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| ok | boolean | sim | true = stats available. |
| stats.users | int | sim | Total players created in the sandbox. |
| stats.ops | int | sim | Total operations (debit + credit + rollback). |
| stats.balance | int | sim | Sum of every player's balance. |
| stats.totalDebit | int | sim | Total apostado. |
| stats.totalCredit | int | sim | Total paid out in winnings. |
| stats.rtp | float | sim | RTP observado (totalCredit / totalDebit). Use pra sanity check. Rodou 1000 apostas de R$10 e o RTP saiu 0.35? Volume baixo — não é bug do jogo, é variância. |
| now | int (unix ms) | sim | Server timestamp. |
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/stats
HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"stats": {
"users": 3,
"ops": 28,
"balance": 30550,
"totalDebit": 2400,
"totalCredit": 550,
"rtp": 0.229
},
"now": 1783996311137
}- Não exige HMAC. Endpoint público de leitura.
- Rode /stats antes e depois de um teste de carga pra medir throughput e RTP.
/resetClear sandbox state
Apaga todos os jogadores, saldos e operações. Use quando quiser começar um teste do zero.
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/resetRequest — body / query
Sem parâmetros — envie apenas os headers (HMAC não é exigido em GET).
Response — 200 OK
| Field | Type | Required | Description & hint |
|---|---|---|---|
| ok | boolean | sim | true = estado limpo. |
| reset | boolean | sim | true = the reset was confirmed. |
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/reset
HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"reset": true
}- Reset é global no sandbox — todo mundo compartilha. Combine com sua equipe antes de rodar.
- Em produção não existe /reset. Não escreva código que dependa de resetar estado.
Fault injection (query string)
Adicione estes parâmetros na URL de qualquer endpoint POST para simular condições reais de produção — latência alta, 5xx, timeouts, divergências. Ideal pra testar sua camada de retry, idempotência e reconciliação.
Query parameters
| Field | Type | Required | Description & hint |
|---|---|---|---|
| lat_min ex.: 50 | int (ms) | no | Minimum artificial latency added before responding. Combine com lat_max pra simular jitter real de rede. |
| lat_max ex.: 800 | int (ms) | no | Maximum artificial latency. The sandbox picks a value between lat_min and lat_max. lat_max=800 aproxima de latência de emergência real. lat_max=3000 estressa timeouts. |
| err_rate ex.: 0.1 | float 0..1 | no | Probability of returning HTTP 500 injected_5xx. 0.1 = 10% das chamadas. Ideal pra validar sua camada de retry. |
| timeout_rate ex.: 0.05 | float 0..1 | no | Probability that the response takes 10 s (forces the client timeout). Use pra validar que seu client cancela a request e depois faz /query pra recuperar o estado real. |
| insuff_rate ex.: 0.02 | float 0..1 | no | Probability that /debit returns insufficient_funds even with balance available. Simula usuário que ficou zerado entre o /balance e o /debit. Teste sua UX de erro. |
| div_rate ex.: 0.1 | float 0..1 | no | Probability that /query returns data that differs from the real state. Serve pra estressar sua rotina de reconciliação — o valor real está no /stats. |
| rtp ex.: 0.97 | float 0..2 | no | Informational target RTP (does not change operation results; useful only in dashboards). |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit?lat_max=800&err_rate=0.1&timeout_rate=0.05
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: bet_stress_001
{"user_id":"player_42","amount":100,"currency":"BRL","round_id":"r_stress_001"}Status codes
Todo erro estruturado vem no body como { "ok": false, "error": "..." } ou como status dentro de uma resposta 200.
| Code | When it happens | What to do |
|---|---|---|
| 200 OK | Operação processada com sucesso. | Leia o campo status do body — pode ser ok, duplicate, insufficient_funds, etc. |
| 401 invalid_signature | x-signature ausente ou HMAC não bate com o body cru. | Verifique: (a) secret correto, (b) você está assinando o body byte-a-byte do que envia, (c) hex minúsculo. |
| 404 unknown_kind | Path final não é um dos endpoints suportados. | Confira o path — case-sensitive, sem barra final. |
| 405 use POST | Endpoint que exige POST recebeu GET. | Só /stats e /reset aceitam GET. Todos os outros são POST. |
| 500 injected_5xx | Falha injetada via err_rate. | Retente com backoff exponencial. Mesmo x-idempotency-key. |
| 500 error (real) | Erro inesperado (DB, RPC). Raro. | Guarde o response body. Rode /query com a mesma idem-key pra ver se aplicou. Contate suporte. |
Pronto pra integrar?
Baixe a Postman collection com todos os endpoints já configurados e pre-request script que assina HMAC automaticamente. Rode contra o sandbox, valide sua integração, depois fale com a gente pra ir pra produção.