Show of Hands

Ask a room a question. They answer on their phones. The answers appear on a screen as they come in.

This page has three parts. Start here is all most people need. For your agent is for driving the poll from an AI assistant. Technical detail is everything else.


Start here

You need: the code from your confirmation email, a laptop for the screen, and your phone.

1. Open your poll

Go to https://showofhands.live/redeem

Paste your code, type a name for your poll, and press the button.

You get three links, a key, and two QR codes. If you are on a laptop, point your phone camera at the Scan to control it square: that puts the controls on your phone without typing a URL.

Keep your code. If you lose the links or the key, or you need them on a different phone or laptop, go back to https://showofhands.live/redeem and enter the same code again. It gives you the same poll back, with everything still in it. It does not open a second one and it does not cost anything. Your code works this way until your pass ends.

2. Set up the room

On your laptop, open the link ending in /screen and press F11 for full screen. A big square code appears. That is what people scan.

On your phone, open the link ending in /control. It asks for the key. Paste it in once and it remembers.

3. Ask your first question

On your phone, tap Write my own, type a question, add up to four answers to choose from, and tap Put it on screen.

In a hurry? Tap Ask AI instead, type a topic, and a question comes back with its answers ready for you to approve.

Tell the room to point their phone camera at the square code on the screen. They tap the link that pops up, give a name and email, and answer.

Bars grow on the screen as answers arrive.

4. Move on

Tap Next for the next question. Tap Close answers if you want the numbers to stop moving while you talk about them.

5. Finish

Press and hold Hold to end session.

6. Get your results

Go to https://showofhands.live/live/YOUR-CODE/results and enter the same key. There is a link to it on your phone controls.

You see every question with its counts, and four buttons: Results as CSV for a spreadsheet, Results as JSON, Print or save as PDF, and Attendee list as CSV for the names and emails people gave when they joined.


Not running a talk? On the page in step 1, choose In their own time instead. No laptop and no screen: add your questions, tap Open every question, and send people the answering link. They answer whenever suits, for as long as your pass lasts.


What is in your pass

A pass lasts 7 days, is bought once, and needs no account and no subscription. One pass opens one poll.

TierParticipantsQuestionsPrice
basic2020USDC 1
small10020USDC 3
medium50030USDC 5

Bigger rooms are coming. If you need one now, email mail@richard-hobbs.com and say how many people you expect.

Three links come with every pass:

LinkWho opens it
https://showofhands.live/live/<code>The people answering, on their phones
https://showofhands.live/live/<code>/screenYou, on the laptop driving the big screen
https://showofhands.live/live/<code>/controlYou, on your phone

Nobody installs anything and nobody makes an account.


Before your event

Set your phone up now, not on stage. Open the control link on the phone you will actually hold, paste the key, tap Unlock. It remembers, and it remembers each poll separately, so you can hold two of them without one overwriting the other.

Add it to your home screen so you are not hunting through tabs mid-talk.

Hard reload the screen and your phone (Ctrl+Shift+R, or Cmd+Shift+R on a Mac). A tab left open for days keeps running the version it loaded on the day you opened it. It looks fine right up until you need something new to work.

Open the screen link on the laptop and go full screen (F11, or Ctrl+Cmd+F on a Mac). The holding screen is mostly QR by design so it scans from the back of a room. It shrinks into the corner once your first question is up, and stays there for latecomers.

The screen asks the browser to keep the laptop awake. That is a request, not a guarantee, so plug the charger in and turn off sleep anyway.


Your phone controls, button by button

ButtonDoesGreyed out when
BackPrevious questionYou are on the first
NextNext question, or the first if none is showingYou are on the last
Close answersFreezes voting, bars stay on screenNothing showing, or already closed
ReopenLets late answers in againAnswers are already open
Hold to end sessionCloses everything, shows your closing screenAlready ended

Close answers is the one worth knowing. Use it when you want to discuss a result without the numbers shifting under you while you talk.

Ending is a press-and-hold on purpose. There is no undo.


Adding questions

Two ways, and the difference matters.

Write my own. Type the question, choose Multiple choice or Open answer, fill in up to four options. Empty option slots are ignored, so two is fine. Then Put it on screen to publish it now, or Add to running order to queue it behind the current one.

Ask AI. Type a topic and a question comes back with its answers a few seconds later. It arrives in an approval queue with Approve and Discard, and the room cannot see it until you approve it.

That asymmetry is deliberate. What you type goes up when you tap the button, because you read it as you wrote it. What a model wrote gets a second pair of eyes before a room sees it.

A count appears next to your poll code whenever something is waiting for approval. Tap it to jump to the queue.


Polls people answer in their own time

Choose In their own time when you open the poll and it works differently: no presenter, no big screen, every question open at once. Good for feedback after an event or a survey round a team.

Two buttons instead of Back and Next:

ButtonDoes
Open every questionOpens the whole set. Share the answering link and answers come in
Close the poll to new answersStops new answers. Your results stay readable

People see the whole set on one page with a progress bar, answer in any order, and can close the tab and come back. Their answers are remembered on their own device, so returning shows what they already sent rather than asking again.

Your pass expiry is the deadline. After it, answers are refused whether or not you remembered to close the poll.

You can add questions mid-run. People who already finished see the new one next time they open the link.

Offering something for finishing

People finish a self-paced poll when there is a reason to. On your phone controls there is Offer something for finishing: type what you are offering, save it, and mention it when you send the link out.

It is shown only to somebody who has answered every question, with a box for their email, already filled in with the address they joined with. They can change it, so a work address for the poll and a personal one for the reward both work.

You collect the addresses from your results page: Who finished, as CSV or as JSON. There are no emails sent to you one by one, and nothing is sent to them either.

Whatever you offer is yours to honour. We carry the message and hand you the list; we hold nothing and promise your audience nothing.

Turning it off is the same box, emptied and saved.


Your results

https://showofhands.live/live/<code>/results, unlocked with the same key. There is a link to it on your phone controls.

ExportWhat it is
Results as CSVOne row per answer: question number, question, type, answer, votes, share
Results as JSONFor feeding into something else
Print or save as PDFThe page without the buttons, for a report or a slide
Who joined, as CSVName, email and join time for everyone who joined
Who finished, as CSVThe same, narrowed to people who completed a self-paced poll, with the address they gave
Who finished, as JSONThe same list, for feeding into something else

Everything is made in your browser and downloaded to your device. Nothing is emailed anywhere.

Typed answers are grouped before counting, ignoring capitals and trailing full stops, so Booking flights, booking flights. and Booking Flights count as one answer with three votes.

Summarising what people typed

Every open-answer question with at least four answers gets Summarise what the room said: three to five themes with rough proportions, instead of twenty typed replies you will never re-read. It appears under the chart and is included in the CSV, JSON and PDF exports.

It is saved once made, so looking again costs nothing. Regenerate forces a fresh one.

Below four answers it refuses. That floor is not adjustable: a summary of two or three replies in a small room can point at who wrote them.


If something goes wrong

SymptomWhat it meansWhat to do
Screen frozen on an old questionDropped connection, or a laptop waking from sleepIt fixes itself within four seconds. If not, reload; nothing is lost
Someone's phone is stuckSame, on their deviceLock and unlock it, or switch apps and come back
"That key is wrong"Wrong or forgotten keyType it again. Capitals do not matter
"too many attempts"Ten tries a minute per networkWait a minute. You only see this if someone is guessing
"This room is full"You hit your participant limitNothing to do mid-talk. A larger pass next time
"This poll has ended"The 7 days are upAnswers are refused from then on
Nobody can joinThe venue is blocking scanned linksRead the URL aloud. It is short enough to type
Room bigger than the wifiSaturated venue wifiTell them to use mobile data. Each phone uses very little
The big screen diesLaptop or browserKeep going from your phone. It shows the question and the live count

Every answer is saved as it arrives, not held in the browser. Reloading anything loses nothing.


What your audience is promised

The join screen tells people their answers are anonymous. That is true by how the thing is built, not by policy.

Nobody can tell who answered what. Each phone makes up a throwaway code for itself and files its answers under that. It matches nothing in the list of who joined, and no record anywhere links the two. There is no export, no screen and no query that can put a name against an answer.

Their email is only ever yours. It is not readable from any browser, including yours. It comes out only in the attendee list you download, which contains no answers.

One answer per phone per question. Answering twice is quietly ignored rather than counted.

Your key opens your poll and nothing else. Every poll has its own.


For your agent

Give your agent the microphone.

Any agent can reach this poll at https://showofhands.live/mcp over MCP: put a question to a live room mid-talk, advance it, and read the answers back, while the talk is happening. No other audience-response tool has an endpoint an agent can drive.

You do not need any of this to run a poll. Everything above works from a phone.

Streamable HTTP, JSON-RPC over POST. GET returns a summary. Every tool except redeem_pass takes the session key.

ToolDoes
read_manualThis document, so an agent arriving cold can work out the rest
redeem_passTurn a purchased code into a poll and its links
add_poll_questionPut a question into a running room
advance_pollNext or previous question
open_all_questionsOpen the whole set at once, for a self-paced poll
close_answersFreeze voting while you talk about a result
end_pollClose the session
get_poll_resultsCounts and a headcount. Never identities

redeem_pass

ArgumentTypeRequiredNotes
codestringyesThe redemption code. Case-insensitive
titlestringyesWhat the room sees while joining
subtitlestringnoOne line under the title
questionsarrayyesMay be empty; add them later
questions[].promptstringyesUnder ~120 characters stays legible on a projector
questions[].kindfree | choicenoDefaults to free
questions[].optionsstring[]when choice2 to 6 short answers
modelive | asyncnoDefaults to live. async is the self-paced shape
brandingobjectnoSee Branding below
curl -s -X POST "https://showofhands.live/mcp" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"redeem_pass","arguments":{
        "code":"MED-7K2P-QX94",
        "title":"Agentic commerce",
        "questions":[{"prompt":"Do you trust an agent to buy for you?","kind":"choice","options":["Yes","With limits","No"]}]}}}'

Lost the session key? Call redeem_pass again with the same code. A code that has already opened a room returns that room, its URLs and its key, with "reopened": true, instead of an error. It never opens a second room and it costs nothing. title is still required by the schema but is ignored on that path, because the poll keeps the name it already has. This is what makes the redemption code, not your stored state, the thing worth keeping for the life of the pass.

add_poll_question

ArgumentTypeRequiredNotes
codestringyesThe poll code
keystringyesThe session key
promptstringyesThe question as the room reads it
kindfree | choicenoDefaults to free
optionsstring[]when choice2 to 6 short answers
publishapprove | now | queuenoDefaults to approve

publish is the important one. By default a question lands as a draft: it appears on the presenter's phone with Approve and Discard, and the room cannot see it. That is enforced in the database, not in the interface, so a draft cannot reach the screen even if something goes wrong client side. Use now when the agent is yours and putting the question up live is the point.

advance_poll

ArgumentTypeRequiredNotes
codestringyes
keystringyes
directionnext | prevnoDefaults to next

Drafts awaiting approval are skipped. They only enter the running order once a human approves them.

open_all_questions

The self-paced control. advance_poll has no meaning without a screen; this does the job instead.

ArgumentTypeRequiredNotes
codestringyes
keystringyes
closebooleannoTrue stops new answers instead of opening the set

Opening a set never closes a question somebody may be part way through.

close_answers

ArgumentTypeRequiredNotes
codestringyes
keystringyes
reopenbooleannoTrue reopens answering instead of closing it

end_poll

ArgumentTypeRequired
codestringyes
keystringyes

Ends the session and switches the screen to the closing screen. The pass stays valid until it expires, so results can still be read back.

get_poll_results

ArgumentTypeRequired
codestringyes
keystringyes

Returns the count for every option on every question, plus how many people joined.

This tool cannot return a name, an email, or an individual answer, and there is no argument that makes it.

Over plain HTTP

Everything above is also reachable with the session key as a bearer token, for when there is no agent to hand:

curl -s -X POST "https://showofhands.live/api/live/<code>/questions" \
  -H "Authorization: Bearer <session_key>" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"What would you hand to an agent first","kind":"free","publish":"now"}'
EndpointMethodDoes
/api/live/<code>/control?action=next|prev|close|reopen|endPOSTThe phone controls
/api/live/<code>/control?action=open_all|close_allPOSTOpen or close a self-paced set
/api/live/<code>/questionsPOSTAdd a question
/api/live/<code>/pendingGETRead drafts awaiting approval
/api/live/<code>/pending?action=approve|discardPOSTReview a draft, body {"question_id":"..."}
/api/live/<code>/draftPOSTAsk the model for a question, body {"topic":"..."}
/api/live/<code>/joinPOSTJoin the room, body {"name":"...","email":"..."}
/api/live/<code>/resultsGETCounts and a headcount
/api/live/<code>/participantsGETWho joined, who finished, and their contact address
/api/live/<code>/offerPOSTSet the completion offer, body {"text":"..."}. Empty clears it
/api/questions/<id>/summarisePOSTSummarise one question's typed answers

Technical detail

Branding

The screen is unbranded by default. Nothing on it identifies the tool, which is the point: it is your event, not ours. Neither AI feature marks the screen either.

Set with the branding argument when an agent opens the poll. The web form does not offer it.

{
  "accent": "#F59E0B",
  "closing": {
    "mode": "custom",
    "heading": "Come and see us at stand 14",
    "sub": "Demos every half hour.",
    "cta": "Book a slot",
    "url": "https://example.com/book"
  }
}

closing.mode is off (a plain thank you), custom (your own call to action, shown with a QR), or via (the VIA signup, used when VIA runs the event).

accent must be a six-digit hex and a closing URL must be http or https. Anything else is dropped, because both end up inside the screen's own styling and markup.

How the anonymity guarantee is enforced

poll_responses.participant_id holds a throwaway token generated in the respondent's own browser. It matches no row in poll_participants, there is no foreign key between them, and nothing server-side holds the mapping. Verifiable at any time; this must return 0:

select count(*) from poll_responses r
where exists (select 1 from poll_participants p where p.id = r.participant_id);

poll_participants has no select policy at all, so respondent emails are unreadable from any browser and reachable only with the service key. One answer per device per question is a unique index, not interface logic. Participant and question caps are enforced in the database, the participant cap under a per-session advisory lock so a room that all scans at once cannot race past it. An expired pass is refused by the database, not by the pages.

The summariser

DeepSeek V4-Flash. It is given the answer text and nothing else: never a name, an email, a timestamp, or the token an answer was recorded against. It refuses below four answers.

Summaries are cached on the question row, so a second look makes no call.

Buying

Passes are sold in the DrHobbs Knowledge store on VIA (ERC-8004 agent 59665), which settles the payment in USDC and emails a redemption code that looks like MED-7K2P-QX94. There is no payment page here and this app holds no wallet.

Two ways to turn a code into a poll, doing exactly the same thing: https://showofhands.live/redeem for people, redeem_pass for agents.

At a glance