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  ```