The QRvote API

A small JSON API. Read any public contest and its results; manage your own with its organizer key or a sign-in. No accounts.

curl https://qrvote.org/api/c/try-it-scarecrow-walk/results

A real sample contest: run it here, or paste it into a terminal.

Examples

Request (no key needed when results are public)

GET /api/c/harvest-fair-scarecrows-x7k2/results

Response

{
  "campaign": { "title": "Harvest Fair Scarecrows", "status": "open", "results": "live", … },
  "results": [
    { "num": 2, "name": "Hay Jude",    "votes": 142 },
    { "num": 1, "name": "Scary Larry", "votes": 118 },
    { "num": 3, "name": "Corn Dog",    "votes": 96 }
  ]
}

Request

PATCH /api/admin/harvest-fair-scarecrows-x7k2
Authorization: Bearer $QRVOTE_KEY
Content-Type: application/json

{ "closed": true }

Response: the whole dashboard, now closed

{ "campaign": { "status": "closed", "closed": true, … }, "entrants": [ … ] }

Request

POST /api/admin/harvest-fair-scarecrows-x7k2/entrants
Authorization: Bearer $QRVOTE_KEY
Content-Type: application/json

{ "entrants": [{ "name": "Sir Squash" }, { "name": "Cornelius", "description": "by the barn" }] }

Response: the dashboard, with each new entry’s QR code

{ "entrants": [ …, { "num": 5, "name": "Sir Squash", "code": "k3v9x2mw", "votes": 0 }, … ] }

Sample data, trimmed.

Start with a prompt

Paste one into your coding assistant. Replace SLUG with your contest’s id from its link.

  • Live results in a terminal

    Using the QRvote API (spec: https://qrvote.org/openapi.json), write a small Node script that prints the live results of the contest with slug SLUG, sorted by votes, refreshing every 10 seconds.

  • Summarize my votes

    Using the QRvote API (https://qrvote.org/openapi.json; auth: https://qrvote.org/auth.md), download my contest’s CSV with the organizer key in $QRVOTE_KEY and summarize votes per entry and per hour.

  • Add entries from a file

    Using the QRvote API (https://qrvote.org/openapi.json; auth: https://qrvote.org/auth.md), write a script that adds every line of entries.txt as an entry to my contest SLUG, with the organizer key in $QRVOTE_KEY.

  • Moderate a Q&A

    Using the QRvote API (https://qrvote.org/openapi.json; auth: https://qrvote.org/auth.md), write a script that lists the questions waiting for approval on my Q&A SLUG (listPosts), shows each one, and approves or hides it as I answer y or n (moderatePost), with the organizer key in $QRVOTE_KEY.

Signing in

  • Organizer key Every contest has one, in its organizer link (https://qrvote.org/c/<slug>/admin#key=<key>). Send Authorization: Bearer <key>. One key, one contest, full control: keep it secret.
  • OAuth 2.1 Apps register themselves; the organizer picks contests and Read or Manage at /connect. Tokens reach the documented operations only. Details in auth.md.
  • AI assistants The same operations are MCP tools at https://mcp.qrvote.org/mcp, or https://mcp.qrvote.org/mcp/organizer with sign-in for claude.ai and ChatGPT. Signed-in apps with Manage can also create contests (5 a day). Connect your assistant.
  • People only Voting, answering, collecting hunt checkpoints and reporting need a person in a browser at the event, behind a Turnstile check. Automated clients are refused; please don’t work around it.

Endpoints

Generated from openapi.json, so it lists every operation.

OperationWhat it does
Public no key
GET /api/healthService status
GET /api/c/{slug}A contest, survey, hunt or board as the public sees it
GET /api/c/{slug}/resultsResults: vote tallies, survey totals, or a hunt leaderboard key if results are private
Your contests organizer key or sign-in
GET /api/admin/{slug}Everything on the organizer dashboard
PATCH /api/admin/{slug}Change settings, or end / reopen voting
POST /api/admin/{slug}/judgesContests: add a judge (judging must be on)
DELETE /api/admin/{slug}/judges/{id}Contests: remove a judge, their link and their scores
POST /api/admin/{slug}/entrantsAdd entries (contests) or checkpoints (hunts)
GET /api/admin/{slug}/export.csvDownload votes, survey responses, hunt players or board posts as CSV
GET /api/admin/{slug}/postersOrder printed posters on Zazzle: a ready order link and print image for each size
POST /api/admin/{slug}/certificatesOrder printed certificates on Zazzle, once voting has closed
GET /api/admin/{slug}/responsesSurvey responses, newest first (up to 500). Quizzes include each response's score.
POST /api/admin/{slug}/hostRun a live quiz: start, reveal, next question, finish, or pause/resume its clock
PUT /api/admin/{slug}/questionsSurveys and quizzes: replace the questions (only until the first response)
PUT /api/admin/{slug}/answersFix a quiz's answer key (allowed after people have answered; every score updates)
GET /api/admin/{slug}/boardBoards and nominations: every post, including those waiting for approval or hidden
PATCH /api/admin/{slug}/posts/{id}Boards and nominations: approve, hide or answer a post; Ideas: set its status, category, reply or pin
POST /api/admin/{slug}/posts/{id}/mergeIdeas and nominations: combine a duplicate into another post
POST /api/admin/{slug}/posts/approve-allBoards and nominations: approve every post waiting for approval
POST /api/admin/{slug}/board/hostQ&A: put a question on the big screen, mark it answered, or take it down
POST /api/admin/{slug}/suggestions/closeNominations: close suggestions and start voting with the finalists

For tools and agents

Every public English page also comes as markdown with Accept: text/markdown. In the browser, pages offer WebMCP tools, and an open organizer dashboard adds its own.