API reference

Base URL https://api-wallet.iamgame.com/v1. Every path below is relative to it. All request and response bodies are JSON; every amount is an integer base-unit string (see Amounts are integers).

Authentication

Auth is a bearer token in the Authorization header. Which token depends on where the call runs — the three kinds map cleanly onto the endpoint groups below:

AuthTokenHeaderUsed by
pkpk_test_… / pk_live_…Authorization: Bearer pk_…Public login flows from the game client
sksk_test_… / sk_live_…Authorization: Bearer sk_…Server-to-server money + verification (never in the browser)
sessionthe user session access tokenAuthorization: Bearer <accessToken>A signed-in player acting on their own wallet
Environment is implied by the key
A pk_test_/sk_test_ key resolves the test environment (devnet); a pk_live_/sk_live_ key resolves live (mainnet). You never pass an environment parameter — it is derived from the key.

Error envelope

Any non-2xx response is a JSON envelope with a stable code. Branch on the code, not the message. Full catalog on the Errors page.

json
{
  "code": "ledger/insufficient_balance",
  "message": "insufficient session balance for bet",
  "details": { "balance": "100", "amount": "150" }
}

Auth

Player login. The /verify endpoints both create-or-fetch the user, provision a wallet on first sign-in, and return a session. See Authentication.

MethodPathAuthPurpose
POST/auth/siws/challengepkIssue a Sign-In-With-Solana challenge for a public key
POST/auth/siws/verifypkVerify a signed SIWS challenge → user + wallet + session
POST/auth/telegram/verifypkVerify Telegram Mini App initData → user + wallet + session
POST/auth/email/initiatepkEmail a 6-digit one-time code to the address
POST/auth/email/verifypkVerify email + code → user + wallet + session
POST/auth/refreshExchange a refresh token for a fresh session (no key)
POST/auth/logoutRevoke a refresh token (204, best-effort)
GET/mesessionThe signed-in user and their wallet

All three verify endpoints accept an optional referralCode and gameKey for first-touch referral attribution.

Sessions

The relying-party handshake: your game backend verifies a player’s wallet session and gets back a canonical identity, scoped to your app + environment. Mint your own app JWT off the result.

MethodPathAuthPurpose
POST/sessions/verifyskVerify a player session token → canonical user identity

Wallets

The signed-in player’s own wallet. Every route is session-authed and acts only on the caller’s wallet. See Withdraw & export.

MethodPathAuthPurpose
GET/wallets/mesessionThe caller's active wallet
GET/wallets/:walletId/balancesessionLive SOL + SPL balances, tokens labelled with the app's currency codes
POST/wallets/:walletId/signsessionSign a base64 Solana transaction (idempotency-key aware)
POST/wallets/signskSign for a named user from your backend — no player session needed. Requires the server-signing capability and a program allow-list, both set in the portal
POST/wallets/:walletId/withdrawsessionOn-chain transfer to a user-supplied address (needs idempotencyKey)
GET/wallets/:walletId/export/preflightsessionWhether self-custody export is currently allowed
POST/wallets/:walletId/exportsessionExport to self-custody (needs idempotencyKey)

Ledger

High-frequency off-chain play. All routes are sk-only; the browser must never reach win/settle. Amounts are integer base-unit strings; writes are idempotent on transactionUuid. See Ledger.

MethodPathAuthPurpose
POST/ledger/sessionsskOpen a play session with a lock (201)
POST/ledger/betskPlace a bet against the session balance
POST/ledger/winskCredit a win, referencing its bet's transactionUuid
POST/ledger/rollbackskReverse a bet (remembered if the bet is not yet seen)
POST/ledger/balanceskCurrent session balance
POST/ledger/settleskSettle the session and net the payout
GET/ledger/reconcileskOff-chain integrity report (200 ok / 409 with discrepancies)

Treasury

Custodial treasury — the real-money cash boundary. sk-only. On-chain movement happens only here; per-minute play stays off-chain in the ledger. currency is the app’s numeric currency id; every move carries a caller-supplied ref. See Treasury.

MethodPathAuthPurpose
POST/treasury/depositskUser's real wallet → treasury (implicit top-up) (201)
POST/treasury/withdrawskTreasury → user's real wallet (explicit cash-out)
POST/treasury/statusskResolve a move's on-chain fate by ref (for a game-side reconciler)
POST/treasury/balanceskReconciliation: user net position + treasury total

Custody

Real-money pool escrow (pari-mutuel). sk-only. Lock each stake into a pool, then settle or refund the whole pool atomically under a conservation guard. This is the wallet side of the game’s IWalletCustody seam. See Custody.

MethodPathAuthPurpose
POST/custody/lockskLock one bet's stake into the pool escrow (201)
POST/custody/confirmskConfirm a lock is backed by a committed bet (orphan guard)
POST/custody/settleskSettle a whole pool atomically with rake + per-bet payouts
POST/custody/refundskRefund every stake in a voided pool (symmetric with settle)
POST/custody/reconcileskRelease orphan locks past the timeout (ops/cron)

Custody routes are only mounted when the app’s pool-escrow model is enabled; a disabled app gets 404 for the whole group.

Referrals

Multi-level referrals across two access tiers. The player-facing routes are session-authed (build “invite friends” UI natively); the payout/chain routes are sk-authed. Payout writes are idempotent on idemKey. See Referrals.

MethodPathAuthPurpose
GET/referrals/mesessionThe player's own code, referrer, and balances
POST/referrals/attribute-selfsessionPlayer attributes themselves with a captured code (best-effort no-op)
GET/referrals/share-linkssessionThe player's per-platform share URLs
POST/referrals/chainskResolve a user's upstream referral chain (up to 10 levels)
POST/referrals/codeskEnsure a referral code exists for a user
POST/referrals/attributeskAttribute a user to a referrer by code
POST/referrals/payoutskRecord a commission payout to one beneficiary (201)
POST/referrals/distributeskSplit one amount across chain levels by basis points
POST/referrals/balanceskA user's accrued referral earnings for a currency
POST/referrals/withdrawskWithdraw a user's accrued earnings

Export

Self-custody export lives under the wallet path. session-authed; needs an idempotencyKey. Preflight first with /wallets/:walletId/export/preflight to check the balance floor.

MethodPathAuthPurpose
POST/wallets/:walletId/exportsessionExport the wallet to self-custody and re-provision a fresh custodial one

Examples

Verify a session (server-to-server)

bash
curl -X POST https://api-wallet.iamgame.com/v1/sessions/verify \
  -H "authorization: Bearer $SK" \
  -H "content-type: application/json" \
  -d '{ "sessionToken": "…" }'

Open a ledger session

bash
curl -X POST https://api-wallet.iamgame.com/v1/ledger/sessions \
  -H "authorization: Bearer $SK" \
  -H "content-type: application/json" \
  -d '{
    "userId": "usr_…",
    "gameCode": "crash",
    "currency": "USDC",
    "lockAmount": "1000000"
  }'

Settle a pari-mutuel pool

bash
curl -X POST https://api-wallet.iamgame.com/v1/custody/settle \
  -H "authorization: Bearer $SK" \
  -H "content-type: application/json" \
  -d '{
    "poolId": "pool_42",
    "currency": 3,
    "rake": "50000",
    "payouts": [
      { "betId": "bet_a", "userId": "usr_1", "payout": "1900000" }
    ]
  }'

Where to go next