HomeDocsPricingPlayChangelogllms.txtLogin

API Documentation

REST API for room management + WebSocket for real-time voting.
Base URL: https://poker.findutils.com

Quick Start

Create a room and get a shareable link in one API call:

curl -X POST https://poker.findutils.com/api/rooms \ -H "Content-Type: application/json" \ -d '{"sessionName":"Sprint 42","scale":"fibonacci","stories":[{"title":"Login page"}]}' # Response (201) { "roomId": "abc12345", "adminToken": "a31d6b88c640255218...", "url": "/play#room=abc12345" }

Connect via WebSocket to vote in real-time:

const ws = new WebSocket('wss://poker.findutils.com/api/rooms/abc12345/ws?name=Alice'); ws.onmessage = (e) => console.log(JSON.parse(e.data));

Base URL

https://poker.findutils.com

All endpoints are relative to this base URL. HTTPS required. The service runs across 300+ edge locations worldwide for sub-5ms latency.

Rate Limits

300 requests per minute per IP address. WebSocket connections are not rate limited after the initial handshake.

HeaderDescription
X-RateLimit-LimitRequests allowed per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets

POST /api/rooms

Create a new planning poker room.

FieldTypeDefaultDescription
sessionNamestring"Planning Session"Display name (max 100 chars)
scalestring"fibonacci"fibonacci, modified_fibonacci, tshirt, powers_of_2, custom
customScalestring[][]Custom values (max 20, each max 10 chars)
anonymousVotingbooleanfalseHide voter identity until reveal
autoRevealSecondsnumber0-1 = auto when all voted, 0 = manual
storiesarray[]Stories with title and optional description
premiumbooleanfalseEnable premium features (50 voters, timer)

Response (201):

{ "roomId": "abc12345", "adminToken": "a31d6b88c640255218...", "url": "/play#room=abc12345" }

The adminToken is required for admin actions (reveal, set estimate, remove story, etc.). Keep it secret. It is never returned by GET endpoints.

GET /api/rooms/:id

Get the current state of a room. The adminToken is never included in the response.

curl https://poker.findutils.com/api/rooms/abc12345

Response includes: roomId, sessionName, scale, stories (with votes if revealed), voters (with online status), currentStoryIndex, phase, and tier.

POST /api/rooms/:id/stories

Add stories to an existing room. Max 200 stories per session.

curl -X POST https://poker.findutils.com/api/rooms/abc12345/stories \ -H "Content-Type: application/json" \ -d '{"stories":[{"title":"New feature"},{"title":"Bug fix","description":"Fix login timeout"}]}'

POST /api/rooms/:id/export PRO

Export session results in CSV, Excel, or Markdown format. Requires API key or x402 payment.

curl -X POST https://poker.findutils.com/api/rooms/abc12345/export?format=csv \ -H "X-API-Key: sk_live_xxxx"

WebSocket: Connect

Connect to a room for real-time voting.

wss://poker.findutils.com/api/rooms/:id/ws?name=YourName

On connect, the server sends a state message with the full room state and your voterId. Other participants receive a voter_joined notification.

Optional token query parameter for authenticated sessions (JWT from the dashboard).

WebSocket: Client Messages

Send JSON messages to perform actions. Admin actions require the adminToken field.

TypeFieldsAdminDescription
votevalue×Cast a vote on the current story
revealReveal all votes
set_estimatevalueSet final estimate
next_story×Move to next story
prev_story×Move to previous story
go_to_storyindex×Jump to specific story
reset_votesClear votes on current story
add_storytitle, description×Add a new story
remove_storystoryIdRemove a story
update_settingsvariousChange room settings
finish_sessionEnd session, save results
start_timersecondsStart discussion timer
pause_timerPause timer
resume_timerResume paused timer
reactionemoji×Send emoji reaction
ping×Keep-alive

WebSocket: Server Messages

TypeDescription
stateFull room state (on connect + after each change)
voter_joinedSomeone connected (voterId, name)
voter_leftSomeone disconnected
reactionEmoji from another voter
timer_tickCountdown update (remaining, running)
timer_expiredDiscussion time is up
errorError (permission denied, room full, etc.)
pongResponse to ping

Estimation Scales

ScaleValues
fibonacci1, 2, 3, 5, 8, 13, 21, ?, ☕
modified_fibonacci0, 0.5, 1, 2, 3, 5, 8, 13, 20, 40, 100, ?, ☕
tshirtXS, S, M, L, XL, XXL, ?, ☕
powers_of_21, 2, 4, 8, 16, 32, 64, ?, ☕
customDefined by customScale array

The ☕ card means "I need a break" and ? means "I don't know enough to estimate."

Voting Modes

Standard Voting

Votes are hidden until reveal. After reveal, you can see who voted what. Prevents anchoring bias while still allowing discussion about specific votes.

Anonymous Voting

Set anonymousVoting: true when creating the room. Even after reveal, votes are not attributed to specific voters. Useful when seniority dynamics might influence estimates.

Auto-Reveal

Set autoRevealSeconds: -1 to automatically reveal votes when all online voters have voted (minimum 2 votes). Set to a positive number for a countdown timer.

Discussion Timer PRO

Time-box discussions per story. Send start_timer with seconds (10-3600). The server broadcasts timer_tick every second and timer_expired when time is up.

// Start a 2-minute timer ws.send(JSON.stringify({ type: 'start_timer', seconds: 120, adminToken: '...' })); // Pause ws.send(JSON.stringify({ type: 'pause_timer', adminToken: '...' })); // Resume ws.send(JSON.stringify({ type: 'resume_timer', adminToken: '...' }));

Reactions

Send emoji reactions during the session. Allowed emojis:

👍 🤔 🔥 😂 ❓

ws.send(JSON.stringify({ type: 'reaction', emoji: '\u{1F525}' }));

Free vs Pro

FeatureFreePro
RoomsUnlimitedUnlimited
Voters per room1050
Session history30 daysUnlimited
ScalesStandard (4)All + custom
Anonymous voting
Discussion timer×
Velocity charts×
Export CSV/Excel×
Teams1 team, 5 membersUnlimited
Bulk import×

x402 Micropayments

No subscription needed. Pay per use with USDC micropayments via the x402 protocol.

ActionPrice (USDC)
Create premium room$0.005
Export session$0.002
Velocity report$0.003
Bulk story import$0.005

Include an X-PAYMENT header with a signed payment payload. The server responds with 402 and payment details if payment is required but missing.

API Keys

API key holders with a Pro plan get free access to all premium features without per-request payments.

curl -X POST https://poker.findutils.com/api/rooms \ -H "Content-Type: application/json" \ -H "X-API-Key: sk_live_xxxxxxxxxxxx" \ -d '{"sessionName":"Sprint 42","premium":true}'

Get an API key from the dashboard.

JavaScript Example

// Create a room const room = await fetch('https://poker.findutils.com/api/rooms', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionName: 'Sprint 42', scale: 'fibonacci', stories: [{ title: 'Login page' }, { title: 'API auth' }], }), }).then(r => r.json()); // Connect via WebSocket const ws = new WebSocket( \`wss://poker.findutils.com/api/rooms/\${room.roomId}/ws?name=Alice\` ); ws.onmessage = (e) => { const msg = JSON.parse(e.data); switch (msg.type) { case 'state': console.log('Room state:', msg.state); break; case 'voter_joined': console.log(msg.name, 'joined'); break; } }; // Vote ws.send(JSON.stringify({ type: 'vote', value: '5' })); // Reveal (admin only) ws.send(JSON.stringify({ type: 'reveal', adminToken: room.adminToken }));

Python Example

import requests import websocket import json # Create a room room = requests.post('https://poker.findutils.com/api/rooms', json={ 'sessionName': 'Sprint 42', 'scale': 'fibonacci', 'stories': [{'title': 'Login page'}], }).json() print(f"Room: {room['roomId']}") # Connect via WebSocket ws = websocket.create_connection( f"wss://poker.findutils.com/api/rooms/{room['roomId']}/ws?name=Bot" ) # Read initial state state = json.loads(ws.recv()) print(f"Connected, {state['state']['onlineCount']} voters online") # Vote ws.send(json.dumps({'type': 'vote', 'value': '8'})) ws.close()

cURL Examples

# Create a room curl -s -X POST https://poker.findutils.com/api/rooms \ -H "Content-Type: application/json" \ -d '{"sessionName":"Sprint 42","scale":"fibonacci"}' | jq . # Get room state curl -s https://poker.findutils.com/api/rooms/abc12345 | jq . # Add stories curl -s -X POST https://poker.findutils.com/api/rooms/abc12345/stories \ -H "Content-Type: application/json" \ -d '{"stories":[{"title":"Feature A"},{"title":"Bug B"}]}' | jq . # Connect via WebSocket (using websocat) websocat wss://poker.findutils.com/api/rooms/abc12345/ws?name=Alice