Skip to content

Cast a vote on a polst.

POST
/polsts/{slug}/votes

Accepts X-Device-Id (anonymous) or a bearer token carrying the vote scope. Rate-limited at 10 votes per minute per caller. The DB upsert on (polstId, deviceId) prevents double-counting, so the endpoint is naturally idempotent without a client-supplied key.

slug
required

Polst slug or UUID.

string
>= 1 characters <= 128 characters

Polst slug or UUID.

object
option
required
string
Allowed values: A B

Vote recorded.

object
data
required
object
tallies
required
object
optionA
required
integer
<= 9007199254740991
optionB
required
integer
<= 9007199254740991
total
required
integer
<= 9007199254740991
votedAt
required
string format: date-time
/^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$/

Missing bearer and X-Device-Id.

Bearer token lacks the vote scope.

Polst not found.

Conflict: either POLST_CLOSED (polst voting window is closed) or VOTE_ALREADY_CAST (caller has already voted on this polst — error.details.existingVote echoes the original vote).

Request body failed validation.

Rate limit exceeded.