github.com/decred/politeia@v1.4.0/politeiawww/api/cms/v1/api.md (about) 1 # cmswww API Specification 2 3 # v1 4 5 This document describes the REST API provided by a `politeiawww` server while in 6 `cmswww` mode. The `politeiawww` server is the web server backend and it 7 interacts with a JSON REST API. This document also describes websockets for 8 server side notifications. It does not render HTML. 9 10 ***Contractor Management Routes*** 11 - [cmswww API Specification](#cmswww-api-specification) 12 - [v1](#v1) 13 - [`Invite new user`](#invite-new-user) 14 - [`Register`](#register) 15 - [`New invoice`](#new-invoice) 16 - [`User invoices`](#user-invoices) 17 - [`Set invoice status`](#set-invoice-status) 18 - [`Invoices`](#invoices) 19 - [`Edit invoice`](#edit-invoice) 20 - [`Generate payouts`](#generate-payouts) 21 - [`Support/Oppose DCC`](#supportoppose-dcc) 22 - [`New DCC comment`](#new-dcc-comment) 23 - [`DCC comments`](#dcc-comments) 24 - [`Set DCC Status`](#set-dcc-status) 25 - [`User sub contractors`](#user-sub-contractors) 26 - [`CMS Users`](#cms-users) 27 - [`Vote DCC`](#vote-dcc) 28 - [`Vote Details`](#vote-details) 29 - [`Active votes`](#active-votes) 30 - [`Start vote`](#start-vote) 31 - [`User code stats`](#user-code-stats) 32 - [Error codes](#error-codes) 33 - [Invoice status codes](#invoice-status-codes) 34 - [Line item type codes](#line-item-type-codes) 35 - [Domain type codes](#domain-type-codes) 36 - [Contractor type codes](#contractor-type-codes) 37 - [Payment status codes](#payment-status-codes) 38 - [DCC type codes](#dcc-type-codes) 39 - [DCC status codes](#dcc-status-codes) 40 - [`Abridged CMS User`](#abridged-cms-user) 41 - [`Proposal billing info`](#proposal-billing) 42 43 **Invoice status codes** 44 45 - [`InvoiceStatusInvalid`](#InvoiceStatusInvalid) 46 - [`InvoiceStatusNotFound`](#InvoiceStatusNotFound) 47 - [`InvoiceStatusNew`](#InvoiceStatusNew) 48 - [`InvoiceStatusUpdated`](#InvoiceStatusUpdated) 49 - [`InvoiceStatusDisputed`](#InvoiceStatusDisputed) 50 - [`InvoiceStatusRejected`](#InvoiceStatusRejected) 51 - [`InvoiceStatusApproved`](#InvoiceStatusApproved) 52 - [`InvoiceStatusPaid`](#InvoiceStatusPaid) 53 54 **Line item type codes** 55 56 - [`LineItemTypeLabor`](#LineItemTypeLabor) 57 - [`LineItemTypeExpense`](#LineItemTypeExpense) 58 - [`LineItemTypeMisc`](#LineItemTypeMisc) 59 60 ### `Invite new user` 61 62 Create a new user on the cmswww server with a registration token and email 63 an invitation to them to register. 64 65 Note: This call requires admin privileges. 66 67 **Route:** `POST v1/user/invite` 68 69 **Params:** 70 71 | Parameter | Type | Description | Required | 72 |-|-|-|-| 73 | email | string | Email is used as the web site user identity for a user. | Yes | 74 75 **Results:** 76 77 | Parameter | Type | Description | 78 |-|-|-| 79 | verificationtoken | String | The verification token which is required when calling [`Register`](#register). If an email server is set up, this property will be empty or nonexistent; the token will be sent to the email address sent in the request.| 80 81 This call can return one of the following error codes: 82 83 - [`ErrorStatusUserAlreadyExists`](#ErrorStatusUserAlreadyExists) 84 - [`ErrorStatusVerificationTokenUnexpired`](#ErrorStatusVerificationTokenUnexpired) 85 86 * **Example** 87 88 Request: 89 90 ```json 91 { 92 "email": "69af376cca42cd9c@example.com" 93 } 94 ``` 95 96 Reply: 97 98 ```json 99 { 100 "verificationtoken": "fc8f660e7f4d590e27e6b11639ceeaaec2ce9bc6b0303344555ac023ab8ee55f" 101 } 102 ``` 103 104 ### `Register` 105 106 Verifies email address of a user account invited via 107 [`Invite new user`](#invite-new-user) and supply details for new user registration. 108 109 **Route:** `POST v1/register` 110 111 **Params:** 112 113 | Parameter | Type | Description | Required | 114 |-|-|-|-| 115 | email | string | Email address of the user. | Yes | 116 | verificationtoken | string | The token that was provided by email to the user. | Yes | 117 | publickey | string | The user's ed25519 public key. | Yes | 118 | username | string | A unique username for the user. | Yes | 119 | password | string | A password for the user. | Yes | 120 121 **Results:** none 122 123 This call can return one of the following error codes: 124 125 - [`ErrorStatusVerificationTokenInvalid`](#ErrorStatusVerificationTokenInvalid) 126 - [`ErrorStatusVerificationTokenExpired`](#ErrorStatusVerificationTokenExpired) 127 - [`ErrorStatusInvalidPublicKey`](#ErrorStatusInvalidPublicKey) 128 - [`ErrorStatusMalformedUsername`](#ErrorStatusMalformedUsername) 129 - [`ErrorStatusDuplicateUsername`](#ErrorStatusDuplicateUsername) 130 - [`ErrorStatusMalformedPassword`](#ErrorStatusMalformedPassword) 131 - [`ErrorStatusDuplicatePublicKey`](#ErrorStatusDuplicatePublicKey) 132 133 **Example:** 134 135 Request: 136 137 ```json 138 { 139 "email": "69af376cca42cd9c@example.com", 140 "verificationtoken": "fc8f660e7f4d590e27e6b11639ceeaaec2ce9bc6b0303344555ac023ab8ee55f", 141 "publickey": "5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 142 "username": "foobar", 143 "password": "69af376cca42cd9c", 144 } 145 ``` 146 147 Reply: 148 149 ```json 150 {} 151 ``` 152 153 ### `New invoice` 154 155 Submit a new invoice for the given month and year. 156 157 **Route:** `POST /v1/invoices/new` 158 159 **Params:** 160 161 | Parameter | Type | Description | Required | 162 |-|-|-|-| 163 | month | int16 | A specific month, from 1 to 12. | Yes | 164 | year | int16 | A specific year. | Yes | 165 | files | [`[]File`](#file) | The invoice json file and any other attachments for line items. | Yes | 166 | publickey | string | The user's public key. | Yes | 167 | signature | string | The signature of the string representation of the file payload. | Yes | 168 169 **Results:** 170 171 | Parameter | Type | Description | 172 |-|-|-| 173 | censorshiprecord | [CensorshipRecord](#censorship-record) | A censorship record that provides the submitter with a method to extract the invoice and prove that he/she submitted it. | 174 175 This call can return one of the following error codes: 176 177 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 178 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 179 - [`ErrorStatusNoPublicKey`](#ErrorStatusNoPublicKey) 180 - [`ErrorStatusInvalidInput`](#ErrorStatusInvalidInput) 181 - [`ErrorStatusMalformedInvoiceFile`](#ErrorStatusMalformedInvoiceFile) 182 - [`ErrorStatusDuplicateInvoice`](#ErrorStatusDuplicateInvoice) 183 184 **Example** 185 186 Request: 187 188 ```json 189 { 190 "month": 12, 191 "year": 2018, 192 "files": [{ 193 "name":"invoice.json", 194 "mime": "text/plain; charset=utf-8", 195 "digest": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 196 "payload": "VGhpcyBpcyBhIGRlc2NyaXB0aW9u" 197 } 198 ] 199 } 200 ``` 201 202 Reply: 203 204 ```json 205 { 206 "censorshiprecord": { 207 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 208 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 209 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 210 } 211 } 212 ``` 213 214 ### `User invoices` 215 216 Returns a page of the user's invoices. 217 218 **Route:** `GET /v1/user/invoices` 219 220 **Params:** 221 222 | Parameter | Type | Description | Required | 223 |-|-|-|-| 224 225 **Results:** 226 227 | | Type | Description | 228 |-|-|-| 229 | invoices | array of [`Invoice`](#invoice)s | The page of invoices. | 230 231 **Example** 232 233 Request: 234 235 ```json 236 {} 237 ``` 238 239 Reply: 240 241 ```json 242 { 243 "invoices": [{ 244 "status": 4, 245 "month": 12, 246 "year": 2018, 247 "timestamp": 1508296860781, 248 "userid": "0", 249 "username": "foobar", 250 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 251 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e", 252 "version": "1", 253 "censorshiprecord": { 254 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 255 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 256 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 257 } 258 }] 259 } 260 ``` 261 262 ### `Set invoice status` 263 264 Sets the invoice status to either `InvoiceStatusApproved`, `InvoiceStatusRejected` or `InvoiceStatusDisputed`. 265 266 Note: This call requires admin privileges. 267 268 **Route:** `POST /v1/invoice/{token}/status` 269 270 **Params:** 271 272 | Parameter | Type | Description | Required | 273 |-|-|-|-| 274 | token | string | Token is the unique censorship token that identifies a specific invoice. | Yes | 275 | status | number | The new [status](#invoice-status-codes) for the invoice. | Yes | 276 | reason | string | The reason for the new status. This is only required if the status is `InvoiceStatusRejected`. | | 277 | signature | string | Signature of token+string(status). | Yes | 278 | publickey | string | The user's public key, sent for signature verification. | Yes | 279 280 **Results:** 281 282 | Parameter | Type | Description | 283 |-|-|-|-| 284 | invoice | [`Invoice`](#invoice) | The updated invoice. | 285 286 This call can return one of the following error codes: 287 288 - [`ErrorStatusInvoiceNotFound`](#ErrorStatusInvoiceNotFound) 289 290 **Example** 291 292 Request: 293 294 ```json 295 { 296 "invoicestatus": 4, 297 "publickey": "f5519b6fdee08be45d47d5dd794e81303688a8798012d8983ba3f15af70a747c", 298 "signature": "041a12e5df95ec132be27f0c716fd8f7fc23889d05f66a26ef64326bd5d4e8c2bfed660235856da219237d185fb38c6be99125d834c57030428c6b96a2576900", 299 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527" 300 } 301 ``` 302 303 Reply: 304 305 ```json 306 { 307 "invoice": { 308 "status": 4, 309 "month": 12, 310 "year": 2018, 311 "timestamp": 1508296860781, 312 "userid": "0", 313 "username": "foobar", 314 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 315 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e", 316 "version": "1", 317 "censorshiprecord": { 318 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 319 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 320 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 321 } 322 } 323 } 324 ``` 325 326 ### `Invoices` 327 328 This request allows administrators or invoice owners to have full view of any 329 of their past invoices. Users of the same domain may be able to see limited 330 information from the invoices. This will allow for inter-domain checks and 331 auditing of invoices. All private infomation will be hidden to non-admins or 332 invoice owners (rates, expenses, payouts, address, locations etc). This will be 333 merely used to audit hours billed. 334 335 There are a few optional parameters that are available to ease searching: 336 Month/Year will return all the invoices submitted for that month, Status 337 will return all invoices of that status. UserID will only return invoices that 338 are owned by that userid and start time/end time will return all invoices that 339 were submitted in that date range. Note: There is a max page size for date 340 range requests. 341 342 343 **Route:** `POST /v1/invoices` 344 345 **Params:** 346 347 | Parameter | Type | Description | Required | 348 |-|-|-|-| 349 | month | int16 | An optional filter that can be set (along with year) to return invoices from a given month, from 1 to 12. | No | 350 | year | int16 | An optional filter that can be set (along with month) to return invoices from a given year. | No | 351 | status | int64 | An optional filter for the list; this should be an [invoice status](#invoice-status-codes). | No | 352 | starttime | int64 | An optional filter that can be set with endtime for date range of submitted invoices. | No | 353 | endtime | int64 | An optional filter that can be set with starttime for date range of submitted invoices. | No | 354 | userid | int64 | An optional filter that can be set to return invoices that only match the provided userid. | No | 355 356 357 **Results:** 358 359 | | Type | Description | 360 |-|-|-| 361 | invoices | array of [`Invoice`](#invoice)s | The page of invoices. | 362 363 **Example** 364 365 Request: 366 367 ```json 368 { 369 "month": 12, 370 "year": 2018 371 } 372 ``` 373 374 Reply: 375 376 ```json 377 { 378 "invoices": [{ 379 "status": 4, 380 "month": 12, 381 "year": 2018, 382 "timestamp": 1508296860781, 383 "userid": "0", 384 "username": "foobar", 385 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 386 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e", 387 "version": "1", 388 "censorshiprecord": { 389 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 390 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 391 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 392 } 393 }] 394 } 395 ``` 396 397 ### `Edit invoice` 398 399 Edits an exisiting invoice and will update the status to `InvoiceStatusUpdated`. 400 401 Note: This call requires the user to be the same as the invoice creator. 402 403 **Route:** `POST /v1/invoices/edit` 404 405 **Params:** 406 407 | Parameter | Type | Description | Required | 408 |-|-|-|-| 409 | token | string | Token is the unique censorship token that identifies a specific invoice. | Yes | 410 | files | [`[]File`](#file) | The invoice CSV file and any other attachments for line items. The first line should be a comment with the month and year, with the format: `# 2006-01` | Yes | 411 | publickey | string | The user's public key. | Yes | 412 | signature | string | The signature of the string representation of the file payload. | Yes | 413 414 **Results:** 415 416 | Parameter | Type | Description | 417 |-|-|-| 418 | invoice | [`Invoice`](#invoice) | The updated invoice. | 419 420 This call can return one of the following error codes: 421 422 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 423 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 424 - [`ErrorStatusNoPublicKey`](#ErrorStatusNoPublicKey) 425 - [`ErrorStatusInvalidInput`](#ErrorStatusInvalidInput) 426 - [`ErrorStatusMalformedInvoiceFile`](#ErrorStatusMalformedInvoiceFile) 427 - [`ErrorStatusDuplicateInvoice`](#ErrorStatusDuplicateInvoice) 428 429 **Example** 430 431 Request: 432 433 ```json 434 { 435 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 436 "files": [{ 437 "name":"invoice.json", 438 "mime": "text/plain; charset=utf-8", 439 "digest": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 440 "payload": "VGhpcyBpcyBhIGRlc2NyaXB0aW9u" 441 } 442 ] 443 } 444 ``` 445 446 Reply: 447 448 ```json 449 { 450 "invoice": { 451 "status": 4, 452 "month": 12, 453 "year": 2018, 454 "timestamp": 1508296860781, 455 "userid": "0", 456 "username": "foobar", 457 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 458 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e", 459 "version": "1", 460 "censorshiprecord": { 461 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 462 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 463 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 464 } 465 } 466 } 467 ``` 468 469 ### `Generate payouts` 470 471 Generates a list of payout information for currently approved invoices. 472 473 Note: This call requires admin privileges. 474 475 **Route:** `POST /v1/admin/generatepayouts` 476 477 **Params:** 478 479 | Parameter | Type | Description | Required | 480 |-|-|-|-| 481 482 **Results:** 483 484 | | Type | Description | 485 |-|-|-| 486 | payouts | array of [`Payout`](#payout)s | The page of invoices. | 487 488 **Example** 489 490 Request: 491 492 ```json 493 {} 494 495 Reply: 496 497 ```json 498 { 499 "payouts": [ 500 { 501 "contractorname": "bill", 502 "username": "bill0012", 503 "month": 1, 504 "year": 2019, 505 "token": "123afed4609f21f4e3262420a875405440f42dcdaa98c163c6610fd9d6b7e855", 506 "address": "TsfDLrRkk9ciUuwfp2b8PawwnukYD7yAjGd", 507 "labortotal": 120000, 508 "expensetotal": 400 509 } 510 ] 511 } 512 ``` 513 514 ### `Invoice comments` 515 516 Retrieve all comments for given invoice. Note that the comments are not 517 sorted. 518 519 **Route:** `GET /v1/invoices/{token}/comments` 520 521 **Params:** 522 523 **Results:** 524 525 | | Type | Description | 526 | - | - | - | 527 | Comments | Comment | Unsorted array of all comments | 528 | AccessTime | int64 | UNIX timestamp of last access time. Omitted if no session cookie is present. | 529 530 **Comment:** 531 532 | | Type | Description | 533 | - | - | - | 534 | userid | string | Unique user identifier | 535 | username | string | Unique username | 536 | timestamp | int64 | UNIX time when comment was accepted | 537 | commentid | string | Unique comment identifier | 538 | parentid | string | Parent comment identifier | 539 | token | string | Censorship token | 540 | comment | string | Comment text | 541 | publickey | string | Public key from the client side, sent to politeiawww for verification | 542 | signature | string | Signature of Token, ParentID and Comment | 543 | receipt | string | Server signature of the client Signature | 544 | resultvotes | int64 | Vote score | 545 | upvotes | uint64 | Pro votes | 546 | downvotes | uint64 | Contra votes | 547 548 **Example** 549 550 Request: 551 552 The request params should be provided within the URL: 553 554 ``` 555 /v1/invoices/f1c2042d36c8603517cf24768b6475e18745943e4c6a20bc0001f52a2a6f9bde/comments 556 ``` 557 558 Reply: 559 560 ```json 561 { 562 "comments": [{ 563 "comment": "I dont like this invoice", 564 "commentid": "4", 565 "parentid": "0", 566 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 567 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 568 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 569 "timestamp": 1527277504, 570 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 571 "userid": "124", 572 "username": "admin", 573 "totalvotes": 0, 574 "resultvotes": 0 575 },{ 576 "comment":"but i did some good work!", 577 "commentid": "4", 578 "parentid": "0", 579 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 580 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 581 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 582 "timestamp": 1527277504, 583 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 584 "userid": "122", 585 "username": "steve", 586 "totalvotes": 0, 587 "resultvotes": 0 588 },{ 589 "comment":"you're right, approving", 590 "commentid": "4", 591 "parentid": "0", 592 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 593 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 594 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 595 "timestamp": 1527277504, 596 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 597 "userid": "124", 598 "username": "admin", 599 "totalvotes": 0, 600 "resultvotes": 0 601 }], 602 "accesstime": 1543539276 603 } 604 ``` 605 606 ### `Invoice exchange rate` 607 608 Retrieve the calculated monthly exchange rate for a given month/year 609 610 **Route:** `POST /v1/invoices/exchangerate` 611 612 **Params:** 613 614 | Parameter | Type | Description | Required | 615 |-|-|-|-| 616 | month | int16 | A specific month, from 1 to 12. | Yes | 617 | year | int16 | A specific year. | Yes | 618 619 **Results:** 620 621 | | Type | Description | 622 | - | - | - | 623 | ExchangeRate | float64 | The calculated monthly average exchange rate | 624 625 **Example** 626 627 Request: 628 629 ```json 630 { 631 "month": 12, 632 "year": 2018 633 } 634 ``` 635 636 Reply: 637 638 ```json 639 { 640 "exchangerate": "17.50659503883639" 641 } 642 ``` 643 644 ### `Pay invoices` 645 646 Temporary command that allows administrators to set all approved invoices to paid. 647 This command will be removed once the address watcher for approved invoices 648 is complete and properly functioning. 649 650 Note: This call requires admin privileges. 651 652 **Route:** `GET /v1/admin/payinvoices` 653 654 **Params:** 655 656 | Parameter | Type | Description | Required | 657 |-|-|-|-| 658 659 **Results:** 660 661 | | Type | Description | 662 |-|-|-| 663 664 **Example** 665 666 Request: 667 668 ```json 669 {} 670 ``` 671 672 Reply: 673 674 ```json 675 {} 676 ``` 677 678 ### `Invoice Payouts` 679 680 This command would provide a list of invoices that were paid out in a given 681 date range. 682 683 Note: This call requires admin privileges. 684 685 **Route:** `GET /v1/admin/invoicepayouts` 686 687 **Params:** 688 689 | Parameter | Type | Description | Required | 690 |-|-|-|-| 691 | starttime | int64 | Start time for the invoice range (in Unix seconds) | Yes | 692 | endtime | int64 | End time for the invoice range (in Unix seconds) | Yes | 693 694 **Results:** 695 696 | | Type | Description | 697 |-|-|-| 698 699 **Example** 700 701 Request: 702 703 ```json 704 { 705 "starttime": "1559460156", 706 "endtime": "1560460156" 707 } 708 ``` 709 710 Reply: 711 712 ```json 713 { 714 "invoices": [ 715 { 716 "status": 4, 717 "month": 12, 718 "year": 2018, 719 "timestamp": 1508296860781, 720 "userid": "0", 721 "username": "foobar", 722 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 723 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e", 724 "version": "1", 725 "censorshiprecord": { 726 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 727 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 728 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 729 }, 730 "lineitems": [ 731 { 732 "type": 1, 733 "domain": "Design", 734 "subdomain": "dcrweb", 735 "description": "Creating mock ups of the current site.", 736 "proposaltoken": "", 737 "labor": 7380, 738 "expenses": 0 739 } 740 ] 741 } 742 ] 743 } 744 ``` 745 746 ### `Edit user` 747 748 Allows a user to submit updates to their cms user information. 749 750 **Route:** `POST /v1/user/edit` 751 752 **Params:** 753 754 | Parameter | Type | Description | Required | 755 |-|-|-|-| 756 | githubname | string | The Github Name tied to the user. | no | 757 | matrixname | string | The Matrix Name tied to the user. | no | 758 | contractorname | string | The contractors IRL name/identity. | no | 759 | contractorlocation | string | Current general locaiton of the contractor. | no | 760 | contractorcontact | string | Email or contact information of the contractor. | no | 761 762 **Results:** 763 764 | | Type | Description | 765 |-|-|-| 766 767 **Example** 768 769 Request: 770 771 ```json 772 { 773 "githubname": "smobs", 774 "matrixname": "smobs:decred.org", 775 "contractorname": "Steve Mobs", 776 "contractorlocation": "Cupertino, CA", 777 "contractorcontact": "smobs@apple.com", 778 } 779 ``` 780 781 Reply: 782 783 ```json 784 {} 785 ``` 786 787 ### `Manage CMS user` 788 789 Edits a user's details. This call requires admin privileges. 790 791 **Route:** `POST /v1/admin/managecms` 792 793 **Params:** 794 795 | Parameter | Type | Description | Required | 796 |-|-|-|-| 797 | userid | string | UserID string of the user to be edited. | yes | 798 | domain | int | The Domain Type that the user currently has | no | 799 | contractortype | int | The contractor type of the user. | no | 800 | supervisoruserid | []string | The userid of the user (if the user is a sub contractor. ) | no | 801 | proposalsowned | []string | The tokens of any proposals that are "owned/managed" by this user. | no | 802 803 **Results:** 804 805 | | Type | Description | 806 |-|-|-| 807 808 **Example** 809 810 Request: 811 812 ```json 813 { 814 "domain": 1, 815 "contractortype": 1, 816 "supervisoruserid": "", 817 "proposalsowned":["337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527"] 818 } 819 ``` 820 821 Reply: 822 823 ```json 824 {} 825 ``` 826 827 ### `User details` 828 829 Returns a CMS user's information. If admin or a user requesting their own 830 information everything is returned. Otherwise, a shorter public user 831 information response is provided. 832 833 **Route:** `GET /v1/user/details` 834 835 **Params:** 836 837 | Parameter | Type | Description | Required | 838 |-|-|-|-| 839 840 **Results:** 841 842 | | Type | Description | 843 |-|-|-| 844 | user | instance of [`CMS User`](#cmsuser) | various user details | 845 846 **Example** 847 848 Request: 849 850 ```json 851 {} 852 ``` 853 854 Reply: 855 856 ```json 857 { 858 "user": { 859 "user": 860 { 861 "id": "0", 862 "email": "6b87b6ebb0c80cb7@example.com", 863 "username": "6b87b6ebb0c80cb7", 864 "isadmin": false, 865 "newuserpaywalladdress": "Tsgs7qb1Gnc43D9EY3xx9ou8Lbo8rB7me6M", 866 "newuserpaywallamount": 10000000, 867 "newuserpaywalltxnotbefore": 1528821554, 868 "newuserpaywalltx": "", 869 "newuserpaywallpollexpiry": 1528821554, 870 "newuserverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 871 "newuserverificationexpiry": 1528821554, 872 "updatekeyverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 873 "updatekeyverificationexpiry": 1528821554, 874 "numofproposals": 0, 875 "resetpasswordverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 876 "resetpasswordverificationexpiry": 1528821554, 877 "identities": [{ 878 "pubkey": "5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 879 "isactive": true 880 }], 881 }, 882 "comments": [], 883 "domain": 1, 884 "githubname": "smobs", 885 "matrixname": "smobs:decred.org", 886 "contractortype": 1, 887 "contractorname": "Steve Mobs", 888 "contractorlocation": "Cupertino, CA", 889 "contractorcontact": "smobs@apple.com", 890 "supervisoruserid": "", 891 } 892 } 893 ``` 894 895 ### `New DCC` 896 897 Creates a new Decred Contractor Clearance proposal. These may either be an 898 issuance or a revocation. In the case of an issuance, an existing user (sponsor) 899 nominates a yet-to-be-approved user to join the contractors. The sponsor also 900 includes a statement to support the nomination of the user. In the case of 901 a revocation, an existing user (sponsor) nominates another existing user to 902 have their access to the contractors' group rescinded and also includes a statement 903 to support that revocation. 904 905 In either case, issuance or revocation, other existing contractors will 906 be asked to offer their support or opposition to a DCC and based upon those 907 results, an administrator will approve or reject the DCC. 908 909 **Route:** `POST /v1/dcc/new` 910 911 **Params:** 912 913 | Parameter | Type | Description | Required | 914 |-|-|-|-| 915 | file | [`File`](#file) | The dcc json file. | Yes | 916 | publickey | string | The user's public key. | Yes | 917 | signature | string | The signature of the string representation of the file payload. | Yes | 918 919 **Results:** 920 921 | | Type | Description | 922 |-|-|-| 923 | censorshiprecord | [CensorshipRecord](#censorship-record) | A censorship record that provides the submitter with a method to extract the dcc and prove that he/she submitted it. | 924 925 **Example** 926 927 Request: 928 929 ```json 930 { 931 "file": 932 { 933 "name":"dcc.json", 934 "mime": "text/plain; charset=utf-8", 935 "digest": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 936 "payload": "VGhpcyBpcyBhIGRlc2NyaXB0aW9u" 937 }, 938 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 939 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e" 940 } 941 ``` 942 943 Reply: 944 945 ```json 946 { 947 "censorshiprecord": { 948 "token": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 949 "merkle": "0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 950 "signature": "fcc92e26b8f38b90c2887259d88ce614654f32ecd76ade1438a0def40d360e461d995c796f16a17108fad226793fd4f52ff013428eda3b39cd504ed5f1811d0d" 951 } 952 } 953 ``` 954 955 ### `DCC Details` 956 957 Retrieve DCC and its details. 958 959 **Routes:** `GET /v1/dcc/{token}` 960 961 **Params:** 962 963 | Parameter | Type | Description | Required | 964 |-|-|-|-| 965 | token | string | Token is the unique censorship token that identifies a specific DCC. | Yes | 966 967 **Results:** 968 969 | | Type | Description | 970 |-|-|-| 971 | dcc | [`DCC`](#dcc) | The DCC with the provided token. | 972 973 **Example** 974 975 Request: 976 977 The request params should be provided within the URL: 978 979 ``` 980 /v1/dcc/f1c2042d36c8603517cf24768b6475e18745943e4c6a20bc0001f52a2a6f9bde 981 ``` 982 983 Reply: 984 985 ```json 986 { 987 "dcc": { 988 "status": 4, 989 "statuschangereason": "This has been revoked due to strong support.", 990 "timestamp": 1565374601, 991 "dccpayload": { 992 "type": 2, 993 "nomineeuserid": "6638a1c9-271f-433e-bf2c-6144ddd8bed5", 994 "statement": "This is a statement to support the DCC to revoke this user.", 995 "domain": 2 996 }, 997 "file": [ 998 { 999 "name": "dcc.json", 1000 "mime": "text/plain; charset=utf-8", 1001 "digest": "cd5176184a510776abf1c394d830427f94d2f7fe4622e27ac839ceefa7fcf277", 1002 "payload": "eyJ0eXBlIjoyLCJub21pbmVldXNlcmlkIjoiNjYzOGExYzktMjcxZi00MzNlLWJmMmMtNjE0NGRkZDhiZWQ1Iiwic3RhdGVtZW50Ijoic2RhZnNkZmFzZmRzZGYiLCJkb21haW4iOjJ9" 1003 } 1004 ], 1005 "publickey": "311fa61d27b18c0033589ef1fb49edd162d791d0702cbab623ffd4486452322a", 1006 "signature": "8a3c5b5cb984cfb7fd59a11d2d7d11a8d50b936358541d917ba348d30bfb1d805c26686836695a9b4b347feee6a674b689b448ed941280874a4b8dbdf360600b", 1007 "version": "1", 1008 "sponsoruserid": "b35ab9d3-a98d-4170-ad5a-85b5bce9fb10", 1009 "sponsorusername": "bsaget", 1010 "supportuserids": [], 1011 "againstuserids": [ 1012 "a5c98ca0-7369-4147-8902-3d268ec2fb24" 1013 ], 1014 "censorshiprecord": { 1015 "token": "edd0882152f9800e7a6240f23d7310bd45145eb85ec463458de828b631083d84", 1016 "merkle": "cd5176184a510776abf1c394d830427f94d2f7fe4622e27ac839ceefa7fcf277", 1017 "signature": "4ea9f76a6c6659d4936aa556182604a3099778a981ebf500d5d47424b7ba0127ab033202b0be7872d09473088c04e9d1145f801455f0ae07be29e2f2d99ac00f" 1018 }, 1019 "publickey": "311fa61d27b18c0033589ef1fb49edd162d791d0702cbab623ffd4486452322a", 1020 "signature": "8a3c5b5cb984cfb7fd59a11d2d7d11a8d50b936358541d917ba348d30bfb1d805c26686836695a9b4b347feee6a674b689b448ed941280874a4b8dbdf360600b", 1021 "version": "1", 1022 "statement": "", 1023 "domain": 0, 1024 "sponsoruserid": "b35ab9d3-a98d-4170-ad5a-85b5bce9fb10", 1025 "sponsorusername": "bsaget", 1026 "supportuserids": [], 1027 "againstuserids": [ 1028 "a5c98ca0-7369-4147-8902-3d268ec2fb24" 1029 ], 1030 "censorshiprecord": { 1031 "token": "edd0882152f9800e7a6240f23d7310bd45145eb85ec463458de828b631083d84", 1032 "merkle": "cd5176184a510776abf1c394d830427f94d2f7fe4622e27ac839ceefa7fcf277", 1033 "signature": "4ea9f76a6c6659d4936aa556182604a3099778a981ebf500d5d47424b7ba0127ab033202b0be7872d09473088c04e9d1145f801455f0ae07be29e2f2d99ac00f" 1034 } 1035 } 1036 } 1037 ``` 1038 1039 ### `Get DCCs` 1040 1041 Retrieve DCCs by status. 1042 1043 **Routes:** `POST /v1/dcc` 1044 1045 **Params:** 1046 1047 | Parameter | Type | Description | Required | 1048 |-|-|-|-| 1049 | status | int | Returns all of the DCCs depending by the provided status. | Yes | 1050 1051 **Results:** 1052 1053 | | Type | Description | 1054 |-|-|-| 1055 | dccs | [`DCC`](#dcc) | The DCCs with the provided status. | 1056 1057 **Example** 1058 1059 Request: 1060 1061 ```json 1062 { 1063 "status":1, 1064 }, 1065 1066 Reply: 1067 1068 ```json 1069 { 1070 "dccs": [{ 1071 "dcc": { 1072 "type": 2, 1073 "status": 4, 1074 "statuschangereason": "This has been revoked due to strong support.", 1075 "timestamp": 1565374601, 1076 "dccpayload": { 1077 "type": 2, 1078 "nomineeuserid": "6638a1c9-271f-433e-bf2c-6144ddd8bed5", 1079 "statement": "This is a statement to support the DCC to revoke this user.", 1080 "domain": 2 1081 }, 1082 "file": [ 1083 { 1084 "name": "dcc.json", 1085 "mime": "text/plain; charset=utf-8", 1086 "digest": "cd5176184a510776abf1c394d830427f94d2f7fe4622e27ac839ceefa7fcf277", 1087 "payload": "eyJ0eXBlIjoyLCJub21pbmVldXNlcmlkIjoiNjYzOGExYzktMjcxZi00MzNlLWJmMmMtNjE0NGRkZDhiZWQ1Iiwic3RhdGVtZW50Ijoic2RhZnNkZmFzZmRzZGYiLCJkb21haW4iOjJ9" 1088 } 1089 ], 1090 "publickey": "311fa61d27b18c0033589ef1fb49edd162d791d0702cbab623ffd4486452322a", 1091 "signature": "8a3c5b5cb984cfb7fd59a11d2d7d11a8d50b936358541d917ba348d30bfb1d805c26686836695a9b4b347feee6a674b689b448ed941280874a4b8dbdf360600b", 1092 "version": "1", 1093 "statement": "", 1094 "domain": 0, 1095 "sponsoruserid": "b35ab9d3-a98d-4170-ad5a-85b5bce9fb10", 1096 "sponsorusername": "bsaget", 1097 "supportuserids": [], 1098 "againstuserids": [ 1099 "a5c98ca0-7369-4147-8902-3d268ec2fb24" 1100 ], 1101 "censorshiprecord": { 1102 "token": "edd0882152f9800e7a6240f23d7310bd45145eb85ec463458de828b631083d84", 1103 "merkle": "cd5176184a510776abf1c394d830427f94d2f7fe4622e27ac839ceefa7fcf277", 1104 "signature": "4ea9f76a6c6659d4936aa556182604a3099778a981ebf500d5d47424b7ba0127ab033202b0be7872d09473088c04e9d1145f801455f0ae07be29e2f2d99ac00f" 1105 } 1106 } 1107 }] 1108 } 1109 ``` 1110 1111 ### `Support Oppose DCC` 1112 1113 Creates a vote on a DCC Record that is used to tabulate support or opposition . 1114 1115 **Route:** `POST /v1/dcc/supportoppose` 1116 1117 **Params:** 1118 1119 | Parameter | Type | Description | Required | 1120 |-|-|-|-| 1121 | vote | string | The vote for the given DCC | Yes | 1122 | token | string | The token of the DCC to support | Yes | 1123 | publickey | string | The submitting user's public key | Yes | 1124 | signature | string | Signature of the Token+Vote by the submitting user | Yes | 1125 1126 **Results:** 1127 1128 | | Type | Description | 1129 |-|-|-| 1130 1131 **Example** 1132 1133 Request: 1134 1135 ```json 1136 { 1137 "vote": "aye", 1138 "token":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1139 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1140 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e" 1141 } 1142 ``` 1143 1144 Reply: 1145 1146 ```json 1147 {} 1148 ``` 1149 1150 ### `New DCC comment` 1151 1152 Submit comment on given DCC. ParentID value "0" means "comment on 1153 proposal"; if the value is not empty it means "reply to comment". 1154 1155 **Route:** `POST /v1/dcc/newcomment` 1156 1157 **Params:** 1158 1159 | Parameter | Type | Description | Required | 1160 | - | - | - | - | 1161 | token | string | Censorship token | Yes | 1162 | parentid | string | Parent comment identifier | Yes | 1163 | comment | string | Comment | Yes | 1164 | signature | string | Signature of Token, ParentID and Comment | Yes | 1165 | publickey | string | Public key from the client side, sent to politeiawww for verification | Yes | 1166 1167 **Results:** 1168 1169 | | Type | Description | 1170 | - | - | - | 1171 | token | string | Censorship token | 1172 | parentid | string | Parent comment identifier | 1173 | comment | string | Comment text | 1174 | signature | string | Signature of Token, ParentID and Comment | 1175 | publickey | string | Public key from the client side, sent to politeiawww for verification | 1176 | commentid | string | Unique comment identifier | 1177 | receipt | string | Server signature of the client Signature | 1178 | timestamp | int64 | UNIX time when comment was accepted | 1179 | resultvotes | int64 | Vote score | 1180 | censored | bool | Has the comment been censored | 1181 | userid | string | Unique user identifier | 1182 | username | string | Unique username | 1183 1184 On failure the call shall return `400 Bad Request` and one of the following 1185 error codes: 1186 1187 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 1188 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 1189 - [`ErrorStatusCommentLengthExceededPolicy`](#ErrorStatusCommentLengthExceededPolicy) 1190 - [`ErrorStatusInvalidCensorshipToken`](#ErrorStatusInvalidCensorshipToken) 1191 - [`ErrorStatusDCCNotFound`](#ErrorStatusDCCNotFound) 1192 - [`ErrorStatusCannotSupportOpposeCommentOnNonActiveDCC`](#ErrorStatusCannotSupportOpposeCommentOnNonActiveDCC) 1193 - [`ErrorStatusDuplicateComment`](#ErrorStatusDuplicateComment) 1194 1195 **Example** 1196 1197 Request: 1198 1199 ```json 1200 { 1201 "token":"abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 1202 "parentid":"0", 1203 "comment":"I dont like this dcc", 1204 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1205 "publickey":"4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7" 1206 } 1207 ``` 1208 1209 Reply: 1210 1211 ```json 1212 { 1213 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 1214 "parentid": "0", 1215 "comment": "I dont like this dcc", 1216 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1217 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 1218 "commentid": "4", 1219 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 1220 "timestamp": 1527277504, 1221 "resultvotes": 0, 1222 "censored": false, 1223 "userid": "124", 1224 "username": "john", 1225 } 1226 ``` 1227 1228 ### `DCC comments` 1229 1230 Retrieve all comments for given DCC. Note that the comments are not 1231 sorted. 1232 1233 **Route:** `GET /v1/dcc/{token}/comments` 1234 1235 **Params:** 1236 1237 **Results:** 1238 1239 | | Type | Description | 1240 | - | - | - | 1241 | Comments | Comment | Unsorted array of all comments | 1242 | AccessTime | int64 | UNIX timestamp of last access time. Omitted if no session cookie is present. | 1243 1244 **Comment:** 1245 1246 | | Type | Description | 1247 | - | - | - | 1248 | userid | string | Unique user identifier | 1249 | username | string | Unique username | 1250 | timestamp | int64 | UNIX time when comment was accepted | 1251 | commentid | string | Unique comment identifier | 1252 | parentid | string | Parent comment identifier | 1253 | token | string | Censorship token | 1254 | comment | string | Comment text | 1255 | publickey | string | Public key from the client side, sent to politeiawww for verification | 1256 | signature | string | Signature of Token, ParentID and Comment | 1257 | receipt | string | Server signature of the client Signature | 1258 | resultvotes | int64 | Vote score | 1259 1260 **Example** 1261 1262 Request: 1263 1264 The request params should be provided within the URL: 1265 1266 ``` 1267 /v1/dcc/f1c2042d36c8603517cf24768b6475e18745943e4c6a20bc0001f52a2a6f9bde/comments 1268 ``` 1269 1270 Reply: 1271 1272 ```json 1273 { 1274 "comments": [{ 1275 "comment": "I dont like this dcc", 1276 "commentid": "4", 1277 "parentid": "0", 1278 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 1279 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 1280 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1281 "timestamp": 1527277504, 1282 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 1283 "userid": "124", 1284 "username": "admin", 1285 "totalvotes": 0, 1286 "resultvotes": 0 1287 },{ 1288 "comment":"Yah this user stinks!", 1289 "commentid": "4", 1290 "parentid": "0", 1291 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 1292 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 1293 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1294 "timestamp": 1527277504, 1295 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 1296 "userid": "122", 1297 "username": "steve", 1298 "totalvotes": 0, 1299 "resultvotes": 0 1300 },{ 1301 "comment":"you're right, approving", 1302 "commentid": "4", 1303 "parentid": "0", 1304 "publickey": "4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7", 1305 "receipt": "96f3956ea3decb75ee129e6ee4e77c6c608f0b5c99ff41960a4e6078d8bb74e8ad9d2545c01fff2f8b7e0af38ee9de406aea8a0b897777d619e93d797bc1650a", 1306 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1307 "timestamp": 1527277504, 1308 "token": "abf0fd1fc1b8c1c9535685373dce6c54948b7eb018e17e3a8cea26a3c9b85684", 1309 "userid": "124", 1310 "username": "admin", 1311 "totalvotes": 0, 1312 "resultvotes": 0 1313 }], 1314 "accesstime": 1543539276 1315 } 1316 ``` 1317 1318 ### `Set DCC Status` 1319 1320 Updates the status of a given DCC proposal. 1321 1322 Note: This call requires admin privileges. 1323 1324 **Route:** `POST /v1/dcc/{token}/status` 1325 1326 **Params:** 1327 1328 | Parameter | Type | Description | Required | 1329 |-|-|-|-| 1330 | reason | string | The reason for approving the DCC. | No | 1331 | status | int | The status to which the DCC will be updated. | Yes | 1332 | token | string | The token of the DCC to approve. | Yes | 1333 | publickey | string | The user's public key. | Yes | 1334 | signature | string | The signature of the string representation of the token, status and reason payload. | Yes | 1335 1336 **Results:** 1337 1338 | | Type | Description | 1339 |-|-|-| 1340 1341 **Example** 1342 1343 Request: 1344 1345 ```json 1346 { 1347 "reason":"this dcc looks well supported!", 1348 "status": 2, 1349 "token":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1350 "publickey":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1351 "signature": "gdd92f26c8g38c90d2887259e88df614654g32fde76bef1438b0efg40e360f461e995d796g16b17108gbe226793ge4g52gg013428feb3c39de504fe5g1811e0e"} 1352 ``` 1353 1354 Reply: 1355 1356 ```json 1357 {} 1358 ``` 1359 1360 ### `User sub contractors` 1361 1362 Returns a list of the user's associated subcontractors 1363 1364 **Route:** `GET /v1/user/subcontractors` 1365 1366 **Params:** 1367 1368 | Parameter | Type | Description | Required | 1369 |-|-|-|-| 1370 1371 **Results:** 1372 1373 | | Type | Description | 1374 |-|-|-|-| 1375 | users | array of [`User`](#user)s | The list of subcontractors. | 1376 1377 **Example** 1378 1379 Request: 1380 1381 ```json 1382 {} 1383 ``` 1384 1385 Reply: 1386 1387 ```json 1388 { 1389 "users": [ 1390 { 1391 "user": 1392 { 1393 "id": "0", 1394 "email": "6b87b6ebb0c80cb7@example.com", 1395 "username": "subcontractor1", 1396 "isadmin": false, 1397 "newuserpaywalladdress": "Tsgs7qb1Gnc43D9EY3xx9ou8Lbo8rB7me6M", 1398 "newuserpaywallamount": 10000000, 1399 "newuserpaywalltxnotbefore": 1528821554, 1400 "newuserpaywalltx": "", 1401 "newuserpaywallpollexpiry": 1528821554, 1402 "newuserverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1403 "newuserverificationexpiry": 1528821554, 1404 "updatekeyverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1405 "updatekeyverificationexpiry": 1528821554, 1406 "numofproposals": 0, 1407 "resetpasswordverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1408 "resetpasswordverificationexpiry": 1528821554, 1409 "identities": [{ 1410 "pubkey": "5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1411 "isactive": true 1412 }], 1413 }, 1414 "domain": 1, 1415 "githubname": "smobs", 1416 "matrixname": "smobs:decred.org", 1417 "contractortype": 3, 1418 "contractorname": "Steve Mobs", 1419 "contractorlocation": "Cupertino, CA", 1420 "contractorcontact": "smobs@apple.com", 1421 "supervisoruserid": "4", 1422 }, 1423 { 1424 "user": 1425 { 1426 "id": "1", 1427 "email": "anotherexample@example.com", 1428 "username": "subcontractor2", 1429 "isadmin": false, 1430 "newuserpaywalladdress": "Tsgs7qb1Gnc43D9EY3xx9ou8Lbo8rB7me6M", 1431 "newuserpaywallamount": 10000000, 1432 "newuserpaywalltxnotbefore": 1528821554, 1433 "newuserpaywalltx": "", 1434 "newuserpaywallpollexpiry": 1528821554, 1435 "newuserverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1436 "newuserverificationexpiry": 1528821554, 1437 "updatekeyverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1438 "updatekeyverificationexpiry": 1528821554, 1439 "numofproposals": 0, 1440 "resetpasswordverificationtoken": "337fc4762dac6bbe11d3d0130f33a09978004b190e6ebbbde9312ac63f223527", 1441 "resetpasswordverificationexpiry": 1528821554, 1442 "identities": [{ 1443 "pubkey": "5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1444 "isactive": true 1445 }], 1446 }, 1447 "domain": 1, 1448 "githubname": "sdobs", 1449 "matrixname": "sdobs:decred.org", 1450 "contractortype": 3, 1451 "contractorname": "Steve Dobs", 1452 "contractorlocation": "Cupertino, CA", 1453 "contractorcontact": "sdobs@apple.com", 1454 "supervisoruserid": "4", 1455 }, 1456 ] 1457 } 1458 ``` 1459 1460 ### `CMS Users` 1461 1462 Returns a list of cms users given optional filters. 1463 1464 **Route:** `GET /v1/cmsusers` 1465 1466 **Params:** 1467 1468 | Parameter | Type | Description | Required | 1469 |-----------|------|-------------|----------| 1470 | domain | int | A query int to match against user's domain. | | 1471 | contractortype | int | A query string to match user's contractor type. | | 1472 1473 **Results:** 1474 1475 | Parameter | Type | Description | 1476 |-|-|-| 1477 | users | array of [Abridged CMS User](#abridged-cms-user) | The list of cms users that match the query. 1478 1479 On failure the call shall return `400 Bad Request` and one of the following 1480 error codes: 1481 - [`ErrorStatusInvalidInput`](#ErrorStatusInvalidInput) 1482 1483 **Example** 1484 1485 Request: 1486 1487 ```json 1488 { 1489 "domain": "1", 1490 "username": "1" 1491 } 1492 ``` 1493 1494 Reply: 1495 1496 ```json 1497 { 1498 "users": [] 1499 } 1500 ``` 1501 1502 ### `Proposal Owners` 1503 1504 Returns a list of cms users that are currently owning/mananging a given proposal. 1505 1506 **Route:** `GET /v1/proposals/owner` 1507 1508 **Params:** 1509 1510 | Parameter | Type | Description | Required | 1511 |-----------|------|-------------|----------| 1512 | proposaltoken | string | A censorship token from a proposal on Politeia. | yes | 1513 1514 **Results:** 1515 1516 | Parameter | Type | Description | 1517 |-|-|-| 1518 | users | array of [Abridged CMS User](#abridged-cms-user) | The list of cms users that own/manage the proposal given. 1519 1520 **Example** 1521 1522 Request: 1523 1524 ```json 1525 { 1526 "proposaltoken": "5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b" 1527 } 1528 ``` 1529 1530 Reply: 1531 1532 ```json 1533 { 1534 "users": [] 1535 } 1536 ``` 1537 1538 ### `Vote DCC` 1539 1540 Creates a vote on a DCC Record that is used for all contractor votes. 1541 1542 **Route:** `POST /v1/dcc/vote` 1543 1544 | Parameter | Type | Description | Required | 1545 |-|-|-|-| 1546 | vote | string | The vote for the given DCC | Yes | 1547 | token | string | The token of the DCC to support | Yes | 1548 | signature | string | Signature of Token and Vote | Yes | 1549 | publickey | string | Public key from the client side, sent to politeiawww for verification | Yes | 1550 1551 **Results:** 1552 1553 | | Type | Description | 1554 |-|-|-| 1555 1556 **Example** 1557 1558 Request: 1559 1560 ```json 1561 { 1562 "vote": "aye", 1563 "token":"5203ab0bb739f3fc267ad20c945b81bcb68ff22414510c000305f4f0afb90d1b", 1564 "signature":"af969d7f0f711e25cb411bdbbe3268bbf3004075cde8ebaee0fc9d988f24e45013cc2df6762dca5b3eb8abb077f76e0b016380a7eba2d46839b04c507d86290d", 1565 "publickey":"4206fa1f45c898f1dee487d7a7a82e0ed293858313b8b022a6a88f2bcae6cdd7" 1566 } 1567 ``` 1568 1569 Reply: 1570 1571 ```json 1572 {} 1573 ``` 1574 1575 ### `Active votes` 1576 1577 Retrieve all dcc active votes 1578 1579 Note that the webserver does not interpret the plugin structures. These are 1580 forwarded as-is to the politeia daemon. 1581 1582 **Route:** `POST /v1/dcc/activevotes` 1583 1584 **Params:** 1585 1586 **Results:** 1587 1588 | | Type | Description | 1589 | - | - | - | 1590 | votes | array of VoteTuple | All current active dcc votes | 1591 1592 **VoteTuple:** 1593 1594 | | Type | Description | 1595 | - | - | - | 1596 | dcc | ProposalRecord | DCC record | 1597 | startvote | Vote | Vote bits, mask etc | 1598 | starvotereply | StartVoteReply | Vote details (user weights, start block etc | 1599 1600 **Example** 1601 1602 Request: 1603 1604 ``` json 1605 {} 1606 ``` 1607 1608 Reply: 1609 1610 ```json 1611 { 1612 "votes": [{ 1613 "dcc": { 1614 "name":"This is a description", 1615 "status":4, 1616 "timestamp":1523902523, 1617 "userid":"", 1618 "publickey":"d64d80c36441255e41fc1e7b6cd30259ff9a2b1276c32c7de1b7a832dff7f2c6", 1619 "signature":"3554f74c112c5da49c6ee1787770c21fe1ae16f7f1205f105e6df1b5bdeaa2439fff6c477445e248e21bcf081c31bbaa96bfe03acace1629494e795e5d296e04", 1620 "files":[], 1621 "censorshiprecord": { 1622 "token":"8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225", 1623 "merkle":"0dd10219cd79342198085cbe6f737bd54efe119b24c84cbc053023ed6b7da4c8", 1624 "signature":"97b1bf0d63d7689a2c6e66e32358d48e98d84e5389f455cc135b3401277d3a37518827da0f2bc892b535937421418e7e8ba6a4f940dfcf19a219867fa8c3e005" 1625 } 1626 } 1627 }], 1628 "vote": { 1629 "token":"8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225", 1630 "mask":3, 1631 "duration":2016, 1632 "Options": [{ 1633 "id":"no", 1634 "description":"Don't approve dcc", 1635 "bits":1 1636 },{ 1637 "id":"yes", 1638 "description":"Approve dcc", 1639 "bits":2 1640 }] 1641 }, 1642 "votedetails": { 1643 "startblockheight":"282893", 1644 "startblockhash":"000000000227ff9b6bf3af53accb81e4fd1690ae44d521a665cb988bcd02ad94", 1645 "endheight":"284909", 1646 "userweights": [] 1647 } 1648 } 1649 ``` 1650 1651 ### `Vote details` 1652 1653 Vote details returns all of the relevant dcc vote information for the 1654 given dcc token. This includes all of the vote parameters and voting 1655 options. 1656 1657 The returned version specifies the start vote version that was used to initiate 1658 the voting period for the given dcc. See the [`Start vote`](#start-vote) 1659 documentation for more details on the differences between the start vote 1660 versions. 1661 1662 The "vote" field is a base64 encoded JSON byte slice of the Vote and will need 1663 to be decoded according to the returned version. See the 1664 [`Start vote`](#start-vote) documentation for more details on the differences 1665 between the Vote versions. 1666 1667 **Route:** `POST /dcc/votedetails` 1668 1669 **Params:** 1670 1671 | Parameter | Type | Description | Required | 1672 |-|-|-|-| 1673 | token | string | The token of the DCC to retreive details | Yes | 1674 1675 **Results (VoteDetailsReply):** 1676 1677 | | Type | Description | 1678 | - | - | - | 1679 | version | uint32 | Start vote version | 1680 | vote | string | JSON encoded Vote | 1681 | publickey | string | Key used for signature | 1682 | signature | string | Start vote signature | 1683 | startblockheight | uint32 | Start block height of the vote | 1684 | startblockhash | string | Start block hash of the vote | 1685 | endblockheight | uint32 | End block height of the vote | 1686 | userweights | []string | All userids + weights for eligible voters | 1687 1688 On failure the call shall return `400 Bad Request` and one of the following 1689 error codes: 1690 - [`ErrorStatusDCCNotFound`](#ErrorStatusDCCNotFound) 1691 - [`ErrorStatusWrongVoteStatus`](#ErrorStatusWrongVoteStatus) 1692 1693 **Example** 1694 1695 Reply: 1696 1697 ``` 1698 { 1699 "version": 2, 1700 "vote": "{}", 1701 "publickey": "8139793b84ad5efc48f395bbc53cc4be101936bc72167cd10c649e1e09bf698b", 1702 "signature": "994c893b6c26c17f900c06f01aa68cc8008af52fcaf0ab223aed810833dbafe6da08728d2a76ea48b45b3a75c48fb8ce89a3feb4a460ad6b6e741f248c4fff0c", 1703 "startblockheight": 342692, 1704 "startblockhash": "0000005e341105be45fb9a7fe24d5ca7879e07bfb1ed2f786ee5ebc220ac1959", 1705 "endblockheight": 344724, 1706 "userweights":[] 1707 } 1708 ``` 1709 ### `Start vote` 1710 1711 Start the voting period on the given dcc proposal that has been contentious. 1712 1713 Signature is a signature of the hex encoded SHA256 digest of the JSON encoded 1714 Vote struct. 1715 1716 **Route:** `POST /v1/dcc/startvote` 1717 1718 **Params:** 1719 1720 | Parameter | Type | Description | Required | 1721 |-|-|-|-| 1722 | publickey | string | Public key used to sign the vote | Yes | 1723 | vote | [`Vote`](#vote) | Vote details | Yes | 1724 | signature | string | Signature of the Vote digest | Yes | 1725 1726 **Results (StartVoteReply):** 1727 1728 | | Type | Description | 1729 | - | - | - | 1730 | startblockheight | number | Start block height of the vote | 1731 | startblockhash | string | Start block hash of the vote | 1732 | endblockheight | number | End block height of the vote | 1733 | userweights | []string | All user ids + "," + weight | 1734 1735 On failure the call shall return `400 Bad Request` and one of the following 1736 error codes: 1737 - [`ErrorStatusInvalidCensorshipToken`](#ErrorStatusInvalidCensorshipToken) 1738 - [`ErrorStatusDCCNotFound`](#ErrorStatusDCCNotFound) 1739 - [`ErrorStatusInvalidPropVoteBits`](#ErrorStatusInvalidPropVoteBits) 1740 - [`ErrorStatusInvalidVoteOptions`](#ErrorStatusInvalidVoteOptions) 1741 - [`ErrorStatusInvalidPropVoteParams`](#ErrorStatusInvalidPropVoteParams) 1742 - [`ErrorStatusInvalidSigningKey`](#ErrorStatusInvalidSigningKey) 1743 - [`ErrorStatusInvalidSignature`](#ErrorStatusInvalidSignature) 1744 - [`ErrorStatusWrongStatus`](#ErrorStatusWrongStatus) 1745 - [`ErrorStatusWrongVoteStatus`](#ErrorStatusWrongVoteStatus) 1746 - [`ErrorStatusInvalidVoteType`] (#ErrorStatusInvalidVoteType) 1747 1748 **Example** 1749 1750 Request: 1751 1752 ``` json 1753 { 1754 "publickey": "d64d80c36441255e41fc1e7b6cd30259ff9a2b1276c32c7de1b7a832dff7f2c6", 1755 "vote": { 1756 "token": "127ea26cf994dabc27e115da0eb90a5657590e2ccc4e7c23c7f80c6fe4afaa59", 1757 "type": 1, 1758 "mask": 3, 1759 "duration": 2016, 1760 "Options": [{ 1761 "id": "no", 1762 "description": "Don't approve dcc", 1763 "bits": 1 1764 },{ 1765 "id": "yes", 1766 "description": "Approve dcc", 1767 "bits": 2 1768 }] 1769 }, 1770 "signature": "5a40d699cdfe5ee31472ec252982e60265a345cd58e4a07b183cf06447b3942d06981e1bfaf8430195109d51428458449446fbfa1d7059aebedc4df769ddb300" 1771 } 1772 ``` 1773 1774 Reply: 1775 1776 ```json 1777 { 1778 "startblockheight": 282899, 1779 "startblockhash":"00000000017236b62ff1ce136328e6fb4bcd171801a281ce0a662e63cbc4c4fa", 1780 "endblockheight": 284915, 1781 "userweights":[] 1782 } 1783 ``` 1784 1785 ### `Proposal Billing Summary` 1786 1787 Retrieve all billing information for all approved proposals. 1788 1789 This retrieves the tokens for approved proposals and uses those tokens to 1790 search through the database for invoices that have line-items that have that 1791 as proposal token added. 1792 1793 There is also a basic pagination feature implemented with an offset and a 1794 page count of proposals to return. Note, there is a max proposal 1795 spending list page count. If above 20, then it will be set to that max. 1796 These are optional and if both unset, all proposal summaries will be returned. 1797 1798 Note: This call requires admin privileges. 1799 1800 **Route:** `GET /v1/proposals/spendingsummary` 1801 1802 | Parameter | Type | Description | Required | 1803 |-|-|-|-| 1804 | offset | int | Page offset | No | 1805 | count | int | Page count | No | 1806 1807 **Results:** 1808 1809 | | Type | Description | 1810 | - | - | - | 1811 | proposals | Array of ProposalSpending | Aggregated information of spending for all approved proposals. | 1812 1813 **ProposalSpending:** 1814 1815 | | Type | Description | 1816 | - | - | - | 1817 | token | string | Censorship record token of proposal. | 1818 | title | string | Title of approved proposal. | 1819 | totalbilled | int64 | Total billed against the proposal (in US Cents) | 1820 | invoices | Array of InvoiceRecord | All (partially filled) invoice records that have line items with the proposal token. | 1821 1822 **Example** 1823 1824 Request: 1825 ``` json 1826 {} 1827 ``` 1828 1829 Reply: 1830 1831 ```json 1832 { 1833 "proposals": [{ 1834 "token": "8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225", 1835 "title": "Super awesome proposal!", 1836 "totalbilled": 115000, 1837 "invoices": [ 1838 { 1839 "status": 0, 1840 "timestamp": 0, 1841 "userid": "5c36086c-fa22-4c53-aee1-adafc4446751", 1842 "username": "admin", 1843 "publickey": "c0876a34451431b77ee9cd2e65662d0829010e0285d9fe1cc1e3ea20005b88bf", 1844 "signature": "", 1845 "file": null, 1846 "version": "", 1847 "input": { 1848 "version": 0, 1849 "month": 5, 1850 "year": 2020, 1851 "exchangerate": 1411, 1852 "contractorname": "", 1853 "contractorlocation": "", 1854 "contractorcontact": "", 1855 "contractorrate": 5000, 1856 "paymentaddress": "", 1857 "lineitems": [ { 1858 "type": 1, 1859 "domain": "Development", 1860 "subdomain": "dvdddasf", 1861 "description": "sadfasdfsdf", 1862 "proposaltoken": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87", 1863 "subuserid": "", 1864 "subrate": 0, 1865 "labor": 1380, 1866 "expenses": 0 1867 } 1868 ] 1869 } 1870 } 1871 ] 1872 }] 1873 } 1874 } 1875 ``` 1876 1877 ### `Proposal Billing Details` 1878 1879 Retrieve all billing information for the given proposal token. 1880 1881 Note: This call requires admin privileges. 1882 1883 **Route:** `POST /v1/proposals/spendingdetails` 1884 1885 **Params:** 1886 1887 | Parameter | Type | Description | Required | 1888 |-|-|-|-| 1889 | token | string | Token for approved proposal. | Yes | 1890 1891 **Results:** 1892 1893 | | Type | Description | 1894 | - | - | - | 1895 | details | ProposalSpending | Aggregated information for the given proposal token. | 1896 1897 **ProposalSpending:** 1898 1899 | | Type | Description | 1900 | - | - | - | 1901 | token | string | Censorship record token of proposal. | 1902 | title | string | Title of approved proposal. | 1903 | totalbilled | int64 | Total billed against the proposal (in US Cents) | 1904 | invoices | Array of InvoiceRecord | All (partially filled) invoice records that have line items with the proposal token. | 1905 1906 **Example** 1907 1908 Request: 1909 1910 ``` json 1911 { 1912 "token": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87" 1913 } 1914 ``` 1915 1916 Reply: 1917 1918 ```json 1919 { 1920 "details": { 1921 "token": "8d14c77d9a28a1764832d0fcfb86b6af08f6b327347ab4af4803f9e6f7927225", 1922 "title": "Super awesome proposal!", 1923 "totalbilled": 115000, 1924 "invoices": [ 1925 { 1926 "status": 0, 1927 "timestamp": 0, 1928 "userid": "5c36086c-fa22-4c53-aee1-adafc4446751", 1929 "username": "admin", 1930 "publickey": "c0876a34451431b77ee9cd2e65662d0829010e0285d9fe1cc1e3ea20005b88bf", 1931 "signature": "", 1932 "file": null, 1933 "version": "", 1934 "input": { 1935 "version": 0, 1936 "month": 5, 1937 "year": 2020, 1938 "exchangerate": 1411, 1939 "contractorname": "", 1940 "contractorlocation": "", 1941 "contractorcontact": "", 1942 "contractorrate": 5000, 1943 "paymentaddress": "", 1944 "lineitems": [ { 1945 "type": 1, 1946 "domain": "Development", 1947 "subdomain": "dvdddasf", 1948 "description": "sadfasdfsdf", 1949 "proposaltoken": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87", 1950 "subuserid": "", 1951 "subrate": 0, 1952 "labor": 1380, 1953 "expenses": 0 1954 } 1955 ] 1956 } 1957 } 1958 ] 1959 } 1960 } 1961 ``` 1962 1963 ### `User code stats` 1964 1965 Returns all code stats based on provided userid and start/endtime. 1966 1967 This will return arrays of Repository Statistics for each month/year and 1968 repo that has been found for the range specified. If no range, it just returns 1969 last month's data. Repo stats include merge additions/deletions, review 1970 additions/deletions, and pull request and review links. 1971 1972 **Route:** `POST /user/codestats` 1973 1974 **Params:** 1975 1976 | Parameter | Type | Description | Required | 1977 |-|-|-|-| 1978 | userid | string | The userid to return code statistics for. | Yes | 1979 | starttime | int64 | The start of time range to return code stats. | No | 1980 | endtime | int64 | The end of time range to return code stats. | No | 1981 1982 **Results:** 1983 1984 | Parameter | Type | Description | 1985 |-|-|-| 1986 | repostats | []CodeStats | An array of repository details based on work performed. | 1987 1988 **Example** 1989 1990 Request: 1991 1992 ```json 1993 { 1994 "userid": "6638a1c9-271f-433e-bf2c-6144ddd8bed5", 1995 "starttime": "1559460156", 1996 "endtime": "1560460156" 1997 } 1998 ``` 1999 2000 Reply: 2001 2002 ```json 2003 { 2004 "repostats": [ 2005 { 2006 "repository": "politeia", 2007 "mergeadditions": "1500", 2008 "mergedeletions": "300", 2009 "reviewadditions": "300", 2010 "reviewdeletions": "234", 2011 "prs": [ 2012 "https://github.com/decred/politeia/pull/800" 2013 ], 2014 "reviews": [ 2015 "politeia/801" 2016 ] 2017 } 2018 ] 2019 } 2020 ``` 2021 2022 ### Error codes 2023 2024 | Status | Value | Description | 2025 |-|-|-| 2026 | <a name="ErrorStatusMalformedName">ErrorStatusMalformedName</a> | 1001 | Invalid name entered for CMS registration. | 2027 | <a name="ErrorStatusMalformedLocation">ErrorStatusMalformedLocation</a> | 1002 | Invalid location entered for CMS registration. | 2028 | <a name="ErrorStatusInvoiceNotFound">ErrorStatusInvoiceNotFound</a> | 1003 | Request invoice not found. | 2029 | <a name="ErrorStatusInvalidMonthYearRequest">ErrorStatusInvalidMonthYearRequest</a> | 1004 | Month and/or was improperly entered for an invoice. | 2030 | <a name="ErrorStatusMalformedInvoiceFile">ErrorStatusMalformedInvoiceFile</a> | 1005 | The invoice file submitted was malformed and not acceptable. | 2031 | <a name="ErrorStatusInvalidInvoiceStatusTransition">ErrorStatusInvalidInvoiceStatusTransition</a> | 1006 | Status update attempted an invalid status transition. | 2032 | <a name="ErrorStatusReasonNotProvided">ErrorStatusReasonNotProvided</a> | 1007 | No reason provided for status updated. | 2033 | <a name="ErrorStatusInvoiceDuplicate">ErrorStatusInvoiceDuplicate</a> | 1008 | Invoice is a duplicate. | 2034 | <a name="ErrorStatusInvalidPaymentAddress">ErrorStatusInvalidPaymentAddress</a> | 1009 | Invalid payment address was submitted. | 2035 | <a name="ErrorStatusMalformedLineItem">ErrorStatusMalformedLineItem</a> | 1010 | Line item in an invoice was malformed and invalid. | 2036 | <a name="ErrorStatusInvoiceMissingName">ErrorStatusInvoiceMissingName</a> | 1011 | Submitted invoice missing contractor name. | 2037 | <a name="ErrorStatusInvoiceMissingContact">ErrorStatusInvoiceMissingContact</a> | 1013 | Submitted invoice missing contractor contact. | 2038 | <a name="ErrorStatusInvoiceMissingRate">ErrorStatusInvoiceMissingRate</a> | 1014 | Submitted invoice missing contractor rate. | 2039 | <a name="ErrorStatusInvoiceInvalidRate">ErrorStatusInvoiceInvalidRate</a> | 1015 | Submitted contractor rate is invalid (either too high or low). | 2040 | <a name="ErrorStatusInvoiceMalformedContact">ErrorStatusInvoiceMalformedContact</a> | 1016 | Malformed contractor contact was entered. | 2041 | <a name="ErrorStatusMalformedProposalToken">ErrorStatusMalformedProposalToken</a> | 1017 | Malformed proposal token for a line item. | 2042 | <a name="ErrorStatusMalformedDomain">ErrorStatusMalformedDomain</a> | 1018 | Malformed domain for a line item. | 2043 | <a name="ErrorStatusMalformedSubdomain">ErrorStatusMalformedSubdomain</a> | 1019 | Malformed subdomain for a line item. | 2044 | <a name="ErrorStatusMalformedDescription">ErrorStatusMalformedDescription</a> | 1020 | Malformed description for a line item. | 2045 | <a name="ErrorStatusWrongInvoiceStatus">ErrorStatusWrongInvoiceStatus</a> | 1021 | Wrong status for an invoice to be editted (approved, rejected, paid). | 2046 | <a name="ErrorStatusInvoiceRequireLineItems">ErrorStatusInvoiceRequireLineItems</a> | 1022 | Invoices require at least 1 line item to be included. | 2047 | <a name="ErrorStatusInvalidInvoiceMonthYear">ErrorStatusInvalidInvoiceMonthYear</a> | 1024 | An invalid month/year was detected in an invoice. | 2048 | <a name="ErrorStatusInvalidExchangeRate">ErrorStatusInvalidExchangeRate</a> | 1025 | Invalid Exchange Rate | 2049 | <a name="ErrorStatusInvalidLineItemType">ErrorStatusInvalidLineItemType</a> | 1026 | An invalid line item type was attempted. | 2050 | <a name="ErrorStatusInvalidLaborExpense">ErrorStatusInvalidLaborExpense</a> | 1027 | An invalid value was entered into labor or expenses. | 2051 | <a name="ErrorStatusDuplicatePaymentAddress">ErrorStatusDuplicatePaymentAddress</a> | 1028 | An duplicate payment address was entered. | 2052 | <a name="ErrorStatusInvalidDatesRequested">ErrorStatusInvalidDatesRequested</a> | 1029 | Invalid dates were submitted for a request. | 2053 | <a name="ErrorStatusInvalidInvoiceEditMonthYear">ErrorStatusInvalidInvoiceEditMonthYear</a> | 1030 | Invoice month/year was attempted to be edited. | 2054 | <a name="ErrorStatusInvalidDCCType">ErrorStatusInvalidDCCType</a> | 1031 | An invalid DCC type was detected. | 2055 | <a name="ErrorStatusInvalidNominatingDomain">ErrorStatusInvalidNominatingDomain</a> | 1032 | An invalid nominating domain was detected. Domain must match sponsoring user's domain. | 2056 | <a name="ErrorStatusMalformedSponsorStatement">ErrorStatusMalformedSponsorStatement</a> | 1033 | The sponsor statement was malformed. | 2057 | <a name="ErrorStatusMalformedDCCFile">ErrorStatusMalformedDCCFile</a> | 1034 | The DCC files was malformed. | 2058 | <a name="ErrorStatusInvalidDCCComment">ErrorStatusInvalidDCCComment</a> | 1035 | A DCC comment was invalid. | 2059 | <a name="ErrorStatusInvalidDCCStatusTransition">ErrorStatusInvalidDCCStatusTransition</a> | 1036 | An invalid DCC status transition. | 2060 | <a name="ErrorStatusDuplicateEmail">ErrorStatusDuplicateEmail</a> | 1037 | A duplicate email address was detected. | 2061 | <a name="ErrorStatusInvalidUserNewInvoice">ErrorStatusInvalidUserNewInvoice</a> | 1038 | The user was not allowed to create a new invoice. | 2062 | <a name="ErrorStatusInvalidDCCNominee">ErrorStatusInvalidDCCNominee</a> | 1039 | The user that was nominated was invalid, either not found or not a potential nominee. | 2063 | <a name="ErrorStatusDCCNotFound">ErrorStatusDCCNotFound</a> | 1040 | A requested DCC proposal was not able to be located based on the provided token. | 2064 | <a name="ErrorStatusWrongDCCStatus">ErrorStatusWrongDCCStatus</a> | 1041 | A user is unable to support/oppose/comment on a DCC that is not active. | 2065 | <a name="ErrorStatusInvalidSupportOppose">ErrorStatusInvalidSupportOppose</a> | 1042 | An invalid "vote" for a support or oppose request. Must be "aye" or "nay". | 2066 | <a name="ErrorStatusDuplicateSupportOppose">ErrorStatusDuplicateSupportOppose</a> | 1043 | A user attempted to support or oppose a DCC multiple times. | 2067 | <a name="ErrorStatusUserIsAuthor">ErrorStatusUserIsAuthor</a> | 1044 | A user attempted to support or oppose a DCC that they authored. | 2068 | <a name="ErrorStatusInvalidUserDCC">ErrorStatusInvalidUserDCC</a> | 1045 | A user with an invalid status attempted to complete a DCC task. | 2069 | <a name="ErrorStatusInvalidDCCContractorType">ErrorStatusInvalidDCCContractorType</a> | 1046 | An invalid contractor type was attempted to be used in a DCC proposal. | 2070 | <a name="ErrorStatusInvalidTypeSubHoursLineItem">ErrorStatusInvalidTypeSubHoursLineItem</a> | 1047 | A non-supervisor user attempted to sumbit a `subcontractor` line item | 2071 | <a name="ErrorStatusMissingSubUserIDLineItem">ErrorStatusMissingSubUserIDLineItem</a> | 1048 | Subcontractor ID cannot be blank | 2072 | <a name="ErrorStatusInvalidSubUserIDLineItem">ErrorStatusInvalidSubUserIDLineItem</a> | 1049 | An invalid subcontractor ID was attempted to be used. | 2073 | <a name="ErrorStatusInvalidSupervisorUser">ErrorStatusInvalidSupervisorUser</a> | 1050 | An invalid Supervisor User ID was attempted to be used. | 2074 2075 ### Invoice status codes 2076 2077 | Status | Value | Description | 2078 |-|-|-| 2079 | <a name="InvoiceStatusInvalid">InvoiceStatusInvalid</a>| 0 | An invalid status. This shall be considered a bug. | 2080 | <a name="InvoiceStatusNotFound">InvoiceStatusNotFound</a> | 1 | The invoice was not found. | 2081 | <a name="InvoiceStatusNew">InvoiceStatusNew</a> | 2 | The invoice has not been reviewed by an admin. | 2082 | <a name="InvoiceStatusUpdated">InvoiceStatusUpdated</a> | 3 | The invoice has been changed and the changes have not been reviewed by an admin. | 2083 | <a name="InvoiceStatusDisputed">InvoiceStatusDisputed</a> | 4 | A portion of the invoice has been disputed and requires contractor resolution. | 2084 | <a name="InvoiceStatusRejected">InvoiceStatusRejected</a> | 5 | The invoice has been rejected by an admin. | 2085 | <a name="InvoiceStatusApproved">InvoiceStatusApproved</a> | 6 | The invoice has been approved by an admin. | 2086 | <a name="InvoiceStatusPaid">InvoiceStatusPaid</a> | 7 | The invoice has been paid. | 2087 2088 ### Line item type codes 2089 2090 | Type | Value | Description | 2091 |-|-|-| 2092 | <a name="LineItemTypeInvalid">LineItemTypeInvalid</a>| 0 | An invalid type. This shall be considered a bug. | 2093 | <a name="LineItemTypeLabor">LineItemTypeLabor</a>| 1 | Line items that correspond to laborious activities. | 2094 | <a name="LineItemTypeExpense">LineItemTypeExpense</a> | 2 | Line items that cover expensed costs. | 2095 | <a name="LineItemTypeMisc">LineItemTypeMisc</a> | 3 | Any line item that doesn't fall into the categories. | 2096 | <a name="LineItemTypeSubHours">LineItemTypeSubHours</a> | 4 | A line item for sub contractor hourly billing. | 2097 2098 ### Domain type codes 2099 | Type | Value | Description | 2100 |-|-|-| 2101 | <a name="DomainTypeInvalid">DomainTypeInvalid</a>| 0 | An invalid Domain type. This shall be considered a bug. | 2102 | <a name="DomainTypeDeveloper">DomainTypeDeveloper</a>| 1 | Development work, typically writing code or designing software architecture. | 2103 | <a name="DomainTypeMarketing">DomainTypeMarketing</a>| 2 | Marketing work, typically event planning, publication outreach or writing. | 2104 | <a name="DomainTypeDesign">DomainTypeDesign</a>| 4 | Design work, typically creating art, web design or sound production for the project. | 2105 | <a name="DomainTypeResearch">DomainTypeResearch</a>| 5 | Research work, typically looking deeper into various subjects closely related to the project. | 2106 2107 ### Contractor type codes 2108 | Type | Value | Description | 2109 |-|-|-| 2110 | <a name="ContractorTypeInvalid">ContractorTypeInvalid</a>| 0 | An invalid Contractor type. This shall be considered a bug. | 2111 | <a name="ContractorTypeDirect">ContractorTypeDirect</a>| 1 | A direct contractor that does not work under another organization. Able to submit invoices. | 2112 | <a name="ContractorTypeSupervisor">ContractorTypeSupervisor</a>| 2 | The supervising manager of a team of sub contractors. Able to submit invoices for themselves and subs. | 2113 | <a name="ContractorTypeSubContractor">ContractorTypeSubContractor</a>| 3 | A sub contractor that works for a supervising manager. NOT able to submit invoices. | 2114 | <a name="ContractorTypeNominee">ContractorTypeNominee</a>| 4 | A nominated contractor that has an associated DCC. | 2115 | <a name="ContractorTypeRevoked">ContractorTypeRevoked</a>| 5 | A contractor that has been revoked by a DCC. | 2116 | <a name="ContractorTypeTemp">ContractorTypeTemp</a>| 6 | A temporary contractor that is allowed to submit 1 invoice before being deactivated. | 2117 | <a name="ContractorTypeTempDeactivated">ContractorTypeTempDeactivated</a>| 7 | A previously temporary contractor that has since been deactivated. | 2118 | <a name="ContractorTypeProposal">ContractorTypeProposal</a>| 8 | A contractor that has been implicitly approved through a stakeholder approved proposal. | 2119 2120 ### Payment status codes 2121 | Status | Value | Description | 2122 |-|-|-| 2123 | <a name="PaymentStatusInvalid">PaymentStatusInvalid</a>| 0 | Invalid status. | 2124 | <a name="PaymentStatusWatching">PaymentStatusWatching</a>| 1 | Payment is currently watching. | 2125 | <a name="PaymentStatusPaid">PaymentStatusPaid</a>| 2 | Payment has been observed to have been paid. | 2126 2127 ### DCC type codes 2128 | Type | Value | Description | 2129 |-|-|-| 2130 | <a name="DCCTypeInvalid">DCCTypeInvalid</a>| 0 | Invalid type. | 2131 | <a name="DCCTypeIssuance">DCCTypeIssuance</a>| 1 | DCC issuance proposal. | 2132 | <a name="DCCTypeRevocation">DCCTypeRevocation</a>| 2 | DCC revocation proposal. | 2133 2134 ### DCC status codes 2135 | Status | Value | Description | 2136 |-|-|-| 2137 | <a name="DCCStatusInvalid">DCCStatusInvalid</a>| 0 | Invalid status. | 2138 | <a name="DCCStatusActive">DCCStatusActive</a>| 1 | Currently active issuance/revocation (awaiting sponsors). | 2139 | <a name="DCCStatusSupported">DCCStatusSupported</a>| 2 | Fully supported issuance/revocation (received enough sponsors to proceed). | 2140 | <a name="DCCStatusApproved">DCCStatusApproved</a>| 3 | Approved issuance/revocation | 2141 | <a name="DCCStatusRejected">DCCStatusRejected</a>| 4 | Rejected issuance/revocation | 2142 | <a name="DCCStatusDebate">DCCStatusDebate</a>| 5 | If a issuance/revocation receives enough comments, it would enter a "debate" status that would require a full contractor vote (to be added later). | 2143 2144 ### `Abridged CMS User` 2145 2146 This is a shortened representation of a user, used for lists. 2147 2148 | | Type | Description | 2149 |-|-|-| 2150 | id | string | The unique id of the user. | 2151 | username | string | Unique username. | 2152 | contractortype | string | CMS Domain of the user. | 2153 | domain | string | CMS contractor type of the user. | 2154 2155 ### `Proposal Billing` 2156 2157 **Route:** `POST /v1/proposals/billing` 2158 2159 **Params:** 2160 2161 | Parameter | Type | Description | Required | 2162 |-|-|-|-| 2163 | token | string | Token is the unique censorship token that identifies a specific proposal. | Yes | 2164 2165 **Results:** 2166 2167 | | Type | Description | 2168 | - | - | - | 2169 | lineitems | array | Array of line items billed by a contractor | 2170 2171 * **Example** 2172 2173 Request: 2174 2175 ```json 2176 { 2177 "token": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87" 2178 } 2179 ``` 2180 2181 Reply: 2182 2183 ```json 2184 { 2185 "lineitems": [ 2186 { 2187 "userid": "8172cb38-32b6-4d0f-9607-6f9f1677746c", 2188 "username": "admin", 2189 "month": 5, 2190 "year": 2020, 2191 "lineitem": { 2192 "type": 1, 2193 "domain": "Development", 2194 "subdomain": "uuuuu", 2195 "description": "wwwwww", 2196 "proposaltoken": "0de5bd82bcccf22f4ccd1881fc9d88159ace56d0c1cfc7dcd86656e738e46a87", 2197 "subuserid": "", 2198 "subrate": 0, 2199 "labor": 540, 2200 "expenses": 0 2201 } 2202 } 2203 ] 2204 } 2205 ```