The governance routes run a holder vote on a token and the execution that follows. They sit under /. A resolution (mode: "binary") asks holders to approve or reject one decision, a multi-option vote (mode: "multi) asks them to choose between named options, and a poll records signed ballots off the ledger. Only a resolution can carry token changes. The token needs the voting-power feature attached before it can carry a vote. Governance votes in the Console drives the same routes from screens.
Routes
Creating, casting, queueing, executing and cancelling a vote each send a transaction. Each returns the settled result, or an accepted answer to follow while the transaction is still queued, like the other writes on the idempotency and async settlement contract. From a signed-in session each also needs a walletVerification block. A request sent with an API key needs none, because creating the key took one, as API keys describes. The governor checks the governance role on the token, so creating or cancelling a vote needs that role. Queueing and executing a vote need no role. A create that breaks the rules below, or a step the vote's current state does not allow, is refused with 422 DALP-14259. A refused create names the rule it broke in data.reason: recordDateTooEarly, recordDateTooLate, votingPowerMissing, documentNotOwned, optionsInvalid, votingPeriodOutOfRange, executionDelayOutOfRange, quorumOutOfRange, approval, treasuryIsToken or metadataKeyLocked. A refusal of a later step carries no reason. metadataKeyLocked means a setMetadata entry sets a key the token has locked, a key the token's template keeps off chain, or a key an earlier entry in the same vote locks. POST /preflights lists each such entry in metadataKeyLocks, by actionIndex and entryIndex, before you create the vote.
Create a vote
POST /api/ takes the tokenAddress, the mode, a title, a descriptionRichText, the recordDateAt, and quorumBps. It also takes an optional approvalThresholdBps, votingPeriodSeconds, and executionDelaySeconds, the options of a multi-option vote, the actions of a resolution that carries token changes, and documents. A document's objectKey must come from an upload grant issued to you. Quorum and threshold are in basis points. The platform refuses a record date less than 1 day or more than 90 days ahead, and a voting period or execution delay outside 1 to 30 days. It also refuses a multi-option vote whose options repeat a label, compared without case and surrounding spaces, with portfolio. and a message that names both options. Without a value, the voting period is 7 days and the execution delay 2 days. The Console offers a fixed set of these lengths, which Create a vote lists.
curl -X POST "https://your-instance.example.com/api/v2/addons/governance/proposals" \
-H "X-Api-Key: sm_dalp_..." \
-H "Prefer: wait=30" \
-H "Content-Type: application/json" \
-d '{
"tokenAddress": "0x8a791620dd6260079bf849dc5567adc3f2fdc318",
"mode": "binary",
"title": "Approve the 2027 dividend policy",
"descriptionRichText": "Holders approve paying 40 percent of 2026 net profit as a dividend in 2027.",
"recordDateAt": "2026-11-23T00:00:00.000Z",
"quorumBps": 2000
}'A settled create answers 200 with the token's governor and timelock and the vote's proposalId, which the cast, queue, execute and cancel calls take:
{
"data": {
"transactionHash": "0x7d1e4b2a9c3f5e6d8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f",
"governorAddress": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
"timelockAddress": "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
"proposalId": "48219370651823409171526401837265940018273645501928374650192837465019283746"
},
"meta": {
"txHashes": ["0x7d1e4b2a9c3f5e6d8a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f"],
"transactionId": "0198f3c2-5a1b-7c4d-8e9f-0a1b2c3d4e5f"
},
"links": { "self": "/api/v2/addons/governance/proposals" }
}Without Prefer: wait the create answers 202 with transactionId, status: "queued" and statusUrl.
The first vote on a token also deploys the token's governor, the contract that counts its votes, and its timelock, the contract that holds a passed vote's actions for the execution delay and then executes them. The body of that first vote can carry quorumFloorBps, 500 by default, and approval, 0 by default. These floors are the lowest quorum and approval threshold that this vote and every later vote on the token can set.
The token's timelock executes a vote's actions. Create is refused with 409 DALP-9155, GOVERNANCE_, while the timelock lacks the governance role on the token's access manager. Grant that role to the timelock, then send the create again. A vote without actions needs no timelock role.
How a vote is counted
The weight of a ballot is the holder's voting power at the record date. Voting power counts only when the holder has activated it and has not delegated it away. GET /api/ returns voting power per holder as it stood at a past block.
- Quorum is
ceil(quorum. A basis point is a hundredth of a percent, soBps × total supply at the record date / 10000) quorumis 20 percent of the supply. It counts every ballot cast, abstentions included, and it is met at exactly that figure. The supply is the token's whole supply at the record date, not only the activated voting power.Bps: 2000 - Approval applies to a resolution. The
fortotal must exceed theagainsttotal. WhenapprovalThresholdBpsis set,formust also reachceil(approval. Abstentions are outside both terms, and the threshold can only tighten the simple majority.Threshold Bps × (for + against) / 10000) - A multi-option vote succeeds on quorum alone. The winning option is read from the tallies, and a tie reports no winner.
Cast, queue, and execute
POST /api/ takes the tokenAddress, the governorAddress, the proposalId, and either support (for, against, or abstain) or optionIndex for a multi-option vote, never both. An optional reason travels with the ballot. The vote must be open, and the wallet must hold voting power at the record date. A ballot is final once cast.
GET .../ lists each ballot with its voter, weight, reason, and castAt. On a resolution, support is for, against, or abstain, and optionIndex and optionLabel are null. On a multi-option vote, support is option, optionIndex is the chosen option's position counted from zero, and optionLabel is that option's text. GET .../ returns the same ballots as CSV, with an optionLabel column after castAt. The lines above the ballots give a resolution's forVotes, againstVotes, and abstainVotes totals, or one optionVotes line per option of a multi-option vote: its position, its text, and its votes.
When the vote has succeeded, POST /queue- queues it on the timelock, which starts the execution delay. After the delay, POST /executions applies everything the vote holds in one transaction. POST /cancellations cancels a vote while it is pending or queued. Any current holder of the token's governance role can cancel, not only the person who created the vote, so the role can stop a vote the holders passed before it executes. All three take the tokenAddress, the governorAddress, and the proposalId. Read the vote before each step to see its status.
Polls
POST /api/ takes the tokenAddress, a title, an optional description, the options, and the recordDateAt, opensAt, and closesAt times. The record date must come before opensAt, and opensAt before closesAt. Each option must differ from the others in the same way as a multi-option vote's, or the create fails with portfolio.. Creating, closing and exporting a poll need the governance role on the token. A poll ballot names the voter, the optionIndex, and the poll's definitionHash, and carries the voter's signature. The platform refuses a ballot whose hash differs from the poll's definition, whose voter is not one of the caller's wallets, or whose signature does not verify as the voter's. It also refuses a voter with no voting power at the record date. GET /polls/ returns callerWalletVotes, each of the caller's wallets that held voting power at the record date with that power, largest first, so a client can tell before signing whether the caller can vote: an empty list means none of their wallets can. A poll never reaches the queue and execute routes.
Next steps
- Governance votes in the Console for the screens, the statuses, and the rules a vote follows.
- Platform API error reference for the refusal codes.
- Idempotency and async settlement for the header contract every write shares.