github.com/decred/politeia@v1.4.0/politeiawww/api/www/v2/api.md (about) 1 # politeiawww API Specification 2 3 # v2 4 5 This document describes the v2 REST API provided by a `politeiawww` server. 6 The `politeiawww` server is the web server backend that interacts with clients 7 using a JSON REST API. 8 9 **Vote Routes** 10 11 - [`Start vote`](#start-vote) 12 - [`Start vote runoff`](#start-vote-runoff) 13 - [`Vote details`](#vote-details) 14 15 ### `Start vote` 16 17 THIS ROUTE HAS BEEN DEPRECATED. The pi/v1 routes should be used instead. 18 19 Start the voting period on the given proposal. 20 21 Signature is a signature of the hex encoded SHA256 digest of the JSON encoded 22 v2 Vote struct. 23 24 Differences between v1 and v2 StartVote: 25 * Signature has been updated to be a signature of the Vote hash. It was 26 previously a signature of just the proposal token. 27 * Vote has been updated. See the Vote comment below for more details. 28 29 Differences between v1 and v2 Vote: 30 * Added the "version" field that specifies the version of the proposal that is 31 being voted on. This was added so that the proposal version is explicitly 32 included in the StartVote signature. 33 * Added the "type" field that specifies the vote type. 34 35 Differences between v1 and v2 StartVoteReply: 36 * StartBlockHeight was changed from a string to a uint32. 37 * EndBlockHeight was changed from a string to a uint32. It was also renamed 38 from EndHeight to EndBlockHeight to be consistent with StartBlockHeight. 39 40 **Route:** `POST /v2/vote/start` 41 42 **Params:** 43 44 | Parameter | Type | Description | Required | 45 |-|-|-|-| 46 | publickey | string | Public key used to sign the vote | Yes | 47 | vote | [`Vote`](#vote) | Vote details | Yes | 48 | signature | string | Signature of the Vote digest | Yes | 49 50 **Results (StartVoteReply):** 51 52 | | Type | Description | 53 | - | - | - | 54 | startblockheight | number | Start block height of the vote | 55 | startblockhash | string | Start block hash of the vote | 56 | endblockheight | number | End block height of the vote | 57 | eligibletickets | []string | All ticket hashes that are eligible to vote | 58 59 On failure the call shall return `400 Bad Request` and one of the following 60 error codes: 61 - [`ErrorStatusInvalidCensorshipToken`](#ErrorStatusInvalidCensorshipToken) 62 - [`ErrorStatusProposalNotFound`](#ErrorStatusProposalNotFound) 63 - [`ErrorStatusInvalidPropVoteBits`](#ErrorStatusInvalidPropVoteBits) 64 - [`ErrorStatusInvalidVoteOptions`](#ErrorStatusInvalidVoteOptions) 65 - [`ErrorStatusInvalidPropVoteParams`](#ErrorStatusInvalidPropVoteParams) 66 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 67 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 68 - [`ErrorStatusInvalidProposalVersion`](#ErrorStatusInvalidProposalVersion) 69 - [`ErrorStatusWrongStatus`](#ErrorStatusWrongStatus) 70 - [`ErrorStatusWrongVoteStatus`](#ErrorStatusWrongVoteStatus) 71 - [`ErrorStatusInvalidVoteType`] (#ErrorStatusInvalidVoteType) 72 - [`ErrorStatusWrongProposalType`](#ErrorStatusWrongProposalType) 73 - [`ErrorStatusInvalidLinkBy`](#ErrorStatusInvalidLinkBy) 74 75 **Example** 76 77 Request: 78 79 ``` json 80 { 81 "publickey": "d64d80c36441255e41fc1e7b6cd30259ff9a2b1276c32c7de1b7a832dff7f2c6", 82 "vote": { 83 "token": "127ea26cf994dabc27e115da0eb90a5657590e2ccc4e7c23c7f80c6fe4afaa59", 84 "type": 1, 85 "mask": 3, 86 "duration": 2016, 87 "Options": [{ 88 "id": "no", 89 "description": "Don't approve proposal", 90 "bits": 1 91 },{ 92 "id": "yes", 93 "description": "Approve proposal", 94 "bits": 2 95 }] 96 }, 97 "signature": "5a40d699cdfe5ee31472ec252982e60265a345cd58e4a07b183cf06447b3942d06981e1bfaf8430195109d51428458449446fbfa1d7059aebedc4df769ddb300" 98 } 99 ``` 100 101 Reply: 102 103 ```json 104 { 105 "startblockheight": 282899, 106 "startblockhash":"00000000017236b62ff1ce136328e6fb4bcd171801a281ce0a662e63cbc4c4fa", 107 "endblockheight": 284915, 108 "eligibletickets":[ 109 "000011e329fe0359ea1d2070d927c93971232c1118502dddf0b7f1014bf38d97", 110 "0004b0f8b2883a2150749b2c8ba05652b02220e98895999fd96df790384888f9", 111 "00107166c5fc5c322ecda3748a1896f4a2de6672aae25014123d2cedc83e8f42", 112 "002272cf4788c3f726c30472f9c97d2ce66b997b5762ff4df6a05c4761272413" 113 ] 114 } 115 ``` 116 117 Note: eligibletickets is abbreviated for readability. 118 119 120 ### `Start vote runoff` 121 122 THIS ROUTE HAS BEEN DEPRECATED. The pi/v1 routes should be used instead. 123 124 Start the runoff voting process on all public, non-abandoned RFP submissions 125 for the provided RFP token. 126 127 `AuthorizeVotes` must contain a vote authorization for each RFP submission that 128 is participating in the runoff vote. Unlike standard votes, these vote 129 authorizations are not signed by the submission author. They are signed by the 130 admin starting the runoff vote. 131 132 StartVotes must contain a StartVote for each RFP submission that is 133 participating in the runoff vote. The runoff vote can only be started once the 134 RFP proposal itself has been approved by a vote and once the LinkBy submission 135 deadline has expired. Once the LinkBy deadline has expired, the runoff vote can 136 be started at any point by an admin. It is not required that RFP submission 137 authors authorize the start of the vote. 138 139 **Route:** `POST /v2/vote/startrunoff` 140 141 **Params:** 142 143 | Parameter | Type | Description | Required | 144 |-|-|-|-| 145 | token | string | RFP proposal censorship token | Yes | 146 | authorizevotes | [][`AuthorizeVote`](#authorize-vote) | Authorize votes for rfp submissions | Yes | 147 | startvotes | [][`StartVote`](#start-vote) | Start votes for rfp submissions | Yes | 148 149 **Results (StartVoteRunoffReply):** 150 151 | | Type | Description | 152 | - | - | - | 153 | startblockheight | number | Start block height of the vote | 154 | startblockhash | string | Start block hash of the vote | 155 | endblockheight | number | End block height of the vote | 156 | eligibletickets | []string | All ticket hashes that are eligible to vote | 157 158 On failure the call shall return `400 Bad Request` and one of the following 159 error codes: 160 - [`ErrorStatusInvalidRunoffVote`](#ErrorStatusInvalidRunoffVote) 161 - [`ErrorStatusInvalidCensorshipToken`](#ErrorStatusInvalidCensorshipToken) 162 - [`ErrorStatusProposalNotFound`](#ErrorStatusProposalNotFound) 163 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 164 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 165 - [`ErrorStatusWrongStatus`](#ErrorStatusWrongStatus) 166 - [`ErrorStatusWrongVoteStatus`](#ErrorStatusWrongVoteStatus) 167 - [`ErrorStatusInvalidAuthVoteAction`](#ErrorStatusInvalidAuthVoteAction) 168 - [`ErrorStatusInvalidPropVoteBits`](#ErrorStatusInvalidPropVoteBits) 169 - [`ErrorStatusInvalidVoteOptions`](#ErrorStatusInvalidVoteOptions) 170 - [`ErrorStatusInvalidPropVoteParams`](#ErrorStatusInvalidPropVoteParams) 171 - [`ErrorStatusInvalidProposalVersion`](#ErrorStatusInvalidProposalVersion) 172 - [`ErrorStatusInvalidVoteType`] (#ErrorStatusInvalidVoteType) 173 - [`ErrorStatusWrongProposalType`](#ErrorStatusWrongProposalType) 174 - [`ErrorStatusLinkByDeadlineNotMet`](#ErrorStatusLinkByDeadlineNotMet) 175 - [`ErrorStatusNoLinkedProposals`](#ErrorStatusNoLinkedProposals) 176 177 **Example** 178 179 Request: 180 181 ``` json 182 { 183 "token": "b1052a4e099aa3b58edb4ad174fee88bc2ef52eb5d052b97ca062f043233a23b", 184 "authorizevote": [ 185 { 186 "token": "6ec6c28c350013873e15a37c16ffcea90dd08043ed55c44194008e167527999a", 187 "action": "authorize", 188 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 189 "signature": "904439a08211c36c894cde928eaae1b75b5dc1e12dc0d9c62d38ba2cc8ea5df4f9ca6774634ef1a95594edfff25b0493b5054c652d93f9037e2edad6fc0ee30b" 190 }, 191 { 192 "token": "abb8f4e498227ee9c58765820cd6137a76bb261e8f8d34b4b44f49d4208e37a9", 193 "action": "authorize", 194 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 195 "signature": "a154563161efd5fedfbc13728af0cc61995ffb3984accb102bcecf2b56e48069e66e32285aea01f0333c46a4610e6fcb86c93bad063cf39567f31b664dcdd60d" 196 }, 197 { 198 "token": "cfd2a55ef902c7fe5dc35da66c578283f4aeebbd58917e771e4e567d84d28363", 199 "action": "authorize", 200 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 201 "signature": "99b7a544dd9c910fa48c653a9e8ff14aa9b083227baeebd81ef35288f388c575cd65870e0cf68d5c692c6c9e4d9063e7f425601b19ad507164b8cdf1031ed90f" 202 } 203 ], 204 "startvotes": [ 205 { 206 "vote": { 207 "token": "6ec6c28c350013873e15a37c16ffcea90dd08043ed55c44194008e167527999a", 208 "proposalversion": 1, 209 "type": 2, 210 "mask": 3, 211 "duration": 2, 212 "quorumpercentage": 1, 213 "passpercentage": 1, 214 "options": [ 215 { 216 "id": "yes", 217 "description": "Don't approve proposal", 218 "bits": 1 219 }, 220 { 221 "id": "no", 222 "description": "Approve proposal", 223 "bits": 2 224 } 225 ] 226 }, 227 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 228 "signature": "d5c909dfa755a777d8f8678e10d955faf5c53d00b1e21c744faadbf15328ff48550b76ff8f9136ecb40b6614ebfe7ca9ee8280c4b0141fd6399a37d0705f7a0d" 229 }, 230 { 231 "vote": { 232 "token": "abb8f4e498227ee9c58765820cd6137a76bb261e8f8d34b4b44f49d4208e37a9", 233 "proposalversion": 1, 234 "type": 2, 235 "mask": 3, 236 "duration": 2, 237 "quorumpercentage": 1, 238 "passpercentage": 1, 239 "options": [ 240 { 241 "id": "yes", 242 "description": "Don't approve proposal", 243 "bits": 1 244 }, 245 { 246 "id": "no", 247 "description": "Approve proposal", 248 "bits": 2 249 } 250 ] 251 }, 252 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 253 "signature": "08f9e9669f3d40b69046b162046c1485c8d0eb32fc1a815101ba7ab25d0feb543d1dcd9825ebea8bd593d935d176ba3099987cd96564810734b0c5a01cd97501" 254 }, 255 { 256 "vote": { 257 "token": "cfd2a55ef902c7fe5dc35da66c578283f4aeebbd58917e771e4e567d84d28363", 258 "proposalversion": 1, 259 "type": 2, 260 "mask": 3, 261 "duration": 2, 262 "quorumpercentage": 1, 263 "passpercentage": 1, 264 "options": [ 265 { 266 "id": "yes", 267 "description": "Don't approve proposal", 268 "bits": 1 269 }, 270 { 271 "id": "no", 272 "description": "Approve proposal", 273 "bits": 2 274 } 275 ] 276 }, 277 "publickey": "d8fa97b2ce42fb279938b9918b3bf5a7fb68ba6a3296159f237be27cda92435d", 278 "signature": "166b210404e0968e300f23961d6e5db6e253ac1b821501c3f8f6fbd7fbf07596e02c3be7114bc8387a7efc14a9a95c56b3dc0b0bea3609ecb6119ff32d60850b" 279 } 280 ] 281 } 282 283 ``` 284 285 Reply: 286 287 ```json 288 { 289 "startblockheight": 417842, 290 "startblockhash": "00000058ff98f9f4a859ab30e81fc66cb1dabefd6a597000dd252716514bd57f", 291 "endblockheight": 417860, 292 "eligibletickets": [ 293 "000011e329fe0359ea1d2070d927c93971232c1118502dddf0b7f1014bf38d97", 294 "0004b0f8b2883a2150749b2c8ba05652b02220e98895999fd96df790384888f9", 295 "00107166c5fc5c322ecda3748a1896f4a2de6672aae25014123d2cedc83e8f42", 296 "002272cf4788c3f726c30472f9c97d2ce66b997b5762ff4df6a05c4761272413" 297 ] 298 } 299 ``` 300 301 Note: eligibletickets is abbreviated for readability. 302 303 ### `Vote details` 304 305 THIS ROUTE HAS BEEN DEPRECATED. The pi/v1 routes should be used instead. 306 307 Vote details returns all of the relevant proposal vote information for the 308 given proposal token. This includes all of the vote parameters and voting 309 options. 310 311 The returned version specifies the start vote version that was used to initiate 312 the voting period for the given proposal. See the [`Start vote`](#start-vote) 313 documentation for more details on the differences between the start vote 314 versions. 315 316 The "vote" field is a base64 encoded JSON byte slice of the Vote and will need 317 to be decoded according to the returned version. See the 318 [`Start vote`](#start-vote) documentation for more details on the differences 319 between the Vote versions. 320 321 **Route:** `GET /v2/vote/{token}` 322 323 **Params:** None 324 325 **Results (VoteDetailsReply):** 326 327 | | Type | Description | 328 | - | - | - | 329 | version | number | Start vote version | 330 | vote | string | JSON encoded Vote | 331 | publickey | string | Key used for signature | 332 | signature | string | Start vote signature | 333 | startblockheight | number | Start block height of the vote | 334 | startblockhash | string | Start block hash of the vote | 335 | endblockheight | number | End block height of the vote | 336 | eligibletickets | []string | All ticket hashes that are eligible to vote | 337 338 On failure the call shall return `400 Bad Request` and one of the following 339 error codes: 340 - [`ErrorStatusProposalNotFound`](#ErrorStatusProposalNotFound) 341 - [`ErrorStatusWrongVoteStatus`](#ErrorStatusWrongVoteStatus) 342 343 **Example** 344 345 Reply: 346 347 ``` 348 { 349 "version": 2, 350 "vote": "{\"token\":\"9a9b823fc46c1f8cbda4c0b0956cd782c31165d22ff0ac268190e68e708477cf\",\"proposalversion\":1,\"type\":1,\"mask\":3,\"duration\":2016,\"quorumpercentage\":20,\"passpercentage\":60,\"options\":[{\"id\":\"no\",\"description\":\"Don't approve proposal\",\"bits\":1},{\"id\":\"yes\",\"description\":\"Approve proposal\",\"bits\":2}]}", 351 "publickey": "8139793b84ad5efc48f395bbc53cc4be101936bc72167cd10c649e1e09bf698b", 352 "signature": "994c893b6c26c17f900c06f01aa68cc8008af52fcaf0ab223aed810833dbafe6da08728d2a76ea48b45b3a75c48fb8ce89a3feb4a460ad6b6e741f248c4fff0c", 353 "startblockheight": 342692, 354 "startblockhash": "0000005e341105be45fb9a7fe24d5ca7879e07bfb1ed2f786ee5ebc220ac1959", 355 "endblockheight": 344724, 356 "eligibletickets":[ 357 "000011e329fe0359ea1d2070d927c93971232c1118502dddf0b7f1014bf38d97", 358 "0004b0f8b2883a2150749b2c8ba05652b02220e98895999fd96df790384888f9", 359 "00107166c5fc5c322ecda3748a1896f4a2de6672aae25014123d2cedc83e8f42", 360 "002272cf4788c3f726c30472f9c97d2ce66b997b5762ff4df6a05c4761272413" 361 ] 362 } 363 ``` 364 365 Note: eligibletickets is abbreviated for readability. 366 367 ### `Authorize vote actions` 368 | Action | Value | Description | 369 |-|-|-| 370 | Authorize | authorize | Authorize a proposal vote | 371 | Revoke | revoke | Revoke a previous authorization | 372 373 ### `Authorize vote` 374 | Parameter | Value | Description | 375 |-|-|-| 376 | token | string | Proposal token of vote that is being authorized | 377 | action | [`AuthVoteAction`](#authorize-vote-actions) | Authorize or revoke | 378 | publickey | string | Public key used for signature | 379 | signature | string | Signature of `token+version+action` | 380 381 ### `Vote types` 382 | Type | Value | Description | 383 |-|-|-| 384 | <a name="VoteTypeInvalid">VoteTypeInvalid</a>| 0 | An invalid vote type. This shall be considered a bug. | 385 | <a name="VoteTypeStandard">VoteTypeStandard</a>| 1 | A simple approve or reject proposal vote where the winner is the voting option that has met the specified pass and quorum requirements. | 386 | <a name="VoteTypeRunoff">VoteTypeRunoff</a>| 2 | A runoff vote that multiple proposals compete in. All proposals are voted on like normal, but there can only be one winner in a runoff vote. The winner is the proposal that meets the quorum requirement, meets the pass requirement, and that has the most net yes votes. The winning proposal is considered approved and all other proposals are considered rejected. If no proposals meet the quorum and pass requirements then all proposals are considered rejected. Note: in a runoff vote it is possible for a proposal to meet the quorum and pass requirements but still be rejected if it does not have the most net yes votes. | 387 388 ### `Vote option` 389 390 | Parameter | Type | Description | 391 | - | - | - | 392 | id | string | Single unique word that identifies this option, e.g. "yes" | 393 | description | string | Human readable description of this option | 394 | bits | number | Bits that make up this choice, e.g. 0x01 | 395 396 ### `Vote` 397 398 | Parameter | Type | Description | 399 | - | - | - | 400 | token | string | Censorship token | 401 | proposalversion | number | Proposal version being voted on | 402 | type | [`VoteT`](#vote-types) | Type of proposal vote | 403 | mask | number | Mask for valid vote bits | 404 | duration | number | Duration of the vote in blocks | 405 | quorumpercentage | number | Percent of eligible votes required for a quorum | 406 | pass percentage | number | Percent of total votes required for the proposal to considered approved | 407 | options | [][`VoteOption`](#vote-option) | Vote options | 408 409 ### `Start vote` 410 411 | Parameter | Type | Description | Required | 412 |-|-|-|-| 413 | publickey | string | Public key used to sign the vote | Yes | 414 | vote | [`Vote`](#vote) | Vote details | Yes | 415 | signature | string | Signature of the Vote digest | Yes |