API · v1
Spinly Developer API
A small, signed REST API for pulling random picks and controlling live sessions from scripts, bots, Stream Deck, or your own apps. Every result includes a verifiable receipt code.
Get a key
Open profile → Developer → Create.
Base URL
https://[your-domain]/api/v1
Auth
Send X-Api-Key: spk_live_… on every request.
/api/v1/randomPick a random item
Returns one item from the supplied list, plus a signed receipt that anyone can verify with the /verify endpoint. Pass an optional seed to make the pick deterministic.
Request
curl -X POST https://[your-domain]/api/v1/random \
-H "X-Api-Key: spk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"items":["alice","bob","carol","dave"]}'Response
{
"ok": true,
"pick": "carol",
"index": 2,
"candidate_count": 4,
"receipt": {
"code": "K7QH3M9XJB2P",
"signature": "f3a1...",
"created_at": "2026-04-20T10:23:11.512Z"
},
"seeded": false
}GET shortcut
curl "https://[your-domain]/api/v1/random?items=alice,bob,carol&seed=demo" \
-H "X-Api-Key: spk_live_xxxxxxxxxxxx"Limits: 2–500 items, each ≤200 chars. Rate limit: 60 req/min/key.
/api/v1/verify/:codeVerify a receipt
Public. Anyone holding a Spinly receipt code can confirm it's genuine and see the original candidate list. The server re-computes the HMAC signature on every call so a tampered DB row would be detected.
curl "https://[your-domain]/api/v1/verify/K7QH3M9XJB2P"Response
{
"ok": true,
"valid": true,
"receipt": {
"code": "K7QH3M9XJB2P",
"source": "api.random",
"pick": "carol",
"candidates": ["alice","bob","carol","dave"],
"signature": "f3a1...",
"created_at": "2026-04-20T10:23:11.512Z",
"session_id": null
}
}Rate limit: 120 req/min/IP.
/api/v1/sessionsCreate a live session
Creates a wheel/picker/team/raffle room programmatically. The response includes a host_token — keep it secret. You'll need it to spin or end the session via the API.
curl -X POST https://[your-domain]/api/v1/sessions \
-H "X-Api-Key: spk_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"tool":"wheel","max_per_user":1}'Response
{
"ok": true,
"session": {
"id": "1c2e...",
"code": "428193",
"tool": "wheel",
"created_at": "...",
"expires_at": "..."
},
"host_token": "a1b2c3...",
"join_url": "https://[your-domain]/join?code=428193"
}Rate limit: 10 req/min/key.
/api/v1/sessions/:code/spinSpin a live session
Picks a winner from the session's current entries (weighted by ticket count, same as the in-app raffle), writes it back so connected guests see the result in real-time, and returns a signed receipt.
curl -X POST https://[your-domain]/api/v1/sessions/428193/spin \
-H "X-Api-Key: spk_live_xxxxxxxxxxxx" \
-H "X-Host-Token: a1b2c3..."Response
{
"ok": true,
"winner": { "name": "Jordan", "color": "#7c3aed" },
"receipt": {
"code": "K7QH3M9XJB2P",
"signature": "f3a1...",
"created_at": "..."
},
"candidate_count": 12
}Errors: 404 if code unknown, 403 if host token wrong, 409 if no entries, 410 if the session has ended. Rate limit: 30 req/min/key.
Errors
400— bad input (zod validation message inerror)401— missing or invalidX-Api-Key403— wrong host token404— session or receipt not found409— session has no entries to pick from429— rate limited (checkRetry-After)500— server error