← POLIAPI/MOCKUPS/PUSH, DON'T POLL
api · mockup
// push, don't poll

Subscribe to a jurisdiction.
Get the event.

Ballot data changes unpredictably. Webhooks turn 'poll every endpoint every hour just in case' into one HTTP POST per actual change — HMAC-signed, replay-protected, exponentially retried.

// event catalogue

Every event you can subscribe to.

Event
When it fires
candidate.filed
A new candidate files paperwork in a tracked jurisdiction.
candidate.withdrew
A candidate withdraws from the ballot.
candidate.disqualified
An election authority removes a candidate (signature challenge, residency, etc).
measure.added
A new ballot measure is certified for an election.
measure.text.updated
The text or fiscal note of a measure changes.
measure.removed
A measure is struck (court ruling, withdrawal).
election.added
A new election is scheduled (regular, special, recall).
election.results.partial
First precincts report (election night).
election.results.final
Election certified by the authority of record.
officeholder.changed
A seat changes hands (election, appointment, resignation, death).
deadline.upcoming
A registration / filing / mail-ballot deadline is within N days.
source.broken
A source we depend on returned 4xx/5xx for >24h.
// payload

Signed, replay-protected, idempotent.

POST → your endpoint
POST /your/webhook HTTP/1.1
Content-Type: application/json
PoliAPI-Event: candidate.filed
PoliAPI-Delivery: 7f3c9e2a-...        // unique per attempt (idempotency key)
PoliAPI-Signature: t=1739564800,v1=...  // HMAC-SHA256 of timestamp + body

{
  "event": "candidate.filed",
  "occurred_at": "2026-02-14T18:22:09Z",
  "jurisdiction": "ocd-division/.../place:asheville",
  "candidate": { "id": "cnd_9k2", "name": "Jordan Reyes" },
  "source_url": "https://buncombecounty.gov/elections/..."
}
verifying the signature (node)
import { createHmac, timingSafeEqual } from 'crypto';

const sig = req.headers['poliapi-signature'];
const [tPart, v1Part] = sig.split(',');
const t  = tPart.split('=')[1];
const v1 = v1Part.split('=')[1];

const expected = createHmac('sha256', WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`)
  .digest('hex');

if (!timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) {
  return res.status(401).send('bad sig');
}
if (Date.now() / 1000 - Number(t) > 300) {
  return res.status(401).send('replay');
}
// reliability

Delivery contract.

Retry
Exponential backoff: 1m, 5m, 30m, 2h, 12h, 24h. 6 attempts before disable.
Idempotency
Same delivery ID may arrive twice. Dedupe with PoliAPI-Delivery header.
Backpressure
Per-endpoint queue. If your endpoint slows, we slow — never drop.
Replay
Manual replay last 30 days from dashboard or POST /v1/webhooks/{id}/replay.