Settle
Live{base}/api/settleUsually sent after /bet succeeds, with the round result. Credit amount to the player's wallet. The exception is a single-state round, which has no prior /bet: the bet and its result arrive together in this call.
Process the whole txns[] batch in one DB transaction (atomic) — if any txn fails, roll back the batch and reply an error with balance_before == balance_after
If the same txn_id arrives again, do not apply it a second time; reply the current balance with code 0, or reply 20002. The only exception is a transaction that follows a /rollback of that round: it carries a corrected result and must be applied (see "re-settle after rollback" on the Contract page).
A 0 amount is real — a feature spin, a bought feature, a tip, or a stake the provider could not supply. Do not reject it: process it as a zero-value transaction and reply code 0 without moving the balance.
BY_TRANSACTION acts on this txn_id only. BY_ROUND acts on every bet in the same round_id at once, and amount is the round's combined total.
Always reply HTTP 200 even for business errors
Single-state rounds: amount = |payout_amount − bet_amount|, and direction is the way to apply it. Always check balance >= bet_amount first, because the stake is committed in this same call. Reply 10002 if the balance is short.
Headers
| Field | Type | Required | Description |
|---|---|---|---|
| X-Api-Key | string | Yes | The API key best-system issued to you (verify it matches) |
| X-Signature | string | Yes | hex(HMAC-SHA256(secret, raw body)) — verify against the raw bytes, never re-serialize. Mismatch → code 30002 |
Request bodyapplication/json
| Field | Type | Required | Description |
|---|---|---|---|
| request_id | string | Yes | Id of this request |
| player_username | string | Yes | The player's username on your system |
| currency | string | Yes | The player's currency code in ISO 4217, e.g. THB |
| product_code | string | — | Game-provider code (e.g. PGSOFT) |
| timestamp | number | Yes | Send time in unix milliseconds |
| txns | object[] | Yes | Result transactions |
| └ txn_id | string | Yes | Transaction ID. Used as the idempotency key (see the notes) |
| └ round_id | string | Yes | Round ID |
| └ amount | number | Yes | Amount for this transaction, never negative and may be 0 (see the notes). Direction comes from the endpoint or the direction field |
| └ game_code | string | — | Game code |
| └ is_feature | boolean | — | Whether this is a free or feature spin. Absent means false |
| └ status | string | — | Vendor bet status. Always SETTLEDOPEN | WAITING | SETTLED | REFUND | REJECT | ROLLBACK | VOID | TIPS |
| └ play_info | string | — | The player's position or choice, e.g. player/banker, or the game name. `UNKNOWN` means the provider could not identify it — display only |
| └ transaction_type | string | — | Either BY_TRANSACTION or BY_ROUND (see the notes)BY_TRANSACTION | BY_ROUND |
| └ single_state | boolean | — | Round whose bet and result arrive in one call, with no prior /bet. Sent on every settle, both true and false (see the note below) |
| └ payout_amount | number | — | Payout amount (stake + win amount). Sent on every settle |
| └ bet_amount | number | — | Stake amount for the round. Sent on every settle, may be 0 |
| └ direction | string | — | Direction of amount. Only when single_state is trueDEBIT | CREDIT |
| └ turn_over | number | — | Valid stake for this bet. May be 0 |
| └ is_end_round | boolean | — | Whether this settle ends the round. false means more parts follow, e.g. freespins. Absent means it ends the round |
| └ is_feature_buy | boolean | — | Result of a bought-feature bet. Provider-dependent |
| └ skip_balance_update | boolean | — | true = do not update the balance, record only. Reply code 0 with the current balance |
{
"request_id": "6c1f2a3b-7d8e-4f90-a1b2-c3d4e5f60718",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236601000,
"txns": [
{
"txn_id": "T-002",
"round_id": "R-1",
"amount": 500,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Baccarat",
"turn_over": 500,
"transaction_type": "BY_TRANSACTION",
"is_end_round": true,
"single_state": false,
"bet_amount": 200,
"payout_amount": 500
}
]
}{
"request_id": "8a2c4e60-91b3-4d75-8e0f-2b7c9d1a4f36",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236742000,
"txns": [
{
"txn_id": "T-011",
"round_id": "R-4",
"amount": 900,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Baccarat",
"turn_over": 600,
"transaction_type": "BY_ROUND",
"is_end_round": true,
"single_state": false,
"bet_amount": 400,
"payout_amount": 900
}
]
}{
"request_id": "1d5b7f92-3c48-4a10-9e6d-5f2a8c0b7e14",
"player_username": "foobar",
"currency": "THB",
"product_code": "PGSOFT",
"timestamp": 1783236918000,
"txns": [
{
"txn_id": "T-050",
"round_id": "R-9",
"amount": 10,
"game_code": "10300",
"is_feature": false,
"status": "SETTLED",
"play_info": "Treasures of Aztec",
"turn_over": 0,
"transaction_type": "BY_ROUND",
"is_end_round": true,
"single_state": true,
"bet_amount": 10,
"payout_amount": 20,
"direction": "CREDIT"
}
]
}Expected Response
Fields in data
| Field | Type | Required | Description |
|---|---|---|---|
| code | number | Yes | 0 = success · see the Seamless codes page |
| request_id | string | Yes | Echoed from the request |
| username | string | Yes | Echo of player_username (defensive) |
| currency | string | Yes | Echoed from the request |
| balance_before | number | Yes | Balance before processing the whole txns[] batch |
| balance_after | number | Yes | Balance after processing the whole batch |
| timestamp | number | Yes | When you processed it (unix ms) |
{
"code": 0,
"request_id": "6c1f2a3b-7d8e-4f90-a1b2-c3d4e5f60718",
"username": "foobar",
"currency": "THB",
"balance_before": 800,
"balance_after": 1300,
"timestamp": 1783236601095
}Possible error codes
| code | Name | HTTP | Message |
|---|---|---|---|
| 10001 | SEAMLESS_USER_NOT_FOUND | 200 | Player not found on the agent system |
| 10002 | SEAMLESS_INSUFFICIENT_BALANCE | 200 | Insufficient balance for the debitbalance < bet_amount. Single-state only |
| 20002 | SEAMLESS_DUPLICATE_TXN | 200 | Duplicate transaction (txn_id already processed) |
| 30002 | SEAMLESS_INVALID_SIGNATURE | 401 | Invalid X-Signature |
| 40003 | SEAMLESS_FORBIDDEN | 200 | Forbidden (api-key/IP) |
| 50001 | SEAMLESS_INTERNAL_ERROR | 200 | Internal error on the agent system |