{"openapi":"3.1.0","info":{"title":"VOTING.md API","version":"1.1","description":"A skill file for agents that start, join, cast, count or report votes among agents and people, with your rules written in: who may vote, how ballots are counted, quorum and thresholds, windows and reminders, delegation, and what the agent may do on its own. Read-only tools over HTTP and MCP write a vote spec, check ballots, tally in six methods, check quorum and resolve delegations. Every voter, ballot and rule comes from your request; nothing here runs, hosts or certifies an election. Read-only, no key, nothing stored. Use at your own risk. voting.md is provided as is, without warranty. Information here may be inaccurate, incomplete or not current, and is not verified; figures are estimates from the numbers you send and the formulas stated. Nothing here is legal, governance, election, corporate, financial, security or other advice, and no result here is a certified, official, binding or legally effective outcome. voting.md never runs, hosts, certifies or enforces an election, never verifies a voter, and never casts a vote a person didn't instruct. Check everything yourself before you act on it.","termsOfService":"https://www.voting.md/terms","license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://www.voting.md"}],"paths":{"/voting.md":{"get":{"operationId":"getSkill","summary":"The VOTING.md skill as Markdown. Add a preset or any setting to write your settings in; notes on clamped or ignored values come back in the X-Settings-Notes header.","parameters":[{"name":"preset","in":"query","required":false,"schema":{"type":"string","enum":["core","team_decision","council","weighted_holders"]}},{"name":"eligibility","in":"query","required":false,"description":"Who may vote: list_only (Only voters on the list the person gave), invited (Anyone the person invited), open (Anyone who sends a ballot). Default list_only.","schema":{"type":"string","enum":["list_only","invited","open"]}},{"name":"duplicate_rule","in":"query","required":false,"description":"A second ballot from the same voter: last (The latest one counts), first (The first one counts), reject (None of them count). Default last.","schema":{"type":"string","enum":["last","first","reject"]}},{"name":"late_ballots","in":"query","required":false,"description":"Ballots outside the window: reject (Don't count them), flag (Count them, flagged). Optional; unset clears it.","schema":{"type":"string","enum":["reject","flag","unset"]}},{"name":"identity","in":"query","required":false,"description":"Voter identity: as_given (As the person's own system gives it; never verified by the agent). Default as_given.","schema":{"type":"string","enum":["as_given"]}},{"name":"method","in":"query","required":false,"description":"Counting method: plurality (Plurality: one choice, most votes wins), approval (Approval: approve any number), ranked_choice (Ranked choice (instant runoff)), borda (Borda count (points by rank)), condorcet (Condorcet (beats every other head to head)), score (Score (points per option)). Default plurality.","schema":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"]}},{"name":"quorum_share","in":"query","required":false,"description":"Quorum: share of eligible voters who must take part (share (0-1)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_share","in":"query","required":false,"description":"Threshold: share the winner or yes must reach (share (0.5001 = strict majority)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_base","in":"query","required":false,"description":"Threshold measured against: cast (Votes cast), eligible (All eligible voters). Optional; unset clears it.","schema":{"type":"string","enum":["cast","eligible","unset"]}},{"name":"tie_rule","in":"query","required":false,"description":"A tie: stop (Stop; a person decides), runoff (Runoff among the tied options), status_quo (No option wins; the current state stands). Default stop.","schema":{"type":"string","enum":["stop","runoff","status_quo"]}},{"name":"window_hours","in":"query","required":false,"description":"A vote stays open for (hours). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0.25,"maximum":720}},{"name":"reminder_hours_before","in":"query","required":false,"description":"Remind voters this long before closing (hours (0 = never)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":168}},{"name":"report_results","in":"query","required":false,"description":"After closing, report the tally: person_first (To the person first; they decide who else sees it), all_voters (To the person and every voter). Default person_first.","schema":{"type":"string","enum":["person_first","all_voters"]}},{"name":"delegation","in":"query","required":false,"description":"Voters may delegate their vote: never (Never), allowed (Allowed, to another eligible voter). Default never.","schema":{"type":"string","enum":["never","allowed"]}},{"name":"max_delegation_depth","in":"query","required":false,"description":"Longest delegation chain honored (steps). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":10}},{"name":"own_ballot_wins","in":"query","required":false,"description":"A delegator who also votes: yes (Keeps their own vote), no (Their delegation stands). Optional; unset clears it.","schema":{"type":"string","enum":["yes","no","unset"]}},{"name":"cast_votes","in":"query","required":false,"description":"Casting a ballot: only_as_instructed (Only as the person instructed, on that question). Default only_as_instructed.","schema":{"type":"string","enum":["only_as_instructed"]}},{"name":"initiate_votes","in":"query","required":false,"description":"Starting a vote: draft_only (Draft the spec for the person to start), send_approved (Open votes the person approved, with their tools), never (Never). Default draft_only.","schema":{"type":"string","enum":["draft_only","send_approved","never"]}},{"name":"invite_agents","in":"query","required":false,"description":"Inviting voters: draft_only (Draft the invitation for the person to send), send_approved (Send invitations the person approved, from accounts they gave), never (Never). Default draft_only.","schema":{"type":"string","enum":["draft_only","send_approved","never"]}},{"name":"public_elections","in":"query","required":false,"description":"Public or government elections: never (Never: no ballots, no counts, no advice). Default never.","schema":{"type":"string","enum":["never"]}}],"responses":{"200":{"description":"The skill","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/api/v1/settings":{"get":{"operationId":"listSettings","summary":"Every setting (group, kind, unit, range, options, default) and the presets.","responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}}}}},"/api/v1/vote_spec":{"get":{"operationId":"voteSpecGet","summary":"Write a vote spec","description":"Turns a question into a complete vote spec: options, method, who may vote, window, quorum, threshold, tie and duplicate rules, delegation, and who runs it, plus a VOTE.md text, a draft invitation for the voters and the checklist the person approves before the vote opens or any invite goes out. It flags a window that is too short or already past, a quorum no turnout could reach, and a method that doesn't fit the options. Nothing is sent, opened or hosted; the person starts the vote with their own tools.","parameters":[{"name":"question","in":"query","required":true,"description":"The question, as it will be put to the voters.","schema":{"type":"string"}},{"name":"options","in":"query","required":false,"description":"The options, 2 to 50 labels. Leave out for a yes/no question. URL-encoded JSON.","schema":{"type":"string"}},{"name":"yes_no","in":"query","required":false,"description":"A yes/no question: options become yes, no (default when options are not sent).","schema":{"type":"boolean"}},{"name":"method","in":"query","required":false,"description":"How ballots are counted. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality.","schema":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"]}},{"name":"eligible_voters","in":"query","required":false,"description":"Who may vote, as labels (agents or people). URL-encoded JSON.","schema":{"type":"string"}},{"name":"eligible_count","in":"query","required":false,"description":"Or how many may vote, when the list is kept elsewhere.","schema":{"type":"integer","minimum":1,"maximum":10000000}},{"name":"opens_at","in":"query","required":false,"description":"When voting opens, ISO 8601 (default: now).","schema":{"type":"string"}},{"name":"closes_at","in":"query","required":false,"description":"When voting closes, ISO 8601. Or send window_hours.","schema":{"type":"string"}},{"name":"window_hours","in":"query","required":false,"description":"How long the vote stays open from opens_at (default 24).","schema":{"type":"number","minimum":0.25,"maximum":720}},{"name":"quorum_share","in":"query","required":false,"description":"Share of eligible voters who must take part.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_share","in":"query","required":false,"description":"Share the winner or yes must reach (0.5001 strict majority, 0.667 two thirds).","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_base","in":"query","required":false,"description":"cast (default) or eligible.","schema":{"type":"string","enum":["cast","eligible"]}},{"name":"tie_rule","in":"query","required":false,"description":"stop (a person decides, default), runoff, or status_quo.","schema":{"type":"string","enum":["stop","runoff","status_quo"]}},{"name":"duplicate_rule","in":"query","required":false,"description":"last (default), first or reject.","schema":{"type":"string","enum":["last","first","reject"]}},{"name":"delegation","in":"query","required":false,"description":"Whether a voter may delegate their vote to another voter (default never).","schema":{"type":"string","enum":["never","allowed"]}},{"name":"max_delegation_depth","in":"query","required":false,"description":"Longest delegation chain honored (default 3).","schema":{"type":"integer","minimum":1,"maximum":10}},{"name":"initiated_by","in":"query","required":false,"description":"The agent or person starting the vote, as a label.","schema":{"type":"string"}},{"name":"on_behalf_of","in":"query","required":false,"description":"The person, team or body the vote is held for.","schema":{"type":"string"}},{"name":"invites","in":"query","required":false,"description":"Agents or people to invite, as labels (usually the eligible voters). URL-encoded JSON.","schema":{"type":"string"}},{"name":"reminder_hours_before","in":"query","required":false,"description":"Send a reminder this many hours before closing (0: none).","schema":{"type":"number","minimum":0,"maximum":168}},{"name":"now","in":"query","required":false,"description":"The current time, ISO 8601 (default: now).","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"voteSpec","summary":"Write a vote spec","description":"Turns a question into a complete vote spec: options, method, who may vote, window, quorum, threshold, tie and duplicate rules, delegation, and who runs it, plus a VOTE.md text, a draft invitation for the voters and the checklist the person approves before the vote opens or any invite goes out. It flags a window that is too short or already past, a quorum no turnout could reach, and a method that doesn't fit the options. Nothing is sent, opened or hosted; the person starts the vote with their own tools.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","maxLength":200,"description":"The question, as it will be put to the voters."},"options":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":50,"description":"The options, 2 to 50 labels. Leave out for a yes/no question."},"yes_no":{"type":"boolean","description":"A yes/no question: options become yes, no (default when options are not sent)."},"method":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"],"description":"How ballots are counted. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality."},"eligible_voters":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Who may vote, as labels (agents or people)."},"eligible_count":{"type":"integer","minimum":1,"maximum":10000000,"description":"Or how many may vote, when the list is kept elsewhere."},"opens_at":{"type":"string","description":"When voting opens, ISO 8601 (default: now)."},"closes_at":{"type":"string","description":"When voting closes, ISO 8601. Or send window_hours."},"window_hours":{"type":"number","minimum":0.25,"maximum":720,"description":"How long the vote stays open from opens_at (default 24)."},"quorum_share":{"type":"number","minimum":0,"maximum":1,"description":"Share of eligible voters who must take part."},"threshold_share":{"type":"number","minimum":0,"maximum":1,"description":"Share the winner or yes must reach (0.5001 strict majority, 0.667 two thirds)."},"threshold_base":{"type":"string","enum":["cast","eligible"],"description":"cast (default) or eligible."},"tie_rule":{"type":"string","enum":["stop","runoff","status_quo"],"description":"stop (a person decides, default), runoff, or status_quo."},"duplicate_rule":{"type":"string","enum":["last","first","reject"],"description":"last (default), first or reject."},"delegation":{"type":"string","enum":["never","allowed"],"description":"Whether a voter may delegate their vote to another voter (default never)."},"max_delegation_depth":{"type":"integer","minimum":1,"maximum":10,"description":"Longest delegation chain honored (default 3)."},"initiated_by":{"type":"string","maxLength":60,"description":"The agent or person starting the vote, as a label."},"on_behalf_of":{"type":"string","maxLength":80,"description":"The person, team or body the vote is held for."},"invites":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Agents or people to invite, as labels (usually the eligible voters)."},"reminder_hours_before":{"type":"number","minimum":0,"maximum":168,"description":"Send a reminder this many hours before closing (0: none)."},"now":{"type":"string","description":"The current time, ISO 8601 (default: now)."}},"required":["question"]},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"question":"Adopt the revised release plan for the next sprint?","yes_no":true,"eligible_voters":["agent-a","agent-b","agent-c","agent-d","agent-e","agent-f"],"window_hours":48,"quorum_share":0.5,"threshold_share":0.5001,"initiated_by":"planner-agent","on_behalf_of":"the release team","reminder_hours_before":6,"now":"2026-11-02T09:00Z"}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/check_ballots":{"get":{"operationId":"checkBallotsGet","summary":"Check ballots","description":"Checks each ballot against the vote's options, method, eligible list, window and duplicate rule, and says which would count and why the others wouldn't. With an eligible list it also says who hasn't voted yet. No count, no winner; use tally for that. It never verifies who really cast a ballot.","parameters":[{"name":"options","in":"query","required":true,"description":"The options, 2 to 50 labels. URL-encoded JSON.","schema":{"type":"string"}},{"name":"ballots","in":"query","required":true,"description":"The ballots: [{voter, weight?, choice | choices | ranking | scores, abstain?, cast_at?}]. URL-encoded JSON.","schema":{"type":"string"}},{"name":"method","in":"query","required":false,"description":"The method the ballots must fit. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality.","schema":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"]}},{"name":"eligible_voters","in":"query","required":false,"description":"Who may vote, as labels. Ballots from anyone else are invalid. Without it, every ballot's voter counts as eligible. URL-encoded JSON.","schema":{"type":"string"}},{"name":"duplicate_rule","in":"query","required":false,"description":"When a voter sends more than one ballot: last (the latest counts, default), first, or reject (none count).","schema":{"type":"string","enum":["last","first","reject"]}},{"name":"opens_at","in":"query","required":false,"description":"When the vote opened, ISO 8601. With cast_at on ballots, earlier ballots are rejected or flagged.","schema":{"type":"string"}},{"name":"closes_at","in":"query","required":false,"description":"When the vote closes, ISO 8601. With cast_at on ballots, later ballots are rejected or flagged.","schema":{"type":"string"}},{"name":"late_ballots","in":"query","required":false,"description":"Ballots outside the window: reject (default) or flag (count them, with a flag).","schema":{"type":"string","enum":["reject","flag"]}},{"name":"score_min","in":"query","required":false,"description":"score method: the lowest allowed score (default 0).","schema":{"type":"number","minimum":-1000,"maximum":1000}},{"name":"score_max","in":"query","required":false,"description":"score method: the highest allowed score (default 5).","schema":{"type":"number","minimum":-1000,"maximum":1000}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"checkBallots","summary":"Check ballots","description":"Checks each ballot against the vote's options, method, eligible list, window and duplicate rule, and says which would count and why the others wouldn't. With an eligible list it also says who hasn't voted yet. No count, no winner; use tally for that. It never verifies who really cast a ballot.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"options":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":50,"description":"The options, 2 to 50 labels."},"ballots":{"type":"array","items":{"type":"object","properties":{"voter":{"type":"string","description":"Who cast it: an agent or person label."},"weight":{"type":"number","minimum":0,"description":"Voting weight, default 1 (shares, tokens, seats: the person's own rule)."},"choice":{"type":"string","description":"plurality: the one option chosen."},"choices":{"type":"array","items":{"type":"string"},"description":"approval: every option approved."},"ranking":{"type":"array","items":{"type":"string"},"description":"ranked_choice, borda, condorcet: options in order of preference, best first; a partial ranking is allowed."},"scores":{"type":"object","description":"score: option to points, within score_min and score_max."},"abstain":{"type":"boolean","description":"An abstention: counts as cast, for no option."},"cast_at":{"type":"string","description":"When it was cast, ISO 8601, checked against the window when one is given."}},"required":["voter"]},"minItems":1,"maxItems":200,"description":"The ballots: [{voter, weight?, choice | choices | ranking | scores, abstain?, cast_at?}]."},"method":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"],"description":"The method the ballots must fit. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality."},"eligible_voters":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Who may vote, as labels. Ballots from anyone else are invalid. Without it, every ballot's voter counts as eligible."},"duplicate_rule":{"type":"string","enum":["last","first","reject"],"description":"When a voter sends more than one ballot: last (the latest counts, default), first, or reject (none count)."},"opens_at":{"type":"string","description":"When the vote opened, ISO 8601. With cast_at on ballots, earlier ballots are rejected or flagged."},"closes_at":{"type":"string","description":"When the vote closes, ISO 8601. With cast_at on ballots, later ballots are rejected or flagged."},"late_ballots":{"type":"string","enum":["reject","flag"],"description":"Ballots outside the window: reject (default) or flag (count them, with a flag)."},"score_min":{"type":"number","minimum":-1000,"maximum":1000,"description":"score method: the lowest allowed score (default 0)."},"score_max":{"type":"number","minimum":-1000,"maximum":1000,"description":"score method: the highest allowed score (default 5)."}},"required":["options","ballots"]},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"options":["yes","no"],"method":"plurality","eligible_voters":["agent-a","agent-b","agent-c","agent-d"],"opens_at":"2026-11-02T09:00Z","closes_at":"2026-11-02T17:00Z","ballots":[{"voter":"agent-a","choice":"yes","cast_at":"2026-11-02T09:30Z"},{"voter":"agent-b","choice":"maybe","cast_at":"2026-11-02T10:00Z"},{"voter":"agent-c","choice":"no","cast_at":"2026-11-02T18:00Z"},{"voter":"agent-x","choice":"yes","cast_at":"2026-11-02T11:00Z"},{"voter":"agent-a","choice":"no","cast_at":"2026-11-02T12:00Z"}]}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/tally":{"get":{"operationId":"tallyGet","summary":"Tally a vote","description":"Counts the ballots you send in one of six methods (plurality, approval, ranked_choice, borda, condorcet, score), with voting weights, an eligible list, a window and a duplicate rule. Lists invalid ballots with reasons and leaves them out. Checks quorum (share of eligible voters who cast a valid ballot or abstained) and a threshold (the winner's or the yes share of cast or eligible weight). A tie, a quorum or threshold shortfall, or an unresolved runoff is an exception for the people and the rules behind the vote: the tool never breaks a tie, certifies a result or verifies a voter.","parameters":[{"name":"options","in":"query","required":true,"description":"The options, 2 to 50 labels. For a yes/no vote use [\"yes\", \"no\"]. URL-encoded JSON.","schema":{"type":"string"}},{"name":"ballots","in":"query","required":true,"description":"The ballots: [{voter, weight?, choice | choices | ranking | scores, abstain?, cast_at?}]. URL-encoded JSON.","schema":{"type":"string"}},{"name":"method","in":"query","required":false,"description":"How to count. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality.","schema":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"]}},{"name":"eligible_voters","in":"query","required":false,"description":"Who may vote, as labels. Ballots from anyone else are invalid. Without it, every ballot's voter counts as eligible. URL-encoded JSON.","schema":{"type":"string"}},{"name":"duplicate_rule","in":"query","required":false,"description":"When a voter sends more than one ballot: last (the latest counts, default), first, or reject (none count).","schema":{"type":"string","enum":["last","first","reject"]}},{"name":"opens_at","in":"query","required":false,"description":"When the vote opened, ISO 8601. With cast_at on ballots, earlier ballots are rejected or flagged.","schema":{"type":"string"}},{"name":"closes_at","in":"query","required":false,"description":"When the vote closes, ISO 8601. With cast_at on ballots, later ballots are rejected or flagged.","schema":{"type":"string"}},{"name":"late_ballots","in":"query","required":false,"description":"Ballots outside the window: reject (default) or flag (count them, with a flag).","schema":{"type":"string","enum":["reject","flag"]}},{"name":"score_min","in":"query","required":false,"description":"score method: the lowest allowed score (default 0).","schema":{"type":"number","minimum":-1000,"maximum":1000}},{"name":"score_max","in":"query","required":false,"description":"score method: the highest allowed score (default 5).","schema":{"type":"number","minimum":-1000,"maximum":1000}},{"name":"eligible_count","in":"query","required":false,"description":"How many could vote, when you don't send the eligible list. Needed for quorum and an eligible-based threshold.","schema":{"type":"integer","minimum":1,"maximum":10000000}},{"name":"quorum_share","in":"query","required":false,"description":"Share of eligible voters (by count, or by weight with eligible_weight) that must take part for the result to count.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"eligible_weight","in":"query","required":false,"description":"Total weight of everyone eligible, for a weighted quorum or an eligible-based threshold.","schema":{"type":"number","minimum":0}},{"name":"threshold_share","in":"query","required":false,"description":"Share the winner (or yes) must reach: of valid non-abstaining ballots (threshold_base cast) or of all eligible (eligible). 0.5 means more than half is not required; use 0.5001 for a strict majority, or 0.667 for two thirds.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_base","in":"query","required":false,"description":"What the threshold share is measured against: cast (default) or eligible.","schema":{"type":"string","enum":["cast","eligible"]}},{"name":"tie_rule","in":"query","required":false,"description":"What the rules say about a tie: stop (default, a person decides), runoff (the tool proposes a runoff among the leaders), status_quo (no option wins; the current state stands).","schema":{"type":"string","enum":["stop","runoff","status_quo"]}},{"name":"status_quo","in":"query","required":false,"description":"The option that stands under the status_quo tie rule, if it is one of the options (for example no).","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"tally","summary":"Tally a vote","description":"Counts the ballots you send in one of six methods (plurality, approval, ranked_choice, borda, condorcet, score), with voting weights, an eligible list, a window and a duplicate rule. Lists invalid ballots with reasons and leaves them out. Checks quorum (share of eligible voters who cast a valid ballot or abstained) and a threshold (the winner's or the yes share of cast or eligible weight). A tie, a quorum or threshold shortfall, or an unresolved runoff is an exception for the people and the rules behind the vote: the tool never breaks a tie, certifies a result or verifies a voter.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"options":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":50,"description":"The options, 2 to 50 labels. For a yes/no vote use [\"yes\", \"no\"]."},"ballots":{"type":"array","items":{"type":"object","properties":{"voter":{"type":"string","description":"Who cast it: an agent or person label."},"weight":{"type":"number","minimum":0,"description":"Voting weight, default 1 (shares, tokens, seats: the person's own rule)."},"choice":{"type":"string","description":"plurality: the one option chosen."},"choices":{"type":"array","items":{"type":"string"},"description":"approval: every option approved."},"ranking":{"type":"array","items":{"type":"string"},"description":"ranked_choice, borda, condorcet: options in order of preference, best first; a partial ranking is allowed."},"scores":{"type":"object","description":"score: option to points, within score_min and score_max."},"abstain":{"type":"boolean","description":"An abstention: counts as cast, for no option."},"cast_at":{"type":"string","description":"When it was cast, ISO 8601, checked against the window when one is given."}},"required":["voter"]},"minItems":1,"maxItems":200,"description":"The ballots: [{voter, weight?, choice | choices | ranking | scores, abstain?, cast_at?}]."},"method":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"],"description":"How to count. One of plurality, approval, ranked_choice, borda, condorcet, score. Default plurality."},"eligible_voters":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Who may vote, as labels. Ballots from anyone else are invalid. Without it, every ballot's voter counts as eligible."},"duplicate_rule":{"type":"string","enum":["last","first","reject"],"description":"When a voter sends more than one ballot: last (the latest counts, default), first, or reject (none count)."},"opens_at":{"type":"string","description":"When the vote opened, ISO 8601. With cast_at on ballots, earlier ballots are rejected or flagged."},"closes_at":{"type":"string","description":"When the vote closes, ISO 8601. With cast_at on ballots, later ballots are rejected or flagged."},"late_ballots":{"type":"string","enum":["reject","flag"],"description":"Ballots outside the window: reject (default) or flag (count them, with a flag)."},"score_min":{"type":"number","minimum":-1000,"maximum":1000,"description":"score method: the lowest allowed score (default 0)."},"score_max":{"type":"number","minimum":-1000,"maximum":1000,"description":"score method: the highest allowed score (default 5)."},"eligible_count":{"type":"integer","minimum":1,"maximum":10000000,"description":"How many could vote, when you don't send the eligible list. Needed for quorum and an eligible-based threshold."},"quorum_share":{"type":"number","minimum":0,"maximum":1,"description":"Share of eligible voters (by count, or by weight with eligible_weight) that must take part for the result to count."},"eligible_weight":{"type":"number","minimum":0,"description":"Total weight of everyone eligible, for a weighted quorum or an eligible-based threshold."},"threshold_share":{"type":"number","minimum":0,"maximum":1,"description":"Share the winner (or yes) must reach: of valid non-abstaining ballots (threshold_base cast) or of all eligible (eligible). 0.5 means more than half is not required; use 0.5001 for a strict majority, or 0.667 for two thirds."},"threshold_base":{"type":"string","enum":["cast","eligible"],"description":"What the threshold share is measured against: cast (default) or eligible."},"tie_rule":{"type":"string","enum":["stop","runoff","status_quo"],"description":"What the rules say about a tie: stop (default, a person decides), runoff (the tool proposes a runoff among the leaders), status_quo (no option wins; the current state stands)."},"status_quo":{"type":"string","description":"The option that stands under the status_quo tie rule, if it is one of the options (for example no)."}},"required":["options","ballots"]},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"options":["Adopt the plan","Revise and revote","Keep things as they are"],"method":"ranked_choice","ballots":[{"voter":"agent-a","ranking":["Adopt the plan","Revise and revote"]},{"voter":"agent-b","ranking":["Revise and revote","Adopt the plan"]},{"voter":"agent-c","ranking":["Keep things as they are","Revise and revote"]},{"voter":"agent-d","ranking":["Adopt the plan"]},{"voter":"agent-e","ranking":["Revise and revote","Keep things as they are"]},{"voter":"agent-f","ranking":["Keep things as they are","Adopt the plan"]},{"voter":"agent-g","ranking":["Adopt the plan","Keep things as they are"]}],"eligible_count":9,"quorum_share":0.5,"threshold_share":0.5001}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/quorum_check":{"get":{"operationId":"quorumCheckGet","summary":"Quorum and threshold check","description":"For a vote in progress or just closed: turnout against the quorum, how many more voters (or how much more weight) are needed, time left in the window and the pace needed to get there, and for a yes/no question whether it passes now, could still pass, or can no longer pass. Every count and rule comes from you; the tool never closes, extends or decides a vote.","parameters":[{"name":"eligible_count","in":"query","required":false,"description":"How many may vote. Or send eligible_voters.","schema":{"type":"integer","minimum":1,"maximum":10000000}},{"name":"eligible_voters","in":"query","required":false,"description":"Who may vote, as labels; its length is the eligible count. URL-encoded JSON.","schema":{"type":"string"}},{"name":"voted","in":"query","required":false,"description":"Who has a valid ballot so far, as labels. Or send ballots_cast. URL-encoded JSON.","schema":{"type":"string"}},{"name":"ballots_cast","in":"query","required":false,"description":"How many valid ballots so far, including abstentions.","schema":{"type":"integer","minimum":0,"maximum":10000000}},{"name":"quorum_share","in":"query","required":false,"description":"Share of eligible voters who must take part.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"quorum_count","in":"query","required":false,"description":"Or a fixed number of voters who must take part.","schema":{"type":"integer","minimum":0,"maximum":10000000}},{"name":"yes","in":"query","required":false,"description":"For a yes/no question: yes weight (or count) so far.","schema":{"type":"number","minimum":0}},{"name":"no","in":"query","required":false,"description":"No weight (or count) so far.","schema":{"type":"number","minimum":0}},{"name":"abstain","in":"query","required":false,"description":"Abstentions so far.","schema":{"type":"number","minimum":0}},{"name":"threshold_share","in":"query","required":false,"description":"Share yes must reach, of cast non-abstaining votes (threshold_base cast) or of all eligible (eligible). Default 0.5001, a strict majority.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_base","in":"query","required":false,"description":"cast (default) or eligible.","schema":{"type":"string","enum":["cast","eligible"]}},{"name":"closes_at","in":"query","required":false,"description":"When the vote closes, ISO 8601, for time left and pace.","schema":{"type":"string"}},{"name":"now","in":"query","required":false,"description":"The current time, ISO 8601 (default: now).","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"quorumCheck","summary":"Quorum and threshold check","description":"For a vote in progress or just closed: turnout against the quorum, how many more voters (or how much more weight) are needed, time left in the window and the pace needed to get there, and for a yes/no question whether it passes now, could still pass, or can no longer pass. Every count and rule comes from you; the tool never closes, extends or decides a vote.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"eligible_count":{"type":"integer","minimum":1,"maximum":10000000,"description":"How many may vote. Or send eligible_voters."},"eligible_voters":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Who may vote, as labels; its length is the eligible count."},"voted":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Who has a valid ballot so far, as labels. Or send ballots_cast."},"ballots_cast":{"type":"integer","minimum":0,"maximum":10000000,"description":"How many valid ballots so far, including abstentions."},"quorum_share":{"type":"number","minimum":0,"maximum":1,"description":"Share of eligible voters who must take part."},"quorum_count":{"type":"integer","minimum":0,"maximum":10000000,"description":"Or a fixed number of voters who must take part."},"yes":{"type":"number","minimum":0,"description":"For a yes/no question: yes weight (or count) so far."},"no":{"type":"number","minimum":0,"description":"No weight (or count) so far."},"abstain":{"type":"number","minimum":0,"description":"Abstentions so far."},"threshold_share":{"type":"number","minimum":0,"maximum":1,"description":"Share yes must reach, of cast non-abstaining votes (threshold_base cast) or of all eligible (eligible). Default 0.5001, a strict majority."},"threshold_base":{"type":"string","enum":["cast","eligible"],"description":"cast (default) or eligible."},"closes_at":{"type":"string","description":"When the vote closes, ISO 8601, for time left and pace."},"now":{"type":"string","description":"The current time, ISO 8601 (default: now)."}}},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"eligible_count":40,"ballots_cast":17,"quorum_share":0.5,"yes":11,"no":5,"abstain":1,"threshold_share":0.5001,"closes_at":"2026-11-02T17:00Z","now":"2026-11-02T13:00Z"}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/resolve_delegations":{"get":{"operationId":"resolveDelegationsGet","summary":"Resolve delegations","description":"Follows delegations (from one voter to another, chains allowed up to max_depth) and works out each voter's effective weight: their own plus everything delegated to them, directly or through others. With the ballots cast so far, a delegator who voted keeps their own vote (own_ballot_wins) and a delegate who never voted leaves the delegated weight uncast. Cycles and chains that are too deep stop with an exception. Returns ballots_for_tally with the weights filled in. It never verifies that a delegation was really given.","parameters":[{"name":"voters","in":"query","required":true,"description":"Every eligible voter, as labels. Voters not listed can't delegate or receive. URL-encoded JSON.","schema":{"type":"string"}},{"name":"weights","in":"query","required":false,"description":"Base weight per voter label (default 1 each). URL-encoded JSON.","schema":{"type":"string"}},{"name":"delegations","in":"query","required":true,"description":"Who delegates to whom: [{from, to}]. One delegation per voter; a later one for the same voter replaces it. URL-encoded JSON.","schema":{"type":"string"}},{"name":"ballots","in":"query","required":false,"description":"Ballots cast so far (voter plus choice, choices, ranking or scores). Optional: without them only the effective weights are worked out. URL-encoded JSON.","schema":{"type":"string"}},{"name":"max_depth","in":"query","required":false,"description":"Longest chain honored (default 3). A voter whose chain is longer keeps their own weight uncast.","schema":{"type":"integer","minimum":1,"maximum":10}},{"name":"own_ballot_wins","in":"query","required":false,"description":"A delegator who cast their own ballot keeps their weight for it (default true). false: their delegation stands and their own ballot is dropped.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"resolveDelegations","summary":"Resolve delegations","description":"Follows delegations (from one voter to another, chains allowed up to max_depth) and works out each voter's effective weight: their own plus everything delegated to them, directly or through others. With the ballots cast so far, a delegator who voted keeps their own vote (own_ballot_wins) and a delegate who never voted leaves the delegated weight uncast. Cycles and chains that are too deep stop with an exception. Returns ballots_for_tally with the weights filled in. It never verifies that a delegation was really given.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"voters":{"type":"array","items":{"type":"string"},"maxItems":200,"description":"Every eligible voter, as labels. Voters not listed can't delegate or receive."},"weights":{"type":"object","description":"Base weight per voter label (default 1 each)."},"delegations":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"]},"description":"Who delegates to whom: [{from, to}]. One delegation per voter; a later one for the same voter replaces it."},"ballots":{"type":"array","items":{"type":"object","properties":{"voter":{"type":"string","description":"Who cast it: an agent or person label."},"weight":{"type":"number","minimum":0,"description":"Voting weight, default 1 (shares, tokens, seats: the person's own rule)."},"choice":{"type":"string","description":"plurality: the one option chosen."},"choices":{"type":"array","items":{"type":"string"},"description":"approval: every option approved."},"ranking":{"type":"array","items":{"type":"string"},"description":"ranked_choice, borda, condorcet: options in order of preference, best first; a partial ranking is allowed."},"scores":{"type":"object","description":"score: option to points, within score_min and score_max."},"abstain":{"type":"boolean","description":"An abstention: counts as cast, for no option."},"cast_at":{"type":"string","description":"When it was cast, ISO 8601, checked against the window when one is given."}},"required":["voter"]},"maxItems":200,"description":"Ballots cast so far (voter plus choice, choices, ranking or scores). Optional: without them only the effective weights are worked out."},"max_depth":{"type":"integer","minimum":1,"maximum":10,"description":"Longest chain honored (default 3). A voter whose chain is longer keeps their own weight uncast."},"own_ballot_wins":{"type":"boolean","description":"A delegator who cast their own ballot keeps their weight for it (default true). false: their delegation stands and their own ballot is dropped."}},"required":["voters","delegations"]},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"voters":["agent-a","agent-b","agent-c","agent-d","agent-e","agent-f"],"weights":{"agent-a":1,"agent-b":1,"agent-c":2,"agent-d":1,"agent-e":1,"agent-f":1},"delegations":[{"from":"agent-b","to":"agent-a"},{"from":"agent-c","to":"agent-b"},{"from":"agent-e","to":"agent-f"}],"ballots":[{"voter":"agent-a","choice":"yes"},{"voter":"agent-d","choice":"no"},{"voter":"agent-f","choice":"no"}],"max_depth":3}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/vote_template":{"get":{"operationId":"voteTemplateGet","summary":"Get a vote template for agents","description":"Serves five ready-to-copy Markdown templates for votes among agents: two inside one agent (self-consistency sampling, a lens council) and three between agents (a ranked-choice decision, a plan approval with the person, a judge panel). Without kind it lists them with when to use each and its URL; with kind it returns the template text, the vote spec parsed from it, the example ballots, the exact tally call and a ready tally body. The templates are fixed text on this site with made-up names and numbers, not data; every count they describe is arithmetic on the ballots sent, never a certified, official or binding result, and nothing here opens, hosts or runs a vote.","parameters":[{"name":"kind","in":"query","required":false,"description":"Which template: self-consistency (one agent samples itself N times, counted by stated confidence), lens-council (one agent reviews a draft through fixed lenses, any veto stops), agent-decision (agents pick one option by ranked choice, with quorum, a window and delegation), plan-approval (agents and the person say yes or no, two thirds of eligible, the person's no is a veto), judge-panel (judge agents score blinded candidates, Borda cross-check). Leave out for the list.","schema":{"type":"string","enum":["self-consistency","lens-council","agent-decision","plan-approval","judge-panel"]}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"voteTemplate","summary":"Get a vote template for agents","description":"Serves five ready-to-copy Markdown templates for votes among agents: two inside one agent (self-consistency sampling, a lens council) and three between agents (a ranked-choice decision, a plan approval with the person, a judge panel). Without kind it lists them with when to use each and its URL; with kind it returns the template text, the vote spec parsed from it, the example ballots, the exact tally call and a ready tally body. The templates are fixed text on this site with made-up names and numbers, not data; every count they describe is arithmetic on the ballots sent, never a certified, official or binding result, and nothing here opens, hosts or runs a vote.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["self-consistency","lens-council","agent-decision","plan-approval","judge-panel"],"description":"Which template: self-consistency (one agent samples itself N times, counted by stated confidence), lens-council (one agent reviews a draft through fixed lenses, any veto stops), agent-decision (agents pick one option by ranked choice, with quorum, a window and delegation), plan-approval (agents and the person say yes or no, two thirds of eligible, the person's no is a veto), judge-panel (judge agents score blinded candidates, Borda cross-check). Leave out for the list."}}},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"kind":"agent-decision"}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/build_settings":{"get":{"operationId":"buildSettingsGet","summary":"Write your settings into the skill","description":"Turns a preset and settings into the sections written at the top of VOTING.md. Every setting is a number or a fixed choice; the catalog is at https://www.voting.md/api/v1/settings. Returns the sections as Markdown, the settings as JSON, a link to the skill with them written in and a one-line install. Out-of-range numbers are clamped with a note. Nothing is stored. Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","parameters":[{"name":"preset","in":"query","required":false,"description":"Starting point: core, team_decision, council, weighted_holders. Applied first; each setting overrides it.","schema":{"type":"string","enum":["core","team_decision","council","weighted_holders"]}},{"name":"eligibility","in":"query","required":false,"description":"Who may vote: list_only (Only voters on the list the person gave), invited (Anyone the person invited), open (Anyone who sends a ballot). Default list_only.","schema":{"type":"string","enum":["list_only","invited","open"]}},{"name":"duplicate_rule","in":"query","required":false,"description":"A second ballot from the same voter: last (The latest one counts), first (The first one counts), reject (None of them count). Default last.","schema":{"type":"string","enum":["last","first","reject"]}},{"name":"late_ballots","in":"query","required":false,"description":"Ballots outside the window: reject (Don't count them), flag (Count them, flagged). Optional; unset clears it.","schema":{"type":"string","enum":["reject","flag","unset"]}},{"name":"identity","in":"query","required":false,"description":"Voter identity: as_given (As the person's own system gives it; never verified by the agent). Default as_given.","schema":{"type":"string","enum":["as_given"]}},{"name":"method","in":"query","required":false,"description":"Counting method: plurality (Plurality: one choice, most votes wins), approval (Approval: approve any number), ranked_choice (Ranked choice (instant runoff)), borda (Borda count (points by rank)), condorcet (Condorcet (beats every other head to head)), score (Score (points per option)). Default plurality.","schema":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"]}},{"name":"quorum_share","in":"query","required":false,"description":"Quorum: share of eligible voters who must take part (share (0-1)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_share","in":"query","required":false,"description":"Threshold: share the winner or yes must reach (share (0.5001 = strict majority)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"threshold_base","in":"query","required":false,"description":"Threshold measured against: cast (Votes cast), eligible (All eligible voters). Optional; unset clears it.","schema":{"type":"string","enum":["cast","eligible","unset"]}},{"name":"tie_rule","in":"query","required":false,"description":"A tie: stop (Stop; a person decides), runoff (Runoff among the tied options), status_quo (No option wins; the current state stands). Default stop.","schema":{"type":"string","enum":["stop","runoff","status_quo"]}},{"name":"window_hours","in":"query","required":false,"description":"A vote stays open for (hours). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0.25,"maximum":720}},{"name":"reminder_hours_before","in":"query","required":false,"description":"Remind voters this long before closing (hours (0 = never)). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":168}},{"name":"report_results","in":"query","required":false,"description":"After closing, report the tally: person_first (To the person first; they decide who else sees it), all_voters (To the person and every voter). Default person_first.","schema":{"type":"string","enum":["person_first","all_voters"]}},{"name":"delegation","in":"query","required":false,"description":"Voters may delegate their vote: never (Never), allowed (Allowed, to another eligible voter). Default never.","schema":{"type":"string","enum":["never","allowed"]}},{"name":"max_delegation_depth","in":"query","required":false,"description":"Longest delegation chain honored (steps). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":10}},{"name":"own_ballot_wins","in":"query","required":false,"description":"A delegator who also votes: yes (Keeps their own vote), no (Their delegation stands). Optional; unset clears it.","schema":{"type":"string","enum":["yes","no","unset"]}},{"name":"cast_votes","in":"query","required":false,"description":"Casting a ballot: only_as_instructed (Only as the person instructed, on that question). Default only_as_instructed.","schema":{"type":"string","enum":["only_as_instructed"]}},{"name":"initiate_votes","in":"query","required":false,"description":"Starting a vote: draft_only (Draft the spec for the person to start), send_approved (Open votes the person approved, with their tools), never (Never). Default draft_only.","schema":{"type":"string","enum":["draft_only","send_approved","never"]}},{"name":"invite_agents","in":"query","required":false,"description":"Inviting voters: draft_only (Draft the invitation for the person to send), send_approved (Send invitations the person approved, from accounts they gave), never (Never). Default draft_only.","schema":{"type":"string","enum":["draft_only","send_approved","never"]}},{"name":"public_elections","in":"query","required":false,"description":"Public or government elections: never (Never: no ballots, no counts, no advice). Default never.","schema":{"type":"string","enum":["never"]}},{"name":"format","in":"query","required":false,"description":"section (default): the settings sections only; skill: the whole skill file too.","schema":{"type":"string","enum":["section","skill"]}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"buildSettings","summary":"Write your settings into the skill","description":"Turns a preset and settings into the sections written at the top of VOTING.md. Every setting is a number or a fixed choice; the catalog is at https://www.voting.md/api/v1/settings. Returns the sections as Markdown, the settings as JSON, a link to the skill with them written in and a one-line install. Out-of-range numbers are clamped with a note. Nothing is stored. Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["core","team_decision","council","weighted_holders"],"description":"Starting point: core, team_decision, council, weighted_holders. Applied first; each setting overrides it."},"eligibility":{"type":"string","enum":["list_only","invited","open"],"description":"Who may vote: list_only (Only voters on the list the person gave), invited (Anyone the person invited), open (Anyone who sends a ballot). Default list_only."},"duplicate_rule":{"type":"string","enum":["last","first","reject"],"description":"A second ballot from the same voter: last (The latest one counts), first (The first one counts), reject (None of them count). Default last."},"late_ballots":{"type":"string","enum":["reject","flag","unset"],"description":"Ballots outside the window: reject (Don't count them), flag (Count them, flagged). Optional; unset clears it."},"identity":{"type":"string","enum":["as_given"],"description":"Voter identity: as_given (As the person's own system gives it; never verified by the agent). Default as_given."},"method":{"type":"string","enum":["plurality","approval","ranked_choice","borda","condorcet","score"],"description":"Counting method: plurality (Plurality: one choice, most votes wins), approval (Approval: approve any number), ranked_choice (Ranked choice (instant runoff)), borda (Borda count (points by rank)), condorcet (Condorcet (beats every other head to head)), score (Score (points per option)). Default plurality."},"quorum_share":{"type":"number","minimum":0,"maximum":1,"description":"Quorum: share of eligible voters who must take part (share (0-1)). Optional; unset clears it. Out-of-range values are clamped."},"threshold_share":{"type":"number","minimum":0,"maximum":1,"description":"Threshold: share the winner or yes must reach (share (0.5001 = strict majority)). Optional; unset clears it. Out-of-range values are clamped."},"threshold_base":{"type":"string","enum":["cast","eligible","unset"],"description":"Threshold measured against: cast (Votes cast), eligible (All eligible voters). Optional; unset clears it."},"tie_rule":{"type":"string","enum":["stop","runoff","status_quo"],"description":"A tie: stop (Stop; a person decides), runoff (Runoff among the tied options), status_quo (No option wins; the current state stands). Default stop."},"window_hours":{"type":"number","minimum":0.25,"maximum":720,"description":"A vote stays open for (hours). Optional; unset clears it. Out-of-range values are clamped."},"reminder_hours_before":{"type":"number","minimum":0,"maximum":168,"description":"Remind voters this long before closing (hours (0 = never)). Optional; unset clears it. Out-of-range values are clamped."},"report_results":{"type":"string","enum":["person_first","all_voters"],"description":"After closing, report the tally: person_first (To the person first; they decide who else sees it), all_voters (To the person and every voter). Default person_first."},"delegation":{"type":"string","enum":["never","allowed"],"description":"Voters may delegate their vote: never (Never), allowed (Allowed, to another eligible voter). Default never."},"max_delegation_depth":{"type":"integer","minimum":1,"maximum":10,"description":"Longest delegation chain honored (steps). Optional; unset clears it. Out-of-range values are clamped."},"own_ballot_wins":{"type":"string","enum":["yes","no","unset"],"description":"A delegator who also votes: yes (Keeps their own vote), no (Their delegation stands). Optional; unset clears it."},"cast_votes":{"type":"string","enum":["only_as_instructed"],"description":"Casting a ballot: only_as_instructed (Only as the person instructed, on that question). Default only_as_instructed."},"initiate_votes":{"type":"string","enum":["draft_only","send_approved","never"],"description":"Starting a vote: draft_only (Draft the spec for the person to start), send_approved (Open votes the person approved, with their tools), never (Never). Default draft_only."},"invite_agents":{"type":"string","enum":["draft_only","send_approved","never"],"description":"Inviting voters: draft_only (Draft the invitation for the person to send), send_approved (Send invitations the person approved, from accounts they gave), never (Never). Default draft_only."},"public_elections":{"type":"string","enum":["never"],"description":"Public or government elections: never (Never: no ballots, no counts, no advice). Default never."},"format":{"type":"string","enum":["section","skill"],"description":"section (default): the settings sections only; skill: the whole skill file too."}}},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"preset":"team_decision"}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/whats_new":{"get":{"operationId":"whatsNewGet","summary":"What's new here, and what's next","description":"What changed on voting.md and when, what is being built, when to check back, and the other .md sites. Pass since (a date) to get only newer entries, for example the updated date of the skill you have. Reads a list kept with the code; fetches nothing and stores nothing.","parameters":[{"name":"since","in":"query","required":false,"description":"Only entries after this date (YYYY-MM-DD).","schema":{"type":"string"}},{"name":"planned","in":"query","required":false,"description":"Include what is being built and the ideas being weighed. Default true.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"whatsNew","summary":"What's new here, and what's next","description":"What changed on voting.md and when, what is being built, when to check back, and the other .md sites. Pass since (a date) to get only newer entries, for example the updated date of the skill you have. Reads a list kept with the code; fetches nothing and stores nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string","maxLength":10,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Only entries after this date (YYYY-MM-DD)."},"planned":{"type":"boolean","default":true,"description":"Include what is being built and the ideas being weighed. Default true."}}},"examples":{"illustrative":{"summary":"Round illustrative numbers, not market data, a price or a quote; send your own.","value":{"since":"2026-10-01"}}}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}}},"components":{"schemas":{"Result":{"type":"object","additionalProperties":true,"properties":{"tool":{"type":"string"},"summary":{"type":"string"},"disclaimer":{"type":"string"},"terms":{"type":"string"}},"required":["disclaimer","terms"]},"Problem":{"type":"object","properties":{"error":{"type":"string"},"hint":{"type":"string"},"docs":{"type":"string"},"disclaimer":{"type":"string"},"terms":{"type":"string"}},"required":["error","disclaimer","terms"]}}}}