Redeem diamonds for credit
LivePOST
/api/v1/diamond/redeemRedeem one shop item.
The redeemed credit is recorded as a DIAMOND_REDEEM entry in the transaction history and carries turnover per the agent's shop_wagering_x.
idempotent = true means a replay — do not count it as a new redeem; just refresh the screen with the returned diamond_balance/balance.
Headers
| Field | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Used — send Bearer <member access_token> |
| X-Api-Key | string | Yes | Agent API key (ak_…) from the bo screen |
| X-Timestamp | string | Yes | Signing time in unix milliseconds (±300s skew allowed) |
| X-Nonce | string | Yes | Unique per-request value (UUIDv4) for replay protection |
| X-Signature | string | Yes | hex(HMAC-SHA256(secret, canonical)) — see the Authentication page |
| X-Player-IP | string | — | The player's real IP (IPv4/IPv6) — recommended (used in login history) |
| X-Player-UA | string | — | The player's User-Agent (optional — recorded in login history) |
| X-Request-Id | string | — | Your correlation id — echoed back as request_uuid (recommended) |
| x-lang | string | — | th (default) or en — the language of message |
Request bodyapplication/json
| Field | Type | Required | Description |
|---|---|---|---|
| item_id | string | Yes | Shop item id to redeem, taken from items in /diamond/shop (UUID). |
| idempotency_key | string | — | Your idempotency key, max 64 chars — send the same value on retry so it never redeems twice. If omitted the server generates a uuid (so a retry must carry your own key to be deduplicated). |
Request example
{
"item_id": "3f1c9a2e-7b41-4d6c-9a8e-2f5b1c0d7e10",
"idempotency_key": "redeem-2026-07-12-9f8a1c"
}Response
Fields in data
| Field | Type | Required | Description |
|---|---|---|---|
| idempotent | boolean | — | true = this was a replay of a prior idempotency_key (no double deduct/credit), balances returned as-is · false = a fresh redeem happened. |
| diamond_balance | number | — | Diamond balance after the item cost is deducted (integer) |
| balance | string | — | Wallet balance after the credit is applied (THB, string) |
| credit_amount | string | — | Credit granted by this redeem (THB, string) |
| item_id | string | — | The redeemed item id (echoed back to tie to a toast/history) |
Response example
{
"success": true,
"code": 0,
"message": "Redeemed successfully",
"data": {
"idempotent": false,
"diamond_balance": 220,
"balance": "170.00",
"credit_amount": "50",
"item_id": "3f1c9a2e-7b41-4d6c-9a8e-2f5b1c0d7e10"
},
"request_uuid": "c4a8f2d6-1b39-4e75-90cd-5e7a3f8b1d64"
}Possible error codes
| code | Name | HTTP | Message |
|---|---|---|---|
| 6222 | DIAMOND_INSUFFICIENT | 400 | Not enough diamonds to redeemNot enough diamonds for this item (diamond_balance < cost_diamonds) — earn more first |
| 6223 | DIAMOND_ITEM_UNAVAILABLE | 400 | Diamond shop item is inactive or not foundThe item is unavailable — no such id or it was deactivated (refetch /diamond/shop) |
| 6221 | DIAMOND_NOT_ENABLED | 400 | Diamond program is not enabled or member not eligibleThe diamond program or shop is off (enabled/shop_enabled = false), or the account does not qualify (not a TRANSFER wallet) |
| 9002 | SERVICE_UNAVAILABLE | 503 | Service unavailableThe agent's credit issuance is temporarily unavailable — diamonds are not deducted, retry later (the real cause is masked from the member) |
| 4001 | VALIDATION_ERROR | 400 | Validation erroritem_id is not a UUID, or idempotency_key exceeds 64 characters |
| 1001 | UNAUTHORIZED | 401 | Unauthorized |
| 1007 | TOKEN_INVALID | 401 | Token invalid |