API Reference
Complete reference for the Lucky Spin backend API. All endpoints return JSON.
Base URL: https://dice.ziesto.ca
Base URL & Rate Limiting
The API has no authentication. Rate limiting is applied at the server level:
- General: 500 requests per 15 minutes per IP
- House seed generation: 20 requests per minute per IP
All responses follow this format:
{
"success": true | false,
"data": { ... }, // present on success
"error": "message" // present on failure
}
Spin Endpoints
GET /api/spin/status
Get the current game status including contract balance, pending spins, and recent history.
Response:
{
"success": true,
"data": {
"contractBalance": "1000000000", // satoshis (10 QTUM)
"pendingSpins": 1,
"recentSpins": [
{
"spinId": 5,
"player": "7926223070...",
"segment": 3,
"payout": "130000000",
"resolvedAt": 1706123456789
}
]
}
}
GET /api/spin/house-seed
Generate a new house seed and return its keccak256 hash. The actual seed is stored on the backend for later reveal. Seeds expire after 2 hours.
Rate limit: 20 requests per minute per IP
Response:
{
"success": true,
"data": {
"houseSeedHash": "0x3a7f8c...", // bytes32 keccak256 hash
"expiresAt": 1706130656789 // Unix timestamp (ms)
}
}
Call this endpoint before placing a spin. Pass the houseSeedHash to the
smart contract's placeSpin() function. The backend will later reveal the
original seed during revealAndResolve().
POST /api/spin/submit-player-seed
Submit the player's revealed seed after the spin is confirmed on-chain.
This triggers the backend to call revealAndResolve() on the contract.
Request Body:
| Parameter | Type | Description |
|---|---|---|
| spinId | number | The on-chain spin ID |
| playerSeed | string | The original seed (bytes32, 0x + 64 hex chars) |
Request:
POST /api/spin/submit-player-seed
Content-Type: application/json
{
"spinId": 5,
"playerSeed": "0xabcdef0123456789..."
}
Response:
{
"success": true,
"data": {
"spinId": 5,
"playerSeedReceived": true,
"revealTxid": "abc123..." // or null if pending
}
}
Errors:
| Code | Error | Cause |
|---|---|---|
| 400 | Missing required fields | spinId or playerSeed not provided |
| 400 | Invalid player seed format | Seed not in bytes32 format |
| 404 | Spin not found or not pending | spinId doesn't match a pending spin |
GET /api/spin/:spinId
Get details of a specific spin by ID. Works for both pending and resolved spins.
| Parameter | Type | Description |
|---|---|---|
| spinId | number (URL) | The on-chain spin ID |
Response (resolved):
{
"success": true,
"data": {
"spinId": 5,
"player": "7926223070...",
"segment": 3,
"payout": "130000000",
"status": "resolved",
"resolvedAt": 1706123456789
}
}
Response (pending):
{
"success": true,
"data": {
"spinId": 6,
"player": "7926223070...",
"hasPlayerSeed": false,
"status": "pending"
}
}
GET /api/spin/find/by-hash?houseSeedHash=0x...
Find a pending spin by its house seed hash. Used by the frontend to discover the on-chain spin ID after placing a transaction.
| Parameter | Type | Description |
|---|---|---|
| houseSeedHash | string (query) | The house seed hash used when placing the spin |
Response:
{
"success": true,
"data": {
"spinId": 5,
"player": "7926223070...",
"hasPlayerSeed": false
}
}
GET /api/spin/history/recent?limit=20
Get recent resolved spins in reverse chronological order.
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number (query) | 20 | Max number of spins to return |
Response:
{
"success": true,
"data": [
{
"spinId": 5,
"player": "7926223...",
"segment": 3,
"payout": "130000000",
"resolvedAt": 1706123456789
}
]
}
GET /api/spin/prizes/info
Get the prize configuration including spin cost and all segment prizes.
Response:
{
"success": true,
"data": {
"spinCost": "100000000",
"prizes": [
{ "segment": 0, "amount": "40000000", "color": "red", "label": "0.4 QTUM" },
{ "segment": 1, "amount": "70000000", "color": "orange", "label": "0.7 QTUM" },
{ "segment": 2, "amount": "110000000", "color": "green", "label": "1.1 QTUM" },
{ "segment": 3, "amount": "130000000", "color": "blue", "label": "1.3 QTUM" },
{ "segment": 4, "amount": "40000000", "color": "red", "label": "0.4 QTUM" },
{ "segment": 5, "amount": "70000000", "color": "orange", "label": "0.7 QTUM" },
{ "segment": 6, "amount": "110000000", "color": "green", "label": "1.1 QTUM" },
{ "segment": 7, "amount": "200000000", "color": "gold", "label": "2.0 QTUM" }
]
}
}
Error Handling
All error responses follow the standard format:
{
"success": false,
"error": "Human-readable error message"
}
| HTTP Code | Meaning | Common Causes |
|---|---|---|
| 400 | Bad Request | Missing or invalid parameters |
| 404 | Not Found | Spin ID doesn't exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Error | QTUM node unreachable, contract call failed |