For developers

Put a wheel in your workflow.

Create saved wheels from your server. Share a playable link, or control a wheel on your own website and receive its winner.

Free pilot · 2–100 text entries · 24-hour share links

Your account

Get an API key

Use an email address you can verify. Your key belongs on your server, never in an iframe or a public browser script.

Sign in or create a developer account to manage keys.

Sign in or create an account

Use at least 8 characters for a new account. Sign-in is kept only for this browser tab session.

Creating an account sends your email to Firebase Authentication. API account data is stored separately from browser-saved My Wheels. Read Privacy and Cookies for storage and deletion details.

Start on your server

Create a wheel and get its link

  1. Create a verified developer account and copy an API key.
  2. Set CHOICESPIN_API_KEY in your server environment.
  3. Send the request below. The response includes data.wheel.id, data.share.url and data.share.embedUrl.
cURL · server-side
curl https://choicespin.com/api/v1/wheels \
  -H "Authorization: Bearer $CHOICESPIN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: activity-wheel-001" \
  --data '{"config":{"title":"Next activity","entries":["Drawing","Music","Reading"]},"share":true}'

Generate a new Idempotency-Key for each intended create operation. Keep that same value when retrying the request, so a retry does not create another wheel. The example value is a placeholder.

Check the HTTP status and save the returned ETag. Send it as If-Match when replacing or deleting a wheel. API errors include error.code and a diagnostic requestId.

Version 1

Endpoints and limits

Base URL: https://choicespin.com/api/v1. Authenticate wheel-management requests with Authorization: Bearer <your key>.

RequestWhat it does
POST /wheelsCreate a wheel; add share: true for a playable snapshot.
GET /wheelsList your wheels, with bounded cursor pagination.
GET /wheels/{id}Read one saved wheel and its version.
PUT /wheels/{id}Replace a wheel using its current If-Match value.
DELETE /wheels/{id}Delete a wheel and disable its share links.
POST /wheels/{id}/sharesCreate a new 24-hour snapshot.
DELETE /wheels/{id}/shares/{shareId}Disable one share link.

OpenAPI specification (JSON) describes request fields, responses and errors.

Saved wheels remain until deleted. Shared links are unlisted snapshots that expire after 24 hours. Updating a saved wheel does not change an earlier link. Anyone with a link can open its names and settings. Deleting a wheel or disabling its link blocks the next read; a copy already loaded cannot be recalled. A 429 response includes Retry-After. Availability also depends on the pilot's shared traffic limits.

On your website

Control an embedded wheel

The embed builder works without an API key. For a server-created snapshot, use the returned embedUrl. Keep the sandbox and referrer policy in your iframe:

<iframe src="YOUR_EMBED_URL" title="Activity wheel"
  width="600" height="600"
  sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"
  referrerpolicy="strict-origin-when-cross-origin"></iframe>
<script src="https://choicespin.com/scripts/embed/embed-client.js"></script>

After the frame exists, the optional helper waits for readiness and returns the correlated winner:

const wheel = ChoiceSpinEmbed.createClient(document.querySelector("iframe"));
await wheel.ready();
await wheel.setEntries(["Drawing", "Music", "Reading"]);
const result = await wheel.spin();
document.querySelector("#winner").textContent = result.winner;
// When your page no longer needs this wheel:
wheel.dispose();

Available methods: ready, spin, setEntries, addEntry, removeWinner, reset, on and dispose. Embed edits affect that browser session, not the saved API wheel. Spin-result events are UI results, not certified draw receipts or a one-spin guarantee.