CHART777 Game API
Offer CHART777 games on your own website. You call our API from your server; your players play inside an iframe; we charge stakes and pay wins through your wallet (seamless wallet). Base URL: https://chart777.com/api/v1/b2b
Overview
- Your server lists games (each has a permanent service id).
- When a player opens a game, your server creates a session and gets a launch URL.
- You show the launch URL in an iframe. The game calls your wallet for every stake and win.
- Each month you pay a share of your GGR (bets − wins) per game — see Pricing.
Getting access
Create a CHART777 account, open My CHART777 → API and apply with your company details. After approval you can create API keys, set your wallet URL and get the signing secret there. Keys and the secret are shown once — store them on your server only.
Authentication
Send your key in the X-Api-Key header on every request. Keys start with c777_live_. Never put a key in browser code.
curl https://chart777.com/api/v1/b2b/games \ -H "X-Api-Key: c777_live_••••••••"
Games and service ids
GET/api/v1/b2b/games
The games you can offer, with your cost rate and certification.
[
{
"serviceId": 1007,
"title": "Miners Fortune",
"rtp": 96.1,
"volatility": "high",
"rate": 0.10, // your cost: share of GGR
"certified": true,
"certLab": "…", "certNumber": "…"
}
]Launching a game
POST/api/v1/b2b/sessions
Create a session for one of your players. playerId is your own id for the player (we never see personal data). Amounts are integer minor units of currency (100 = 1.00).
POST /api/v1/b2b/sessions
X-Api-Key: c777_live_••••
Content-Type: application/json
{ "serviceId": 1007, "playerId": "p-123456", "currency": "USD", "locale": "en" }
→ 200
{ "sessionId": "cm…", "serviceId": 1007, "expiresAt": "2026-10-28T12:00:00Z",
"launchUrl": "https://chart777.com/embed/en/1007?session=…" }Show it in an iframe:
<iframe src="LAUNCH_URL" allow="autoplay; fullscreen" style="width:100%;aspect-ratio:16/9;border:0"></iframe>
A session lasts 2 hours by default; create a new one each time the player opens the game.
Seamless wallet
For every action the game sends a POST to your wallet URL (HTTPS). Verify the signature, apply the action, and answer with the player's balance.
POST https://your-site.example/chart777/wallet
X-Chart777-Timestamp: 1761400000
X-Chart777-Signature: hex(HMAC_SHA256(secret, timestamp + "." + rawBody))
{
"requestId": "…",
"action": "debit", // balance | debit | credit | rollback
"sessionId": "cm…", "playerId": "p-123456", "currency": "USD", "serviceId": 1007,
"roundId": "cm…",
"transactionId": "cm…:bet", // debit/credit/rollback only — unique, retried with the same id
"referenceTransactionId": "…", // rollback: the debit being reversed
"amount": 1000, // minor units
"roundFinished": true // on credit
}
→ 200 { "balance": 99000 }
→ 200 { "error": { "code": "INSUFFICIENT_FUNDS", "message": "Not enough balance" } }- balance — return the current balance.
- debit — take the stake. Refuse with
INSUFFICIENT_FUNDS,PLAYER_BLOCKEDorSESSION_EXPIREDwhen needed. - credit — add the win (also sent with
amount: 0to close a losing round). - rollback — return a debit that we could not confirm (no answer / timeout). If you never applied that debit, just answer with the balance.
- Idempotency: the same
transactionIdcan arrive more than once (we retry wins until you confirm). Apply it once and answer with the balance every time. - Reject requests whose timestamp is more than 5 minutes old or whose signature doesn't match.
- Answer within 8 seconds.
Signature check in Node.js:
import { createHmac, timingSafeEqual } from 'node:crypto';
const expected = createHmac('sha256', SECRET).update(req.headers['x-chart777-timestamp'] + '.' + rawBody).digest('hex');
const ok = timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-chart777-signature']));PHP:
$expected = hash_hmac('sha256', $_SERVER['HTTP_X_CHART777_TIMESTAMP'] . '.' . file_get_contents('php://input'), $secret);
$ok = hash_equals($expected, $_SERVER['HTTP_X_CHART777_SIGNATURE']);Rounds and usage
GET/api/v1/b2b/rounds?from=2026-10-01&to=2026-11-01&page=1
Your rounds, newest first (100 per page): bet, win, status (SETTLED, CREDIT_PENDING, FAILED) and the server seed hash for audits.
GET/api/v1/b2b/usage?month=2026-10
Per game and month: rounds, bets, wins, GGR, your rate and the cost.
{ "month": "2026-10", "totalCost": 12345,
"lines": [ { "serviceId": 1007, "currency": "USD", "rounds": 812, "bets": 4100000, "wins": 3920000,
"ggr": 180000, "rate": 0.10, "cost": 18000 } ] }Pricing
Cost = GGR × rate, per game and month (a month with negative GGR costs nothing for that game). Your rate is shown in /games and in your API page; it can differ per game. Invoices are issued monthly from the usage report.
Errors and limits
Errors use HTTP status codes and a JSON body { "ok": false, "error": { "code": "…", "message": "…" } }. Common codes: UNAUTHENTICATED (missing/invalid key), FORBIDDEN (account not active), VALIDATION_FAILED, GAME_UNAVAILABLE, RATE_LIMITED. Rate limit: 300 requests per minute per IP address.