Pepvote Support Center

Candidates

Read and manage candidates in a voting event.

Endpoints

MethodPathScopeDescription
GET/voting-events/:idOrCode/candidatesreadList candidates.
POST/voting-events/:idOrCode/candidateswriteCreate a candidate.
POST/voting-events/:idOrCode/candidates/batchwriteCreate up to 100 candidates.
POST/voting-events/:idOrCode/candidates/approvewriteApprove up to 100 candidates.
POST/voting-events/:idOrCode/candidates/unapprovewriteRemove approval from up to 100 candidates.
GET/voting-events/:idOrCode/candidates/:idreadGet a candidate.
PATCH/voting-events/:idOrCode/candidates/:idwriteUpdate a candidate.
DELETE/voting-events/:idOrCode/candidates/:idwriteDelete a candidate.
PUT/voting-events/:idOrCode/candidates/:id/avatarwriteSet an avatar from an upload.
DELETE/voting-events/:idOrCode/candidates/:id/avatarwriteRemove an avatar.

Query parameters

NameTypeRequiredDescription
positionIdstringNoFilter by position.
groupIdstringNoFilter by group.
statusnot_approved, pending, or approvedNoFilter by registration status.
searchstringNoSearch candidate names and emails.
expandgroup, positions, or bothNoAdd the candidate's group and positions.

Send ?expand=group,positions on the list or one-candidate endpoint. Each returned candidate then includes a group object and a positions array. A missing group is null.

Request fields

name is required on a single create. Send at least one field on update. On update, groupId and referendumRole accept null to clear them. avatarUrl is an external image URL and is accepted on a create or in a batch row. To store an image in Pepvote, use the avatar endpoints after the upload flow.

FieldTypeDescription
namestring1 to 200 characters.
emailstringUp to 320 characters.
positionIdsstring arrayPosition IDs.
groupIdstring or nullGroup ID.
statusenumnot_approved, pending, or approved.
referendumRoleenum or nullfor, against, or abstain.
avatarUrlstringExternal image URL, up to 2,048 characters. Create and batch only.

Create example

curl -X POST "https://api.pepvote.com/voting-events/BOARD26/candidates" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" -H "Idempotency-Key: candidate-amina-001" \
  -d '{"name":"Amina Bello","email":"amina@example.com","positionIds":["j57position01"],"status":"approved","avatarUrl":"https://images.example/amina.jpg"}'
{
  "data": {
    "id": "j57candidate01",
    "votingEventId": "j57event01",
    "groupId": null,
    "positionIds": [
      "j57position01"
    ],
    "name": "Amina Bello",
    "email": "amina@example.com",
    "status": "approved",
    "selfRegistered": false,
    "referendumRole": null,
    "avatarUrl": "https://images.example/amina.jpg",
    "createdAt": 1776900200000
  }
}

Batch create and approval

A batch accepts { "candidates": [...] } with 1 to 100 rows. It uses the batch rate limit bucket and returns { "data": { "created": [...], "skipped": [{ "index": 0, "reason": "..." }] } }.

curl -X POST "https://api.pepvote.com/voting-events/BOARD26/candidates/approve" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" -d '{"ids":["j57candidate01","j57candidate02"]}'
{
  "data": {
    "approvedCount": 2,
    "errors": [
    ]
  }
}

unapprove returns unapprovedCount instead. Both endpoints accept 1 to 100 IDs. An error item has id and reason.

Avatar example

curl -X PUT "https://api.pepvote.com/voting-events/BOARD26/candidates/j57candidate01/avatar" \
  -H "Authorization: Bearer $PEPVOTE_API_KEY" -H "User-Agent: my-app/1.0" \
  -H "Content-Type: application/json" -d '{"storageId":"kg2storage01"}'
{
  "data": {
    "id": "j57candidate01",
    "name": "Amina Bello",
    "avatarUrl": "https://storage.example/avatar.png"
  }
}

A successful create returns 201. Delete returns 202 with { "data": { "id": "...", "deletion": "queued" } }.

Was this helpful?

Last updated September 6, 2026

On this page