Pepvote Support Center

Voting events

Create, read, update, and delete voting events.

Use a voting event's id or its short code wherever a path has :idOrCode.

Endpoints

MethodPathScopeDescription
GET/voting-eventsreadList accessible voting events.
POST/voting-eventswriteCreate a voting event.
GET/voting-events/:idOrCodereadGet one voting event.
PATCH/voting-events/:idOrCodewriteUpdate allowed event settings.
DELETE/voting-events/:idOrCodewriteDelete a voting event.
PUT/voting-events/:idOrCode/logowriteSet the event logo from an upload.
DELETE/voting-events/:idOrCode/logowriteRemove the event logo.
GET/voting-events/:idOrCode/statsreadGet event counts and turnout.

List query parameters

NameTypeRequiredDescription
limitintegerNoPage size from 1 to 200. Default: 50.
cursorstringNoCursor from nextCursor.
typeelection or pollNoFilter by event type.
statusdraft, upcoming, ongoing, or endedNoFilter by status. Same names as the dashboard.

Create request fields

title is required. See uploads before setting a logo.

FieldTypeRequiredDescription
titlestringYes1 to 200 characters.
typeelection or pollNoDefaults to Pepvote's event type.
descstringNoUp to 5,000 characters.
startsAt, endsAtintegerNoUnix milliseconds.
resultSettingsobjectNoHow and when results are shown. See result settings.
groupModebooleanNoEnable event groups.
voterCanRegister, candidateCanRegisterbooleanNoAllow public registration.
canContestMultiplePositionsbooleanNoAllow a candidate to enter more than one position.
requireVoterIdToRegisterbooleanNoRequire a voter ID during public voter registration.
requireVoterIdToVotebooleanNoRequire a voter ID to cast a ballot.
shuffleCandidates, multiStepVotingbooleanNoSet the voting experience.
enableWeightedVotingbooleanNoEnable weighted voting.
votingFormatdefault, big_avatar, big_avatar_full_image, options_with_avatar, or optionsNoSet the ballot layout.
aliasesobjectNoRename Pepvote's default terms. See aliases.

Update request fields

Send at least one field. Send null to clear desc, startsAt, or endsAt.

FieldTypeDescription
titlestring1 to 200 characters.
descstring or nullUp to 5,000 characters.
startsAt, endsAtinteger or nullUnix milliseconds.
voterCanRegister, candidateCanRegisterbooleanAllow public registration.
resultSettingsobjectHow and when results are shown. See result settings.
aliasesobjectRename Pepvote's default terms. See aliases.

Result settings

resultSettings holds every result option in one object. Responses always return all six keys. On POST and PATCH, send only the keys you want to change.

KeyTypeDescription
livebooleanCandidates and voters can see results while voting is live.
publishedbooleanResults are visible after voting ends.
displayLimitinteger or nullCandidates shown per position on the results page, 2 to 10. On PATCH, null restores the default of 3.
groupByCandidateGroupbooleanOne row per candidate group. Needs groupMode.
showWeightedVotesbooleanShow weighted tallies on a weighted event. Default true.
percentageBasevotes or votersWhat shares are out of on plurality and approval positions that allow more than one pick. Default votes.

With votes, each candidate's share is out of every pick made on the position, so a position's shares add up to 100%. With voters, each share is out of the voters who voted on the position. Use it when a rule says a winner needs more than half of the voters: on a pick-2 position, a candidate every voter picked shows 100%, not 50%, and the shares add up to as much as 200%.

groupByCandidateGroup cannot be true while percentageBase is voters. A group row adds up its candidates' votes, so one voter could count twice. Setting percentageBase to voters turns group view off.

curl -X PATCH "https://api.pepvote.com/voting-events/BOARD26" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" \
  -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" \
  -d '{"resultSettings":{"published":true,"percentageBase":"voters"}}'

Aliases

An alias replaces one of Pepvote's default words everywhere voters and organizers read it. A student union can call a position a "role", and a quadratic budget event can call a credit a "token".

The aliases object takes the same keys the API returns. Send only the ones you want to change. Each value is 1 to 60 characters and is trimmed.

KeyReplaces
votingEventelection or poll
votingCentervoting center
positionposition
groupgroup
positionGroup, candidateGroup, voterGroupgroup, for that one kind. Falls back to group.
candidatecandidate
votervoter
voterIdvoter ID
sponsorsponsor
weightweight. Only kept while enableWeightedVoting is true.
quadraticCreditcredit, the unit voters spend under quadratic voting

On PATCH, send null for an alias to restore its default word. On POST, omit the alias instead.

curl -X PATCH "https://api.pepvote.com/voting-events/BOARD26" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" \
  -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" \
  -d '{"aliases":{"quadraticCredit":"token","position":"role","sponsor":null}}'
{
  "data": {
    "id": "j57event01",
    "code": "BOARD26",
    "aliases": {
      "votingEvent": null,
      "votingCenter": null,
      "position": "role",
      "group": null,
      "positionGroup": null,
      "candidateGroup": null,
      "voterGroup": null,
      "candidate": null,
      "voter": null,
      "voterId": null,
      "sponsor": null,
      "weight": null,
      "quadraticCredit": "token"
    }
  }
}

Create example

curl -X POST "https://api.pepvote.com/voting-events" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" \
  -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: board-2026" \
  -d '{"title":"Board election 2026","type":"election","resultSettings":{"live":true}}'
{
  "data": {
    "id": "j57event01",
    "code": "BOARD26",
    "type": "election",
    "title": "Board election 2026",
    "desc": null,
    "startsAt": null,
    "endsAt": null,
    "status": "draft",
    "locked": false,
    "resultSettings": {
      "live": true,
      "published": false,
      "displayLimit": null,
      "groupByCandidateGroup": false,
      "showWeightedVotes": true,
      "percentageBase": "votes"
    },
    "groupMode": false,
    "votingFormat": "default",
    "shuffleCandidates": false,
    "multiStepVoting": false,
    "canContestMultiplePositions": false,
    "enableWeightedVoting": false,
    "enablePayToVote": false,
    "enablePayToRegisterCandidate": false,
    "voting": {
      "requireVoterIdToVote": false
    },
    "registration": {
      "voterCanRegister": false,
      "voterPublicRegistrationClosesAt": null,
      "candidateCanRegister": false,
      "candidatePublicRegistrationClosesAt": null,
      "requireVoterIdToRegister": false,
      "voterIdValidationLogic": null,
      "voterIdValidatingValue": null
    },
    "aliases": {
      "votingEvent": null,
      "votingCenter": null,
      "position": null,
      "group": null,
      "positionGroup": null,
      "candidateGroup": null,
      "voterGroup": null,
      "candidate": null,
      "voter": null,
      "voterId": null,
      "sponsor": null,
      "weight": null,
      "quadraticCredit": null
    },
    "plan": {
      "name": "Starter",
      "maxVoters": 500
    },
    "logoUrl": null,
    "createdAt": 1776900000000
  }
}

Logo example

Upload the image first. Then pass its storageId to the logo endpoint.

curl -X PUT "https://api.pepvote.com/voting-events/BOARD26/logo" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" \
  -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" \
  -d '{"storageId":"kg2storage01"}'
{
  "data": {
    "id": "j57event01",
    "code": "BOARD26",
    "logoUrl": "https://storage.example/logo.png"
  }
}

Delete returns 204 for a voting event. The stats response has votingEventId, positionCount, candidateCount, approvedCandidateCount, sponsorCount, groupCount, voterCount, approvedVoterCount, pendingVoterCount, votedVoterCount, votesCast, votesConfirmed, and turnoutPercent.

Was this helpful?

Last updated October 27, 2026

On this page