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:
| Auth | Token | Header | Used by |
|---|---|---|---|
| pk | pk_test_… / pk_live_… | Authorization: Bearer pk_… | Public login flows from the game client |
| sk | sk_test_… / sk_live_… | Authorization: Bearer sk_… | Server-to-server money + verification (never in the browser) |
| session | the user session access token | Authorization: Bearer <accessToken> | A signed-in player acting on their own wallet |
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.
{
"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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /auth/siws/challenge | pk | Issue a Sign-In-With-Solana challenge for a public key |
POST | /auth/siws/verify | pk | Verify a signed SIWS challenge → user + wallet + session |
POST | /auth/telegram/verify | pk | Verify Telegram Mini App initData → user + wallet + session |
POST | /auth/email/initiate | pk | Email a 6-digit one-time code to the address |
POST | /auth/email/verify | pk | Verify email + code → user + wallet + session |
POST | /auth/refresh | — | Exchange a refresh token for a fresh session (no key) |
POST | /auth/logout | — | Revoke a refresh token (204, best-effort) |
GET | /me | session | The 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /sessions/verify | sk | Verify 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | /wallets/me | session | The caller's active wallet |
GET | /wallets/:walletId/balance | session | Live SOL + SPL balances, tokens labelled with the app's currency codes |
POST | /wallets/:walletId/sign | session | Sign a base64 Solana transaction (idempotency-key aware) |
POST | /wallets/sign | sk | Sign 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/withdraw | session | On-chain transfer to a user-supplied address (needs idempotencyKey) |
GET | /wallets/:walletId/export/preflight | session | Whether self-custody export is currently allowed |
POST | /wallets/:walletId/export | session | Export 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /ledger/sessions | sk | Open a play session with a lock (201) |
POST | /ledger/bet | sk | Place a bet against the session balance |
POST | /ledger/win | sk | Credit a win, referencing its bet's transactionUuid |
POST | /ledger/rollback | sk | Reverse a bet (remembered if the bet is not yet seen) |
POST | /ledger/balance | sk | Current session balance |
POST | /ledger/settle | sk | Settle the session and net the payout |
GET | /ledger/reconcile | sk | Off-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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /treasury/deposit | sk | User's real wallet → treasury (implicit top-up) (201) |
POST | /treasury/withdraw | sk | Treasury → user's real wallet (explicit cash-out) |
POST | /treasury/status | sk | Resolve a move's on-chain fate by ref (for a game-side reconciler) |
POST | /treasury/balance | sk | Reconciliation: 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /custody/lock | sk | Lock one bet's stake into the pool escrow (201) |
POST | /custody/confirm | sk | Confirm a lock is backed by a committed bet (orphan guard) |
POST | /custody/settle | sk | Settle a whole pool atomically with rake + per-bet payouts |
POST | /custody/refund | sk | Refund every stake in a voided pool (symmetric with settle) |
POST | /custody/reconcile | sk | Release 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | /referrals/me | session | The player's own code, referrer, and balances |
POST | /referrals/attribute-self | session | Player attributes themselves with a captured code (best-effort no-op) |
GET | /referrals/share-links | session | The player's per-platform share URLs |
POST | /referrals/chain | sk | Resolve a user's upstream referral chain (up to 10 levels) |
POST | /referrals/code | sk | Ensure a referral code exists for a user |
POST | /referrals/attribute | sk | Attribute a user to a referrer by code |
POST | /referrals/payout | sk | Record a commission payout to one beneficiary (201) |
POST | /referrals/distribute | sk | Split one amount across chain levels by basis points |
POST | /referrals/balance | sk | A user's accrued referral earnings for a currency |
POST | /referrals/withdraw | sk | Withdraw 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.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /wallets/:walletId/export | session | Export the wallet to self-custody and re-provision a fresh custodial one |
Examples
Verify a session (server-to-server)
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
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
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
- Errors — the full code catalog and which are retryable.
- Webhooks — get pushed events instead of polling.
- Choose a money model — ledger vs treasury vs custody.