Leader election in two HTTP calls.
Create a room once. Let every candidate campaign. One process receives a short lease and a secret leader token. Everyone else receives the leader and when to try again.
Copy this. You have a leader.
ROOM=$(curl -s -X POST https://api.octostore.io/elections \
| jq -r .election_id)
curl -s -X POST \
"https://api.octostore.io/elections/$ROOM/campaign" \
-H "Content-Type: application/json" \
-d '{"candidate_id":"worker-a","ttl_seconds":30}'
Run the campaign call from every candidate. The first live winner gets status: "leader". The others get status: "follower". They all see the same candidate ID, term, expiry, and retry timing.
The response tells you what to do next.
If you won
{
"status": "leader",
"leader": {
"candidate_id": "worker-a",
"term": 1842,
"expires_at": "..."
},
"leader_token": "...",
"renew_after_ms": 15000
}
Save the token, start leader-only work, and renew around renew_after_ms.
If someone else won
{
"status": "follower",
"leader": {
"candidate_id": "worker-a",
"term": 1842,
"expires_at": "..."
},
"retry_after_ms": 29876
}
Do not perform leader-only work. Wait for the returned delay, then campaign again.
Keep the lease while you are healthy.
The leader token is a bearer capability. It can renew or resign the current term, but it does not create an account and it grants no authority over another room.
curl -s -X POST \
"https://api.octostore.io/elections/$ROOM/renew" \
-H "Content-Type: application/json" \
-d "{\"leader_token\":\"$LEADER_TOKEN\",\"ttl_seconds\":30}"
Public leases can last from 5 to 300 seconds. Renewing keeps the same term. If renewal stops because the leader crashes or loses the network, the lease expires and a later campaign can create a higher term.
Resign when you are done.
A clean shutdown does not need to make followers wait for expiry.
curl -s -X POST \
"https://api.octostore.io/elections/$ROOM/resign" \
-H "Content-Type: application/json" \
-d "{\"leader_token\":\"$LEADER_TOKEN\"}"
Why the term matters.
A lease tells candidates who should be leader now. It cannot erase an old process's memory. A paused leader can wake up after its lease expires and still believe it is in charge.
Carry the returned term into downstream writes when the destination can remember the newest value. Once it has accepted 1843, it can reject a late write from 1842. Leases solve liveness. Fencing terms solve stale authority.
Use it from anything.
Cron and scheduled jobs. Let one machine run the cleanup even when the schedule fires everywhere.
Controllers and reconcilers. Keep one active coordinator while warm standbys observe.
Migrations and maintenance. Prevent two deploy processes from starting the same singleton task.
Agents and background workers. Choose one dispatcher without forcing the fleet into a workflow engine.
No signup does not mean no boundary.
- The generated 192-bit room ID is a hard-to-guess coordination address, not authentication.
- Anyone who knows the room ID can campaign or inspect its public leader.
- Only the 256-bit leader token can renew or resign the current term.
- Keep leader tokens out of URLs and logs.
- Room creation and campaigns have a per-client admission budget; follow
Retry-Afterafter a429. - Self-host when room discovery, traffic, or state must remain private.