github.com/decred/politeia@v1.4.0/politeiad/api/v1/api.md (about)

     1  # politeiad API Specification
     2  
     3  # v1
     4  
     5  This document describes the REST API provided by a `politeiad` daemon.
     6  
     7  `politeiad` provides a time-ordered cryptographically-accountable digital
     8  commons where speech of various formats can be exchanged with a transparent
     9  censorship mechanism.
    10  
    11  **Methods**
    12  
    13  - [`Identity`](#identity)
    14  - [`New record`](#new-record)
    15  - [`Get unvetted record`](#get-unvetted-record)
    16  - [`Get vetted record`](#get-vetted-record)
    17  - [`Set unvetted status`](#set-unvetted-status)
    18  - [`Set vetted status`](#set-vetted-status)
    19  - [`Update unvetted record`](#update-unvetted-record)
    20  - [`Update vetted record`](#update-vetted-record)
    21  - [`Update vetted metadata`](#update-vetted-metadata)
    22  - [`Inventory`](#inventory)
    23  
    24  **Error status codes**
    25  
    26  - [`ErrorStatusInvalid`](#ErrorStatusInvalid)
    27  - [`ErrorStatusInvalidRequestPayload`](#ErrorStatusInvalidRequestPayload)
    28  - [`ErrorStatusInvalidChallenge`](#ErrorStatusInvalidChallenge)
    29  - [`ErrorStatusInvalidFilename`](#ErrorStatusInvalidFilename)
    30  - [`ErrorStatusInvalidFileDigest`](#ErrorStatusInvalidFileDigest)
    31  - [`ErrorStatusInvalidBase64`](#ErrorStatusInvalidBase64)
    32  - [`ErrorStatusInvalidMIMEType`](#ErrorStatusInvalidMIMEType)
    33  - [`ErrorStatusUnsupportedMIMEType`](#ErrorStatusUnsupportedMIMEType)
    34  - [`ErrorStatusInvalidRecordStatusTransition`](#ErrorStatusInvalidRecordStatusTransition)
    35  - [`ErrorStatusEmpty`](#ErrorStatusEmpty)
    36  - [`ErrorStatusInvalidMDID`](#ErrorStatusInvalidMDID)
    37  - [`ErrorStatusDuplicateMDID`](#ErrorStatusDuplicateMDID)
    38  - [`ErrorStatusDuplicateFilename`](#ErrorStatusDuplicateFilename)
    39  - [`ErrorStatusFileNotFound`](#ErrorStatusFileNotFound)
    40  - [`ErrorStatusNoChanges`](#ErrorStatusNoChanges)
    41  
    42  **Record status codes**
    43  
    44  - [`RecordStatusInvalid`](#RecordStatusInvalid)
    45  - [`RecordStatusNotFound`](#RecordStatusNotFound)
    46  - [`RecordStatusNotReviewed`](#RecordStatusNotReviewed)
    47  - [`RecordStatusCensored`](#RecordStatusCensored)
    48  - [`RecordStatusPublic`](#RecordStatusPublic)
    49  - [`RecordStatusUnreviewedChanges`](#RecordStatusUnreviewedChanges)
    50  
    51  ## Methods
    52  
    53  ### `Identity`
    54  
    55  Obtain `politeiad` Ed25519 public key. For more information go to
    56  https://ed25519.cr.yp.to/
    57  
    58  All `politeiad` commands are initiated by clients and shall contain a challenge
    59  that shall be signed by the server.  The client challenge shall be a 32 byte
    60  hex encoded array. Clients shall verify the challenge signature.
    61  
    62  **Route**: `POST /v1/identity`
    63  
    64  **Params**:
    65  
    66  | Parameter | Type | Description | Required |
    67  |-|-|-|-|
    68  | challenge | string | 32 byte hex encoded array. | Yes |
    69  
    70  **Results**:
    71  
    72  | | Type | Description |
    73  |-|-|-|
    74  | response | string | hex encoded signature of challenge byte array. |
    75  | publickey | string | Ed25519 public key that is used to verify all server side signatures. |
    76  
    77  **Example**
    78  
    79  Request:
    80  
    81  ```json
    82  {
    83    "challenge":"808a6d4f02d91434f3b7e176f1cc8d0a2e90b47565ff1f0d722386b7785d3e3e"
    84  }
    85  ```
    86  
    87  Reply:
    88  
    89  ```json
    90  {
    91    "response":"fa51baceaf08edb0e75aaf02d8a0180757c960650f3df63fc7fabe7b4677fe3cb07fabcdb700ed5aded5818cb92ba05f97a83fae606710f74deaeef238868406",
    92    "publickey":"8f627e9da14322626d7e81d789f7fcafd25f62235a95377f39cbc7293c4944ad"
    93  }
    94  ```
    95  
    96  ### `New record`
    97  
    98  Create a new record.
    99  
   100  **Route**: `POST /v1/newrecord`
   101  
   102  **Params**:
   103  
   104  | Parameter | Type | Description | Required |
   105  |-|-|-|-|
   106  | challenge | string | 32 byte hex encoded array. | Yes |
   107  | metadata | array of [`Metadata stream`](#metadata-stream) | Streams of non-provable metadata. | Yes |
   108  | files | array of [`File`](#file) | Files that make up the provable record. | Yes |
   109  
   110  **Results**:
   111  
   112  | | Type | Description |
   113  |-|-|-|
   114  | response | string | hex encoded signature of challenge byte array. |
   115  | censorshiprecord | [CensorshipRecord](#censorship-record) | A censorship record that provides the submitter with a method to extract the record and prove that he/she submitted it. |
   116  
   117  **Example**
   118  
   119  Request:
   120  
   121  ```json
   122  {
   123    "challenge":"de0256b26ad723a979febf1d4b59c4dcd451946fcf16bea314a5286a45d2af3e",
   124    "metadata":
   125    [
   126      {
   127        "id":12,
   128        "payload":"{\"moo\":\"lala\"}"
   129      },
   130      {
   131        "id":2,
   132        "payload":"{\"foo\":\"bar\"}"
   133      }
   134    ],
   135    "files":
   136    [
   137      {
   138        "name":"a",
   139        "mime":"text/plain; charset=utf-8",
   140        "digest":"22e88c7d6da9b73fbb515ed6a8f6d133c680527a799e3069ca7ce346d90649b2",
   141        "payload":"bW9vCg=="
   142      }
   143    ]
   144  }
   145  ```
   146  
   147  Reply:
   148  
   149  ```json
   150  {
   151    "response":"3d01eb4929c4d7bbe08cd139b872f3f2b626602340e7010335259b04e80564499acefbe7fec5b55203517c55e710f01c726820a428fdf7c9ab791ebba65acc03",
   152    "censorshiprecord":
   153    {
   154      "token":"d76e2f721957dfadee51c1edd6a478dcff6291a3b5b10e15557bbeddf11abe82",
   155      "merkle":"22e88c7d6da9b73fbb515ed6a8f6d133c680527a799e3069ca7ce346d90649b2",
   156      "signature":"6a1f539ad8c9098eb05732157b066df05a659d477864130cc0d74403c1253c40d60718b27786c36e8fd96cac1a8beac5c768c1423bfd65acc3e180276364840b"
   157    }
   158  }
   159  ```
   160  
   161  ### `Get unvetted record`
   162  
   163  Retrieve an unvetted record.
   164  
   165  **Route**: `POST /v1/getunvetted`
   166  
   167  **Params**:
   168  
   169  | Parameter | Type | Description | Required |
   170  |-|-|-|-|
   171  | challenge | string | 32 byte hex encoded array. | Yes |
   172  | token | string | Record identifier. | Yes |
   173  
   174  **Results**:
   175  
   176  | | Type | Description |
   177  |-|-|-|
   178  | response | string | hex encoded signature of challenge byte array. |
   179  | record | [Record](#record) | Record, including metadata. |
   180  
   181  **Example**
   182  
   183  Request:
   184  
   185  ```json
   186  {
   187    "challenge":"36a5c4d0574e8b963d7221a867eb3d629089b3b83b58e600aeb291b786743231",
   188    "token":"e2354df18ea005e409ae488a07c73d1648944ea07b350c1d0854f76d520855d4"
   189  }
   190  ```
   191  
   192  Reply:
   193  
   194  ```json
   195  {
   196    "response":"914d8aa889b7a3fbfbbbe168f3ff8c502984efe40505b569abb11c0ce7665c2938eabc853cb77afa53f1d0db9ef588def0f65ff6d126407ae6a9b8bd3c08ee08",
   197    "record":
   198    {
   199      "status":2,
   200      "timestamp":1512761862,
   201      "censorshiprecord":
   202      {
   203        "token":"e2354df18ea005e409ae488a07c73d1648944ea07b350c1d0854f76d520855d4",
   204        "merkle":"22e88c7d6da9b73fbb515ed6a8f6d133c680527a799e3069ca7ce346d90649b2",
   205        "signature":"23a40823bc75bd984d47039b0ee4066fe750701aec26f0dceeae5882425b4ac09c8a0cf4a6b09ad0284fafbc6f142e8a80e7d97448ddd1ae321390bd7d91b305"
   206      },
   207      "metadata":
   208      [
   209        {
   210          "id":2,
   211  	"payload":"{\"foo\":\"bar\"}"
   212        },{
   213          "id":12,
   214  	"payload":"{\"moo\":\"lala\"}"
   215        }
   216      ],
   217      "files":
   218      [
   219        {
   220          "name":"a",
   221  	"mime":"text/plain; charset=utf-8",
   222  	"digest":"22e88c7d6da9b73fbb515ed6a8f6d133c680527a799e3069ca7ce346d90649b2",
   223  	"payload":"bW9vCg=="
   224        }
   225      ]
   226    }
   227  }
   228  ```
   229  
   230  ### `Get vetted record`
   231  
   232  Retrieve a vetted record.
   233  
   234  **Route**: `POST /v1/getvetted`
   235  
   236  **Params**:
   237  
   238  | Parameter | Type | Description | Required |
   239  |-|-|-|-|
   240  | challenge | string | 32 byte hex encoded array. | Yes |
   241  | token | string | Record identifier. | Yes |
   242  | version | string | Record version. | No |
   243  **Results**:
   244  
   245  | | Type | Description |
   246  |-|-|-|
   247  | response | string | hex encoded signature of challenge byte array. |
   248  | record | [Record](#record) | Record, including metadata. |
   249  
   250  **Example**
   251  
   252  Request:
   253  
   254  ```json
   255  {
   256    "challenge":"8a18531579091a9de89ba1f8d61878bd39540126950b4a668d19c2a57eea6acf",
   257    "token":"b468a8f7b1cc96031b7ba0f83c57c67f64e9247482f32be59baaa9f6631a2fea"
   258  }
   259  ```
   260  
   261  Reply:
   262  
   263  ```json
   264  {
   265    "response":"f782a969a49cd5e779a748b8c3aa1be758d19f4af0631519e0a74d8cd26787a8d74ad359e738623985e16f64d2c1d5871273c85627519295afc4058703bd6508",
   266    "record":
   267    {
   268      "status":4,
   269      "timestamp":1513013590,
   270      "censorshiprecord":
   271      {
   272        "token":"b468a8f7b1cc96031b7ba0f83c57c67f64e9247482f32be59baaa9f6631a2fea",
   273        "merkle":"77ba3195336398cd9faa7bc8cefe2bbfbb2b4979fef92a400ce6e91e29ef22d2",
   274        "signature":"c94cd71ba065381ad1832d59b5b3d525213012e3a8ed29e8f15646ecaad1ce0109f88cdb343dde516d80c6b32ae69794d897ce6964a719347d61443483b35103"
   275      },
   276      "metadata":
   277      [
   278        {
   279          "id":2,
   280  	"payload":"{\"foo\":\"bar\"}"},
   281  	{"id":12,"payload":"{\"moo\":\"lala\"}"
   282        }
   283      ],
   284      "files":
   285      [
   286        {
   287          "name":"a",
   288  	"mime":"text/plain; charset=utf-8",
   289  	"digest":"22e88c7d6da9b73fbb515ed6a8f6d133c680527a799e3069ca7ce346d90649b2",
   290  	"payload":"bW9vCg=="
   291        },
   292        {
   293          "name":"b",
   294  	"mime":"text/plain; charset=utf-8",
   295  	"digest":"12a31b5e662dfa0a572e9fc523eb703f9708de5e2d53aba74f8ebcebbdb706f7",
   296  	"payload":"aWJsZWgK"
   297        }
   298      ]
   299    }
   300  }
   301  ```
   302  
   303  ### `Set unvetted status`
   304  
   305  Set unvetted status of a record.  There are only a few valid state transitions.
   306  A record that public or unreviewed may be changed.  Changes must be vetted by
   307  issuing a [`Set unvetted status`](#set-unvetted-status) call. Note that
   308  individual updates will be visible once the changes are made public.
   309  
   310  One can, optionally, send in metadata streams for update as well.  This can,
   311  for example, be used to mark who made an update.
   312  
   313  Censoring a record is a permanent action and once a recod is censored it can
   314  not be modfied.
   315  
   316  This command requires administrator privileges.
   317  
   318  **Route**: `POST /v1/setunvettedstatus`
   319  
   320  **Params**:
   321  
   322  | Parameter | Type | Description | Required |
   323  |-|-|-|-|
   324  | challenge | string | 32 byte hex encoded array. | Yes |
   325  | token | string | Record identifier. | Yes |
   326  | status | number | New record status. | Yes |
   327  | mdappend | array of [`MetadataStream`](#metadatastream) | Append payload to metadata stream(s). | No |
   328  | mdoverwrite | array of [`MetadataStream`](#metadatastream) | Overwrite payload to metadata stream(s). | No |
   329  
   330  **Results**:
   331  
   332  | | Type | Description |
   333  |-|-|-|
   334  | response | string | hex encoded signature of challenge byte array. |
   335  | status | number | New record status. |
   336  
   337  **Example**
   338  
   339  Request:
   340  
   341  ```json
   342  {
   343    "challenge":"db30532986113a7f973a589700e4296c93b3d9662a07c778bcf1ef4011dceb90",
   344    "token":"1993f120323c4a4f89bf75cbd72e8eb728246e1e48292052abe8221e49588423",
   345    "status":3,
   346    "mdappend":
   347    [
   348      {
   349        "id":2,
   350        "payload":"{\"11foo\":\"11bar\"}"
   351      }
   352    ],
   353    "mdoverwrite":
   354    [
   355      {
   356        "id":12,"payload":"\"zap\""
   357      }
   358    ]
   359  }
   360  ```
   361  
   362  Reply:
   363  
   364  ```json
   365  {
   366    "response":"a5cd683beec39c34ec7b01ad7c2c0c57757dbe7353f5b759ac6121755a5465b5edd157b0d198c8fdfa7d9960876dc4dfbd10dfb63acba93b8ba05d342668320d",
   367    "status":3
   368  }
   369  ```
   370  
   371  ### `Set vetted status`
   372  
   373  Set vetted status of a record.  The only state transition that is allowed is 
   374  setting a record that is public to archived.  Changes must be vetted by
   375  issuing a [`Set vetted status`](#set-vetted-status) call.
   376  
   377  One can, optionally, send in metadata streams for update as well.  This can,
   378  for example, be used to mark who made an update.
   379  
   380  Marking a proposal as abandoned is a permanent action and once a record is
   381  archived it can not be modified.
   382  
   383  This command requires administrator privileges.
   384  
   385  **Route**: `POST /v1/setvettedstatus`
   386  
   387  **Params**:
   388  
   389  | Parameter | Type | Description | Required |
   390  |-|-|-|-|
   391  | challenge | string | 32 byte hex encoded array. | Yes |
   392  | token | string | Record identifier. | Yes |
   393  | status | number | New record status. | Yes |
   394  | mdappend | array of [`MetadataStream`](#metadatastream) | Append payload to metadata stream(s). | No |
   395  | mdoverwrite | array of [`MetadataStream`](#metadatastream) | Overwrite payload to metadata stream(s). | No |
   396  
   397  **Results**:
   398  
   399  | | Type | Description |
   400  |-|-|-|
   401  | response | string | hex encoded signature of challenge byte array. |
   402  | status | number | New record status. |
   403  
   404  **Example**
   405  
   406  Request:
   407  
   408  ```json
   409  {
   410    "challenge":"db30532986113a7f973a589700e4296c93b3d9662a07c778bcf1ef4011dceb90",
   411    "token":"1993f120323c4a4f89bf75cbd72e8eb728246e1e48292052abe8221e49588423",
   412    "status":6,
   413    "mdappend":
   414    [
   415      {
   416        "id":2,
   417        "payload":"{\"11foo\":\"11bar\"}"
   418      }
   419    ],
   420    "mdoverwrite":
   421    [
   422      {
   423        "id":12,"payload":"\"zap\""
   424      }
   425    ]
   426  }
   427  ```
   428  
   429  Reply:
   430  
   431  ```json
   432  {
   433    "response":"a5cd683beec39c34ec7b01ad7c2c0c57757dbe7353f5b759ac6121755a5465b5edd157b0d198c8fdfa7d9960876dc4dfbd10dfb63acba93b8ba05d342668320d",
   434    "status":6
   435  }
   436  ```
   437  
   438  ### `Update unvetted record`
   439  
   440  Update a unvetted record. This call enables a user to update a record by
   441  adding/overwriting files, deleting files and append/overwrite metadata
   442  records.  All changes will be recorded as changesets in the backend.
   443  
   444  The returned censorship record will contain the newly calculated merkle root
   445  of the entire record. It is the responsibility of the caller to keep track of
   446  files that have been added or removed if they wish to independently verify 
   447  the record.
   448  
   449  Note that metadata streams are NOT part of the official record.  They exist for
   450  the caller to be able to associate pertinent data to the record.  For example,
   451  they can be used to store JSON encoded comments in a proposal system.
   452  
   453  **Route**: `POST /v1/updateunvetted`
   454  
   455  **Params**:
   456  
   457  | Parameter | Type | Description | Required |
   458  |-|-|-|-|
   459  | challenge | string | 32 byte hex encoded array. | Yes |
   460  | token | string | 32 byte record identifier. |
   461  | mdappend | array of [`MetadataStream`](#metadatastream) | Append payload to metadata stream(s). | No |
   462  | mdoverwrite | array of [`MetadataStream`](#metadatastream) | Overwrite payload to metadata stream(s). | No |
   463  | filesdel | array of string | Filesnames to remove from record. | No |
   464  | filesadd | array of [`File`](#file) | Files to add/overwrite in record. | No |
   465  
   466  **Results**:
   467  
   468  | | Type | Description |
   469  |-|-|-|
   470  | response | string | hex encoded signature of challenge byte array. |
   471  | record | [Record](#record) | Record, including metadata. |
   472  
   473  **Example**
   474  
   475  Request:
   476  
   477  ```json
   478  {
   479    "challenge":"3d41f60ffd17176e7b456e67a2fb712d3ff7a719edb45db11c87b124b9d9afc1",
   480    "token":"793766f3be00e093318b8f13e6e0e200be209d56b53263ce61c5f9fbb2309321",
   481    "mdappend":
   482    [
   483      {
   484        "id":12,
   485        "payload":"{\"foo\":\"bar\"}"
   486      }
   487    ],
   488    "mdoverwrite":null,
   489    "filesdel":
   490    [
   491      "a"
   492    ],
   493    "filesadd":
   494    [
   495      {
   496      "name":"b",
   497      "mime":"text/plain; charset=utf-8",
   498      "digest":"12a31b5e662dfa0a572e9fc523eb703f9708de5e2d53aba74f8ebcebbdb706f7",
   499      "payload":"aWJsZWgK"
   500      }
   501    ]
   502  }
   503  ```
   504  
   505  Reply:
   506  
   507  ```json
   508  {
   509    "response":"f782a969a49cd5e779a748b8c3aa1be758d19f4af0631519e0a74d8cd26787a8d74ad359e738623985e16f64d2c1d5871273c85627519295afc4058703bd6508",
   510    "record":
   511    {
   512      "status":5,
   513      "timestamp":1513013590,
   514      "version": 1,
   515      "censorshiprecord":
   516      {
   517        "token":"793766f3be00e093318b8f13e6e0e200be209d56b53263ce61c5f9fbb2309321",
   518        "merkle":"77ba3195336398cd9faa7bc8cefe2bbfbb2b4979fef92a400ce6e91e29ef22d2",
   519        "signature":"c94cd71ba065381ad1832d59b5b3d525213012e3a8ed29e8f15646ecaad1ce0109f88cdb343dde516d80c6b32ae69794d897ce6964a719347d61443483b35103"
   520      },
   521      "metadata":
   522      [
   523        {
   524          "id":2,
   525          "payload":"{\"foo\":\"bar\"}"},
   526          {"id":12,"payload":"{\"moo\":\"lala\"}"
   527        }
   528      ],
   529      "files":
   530      [
   531        {
   532          "name":"b",
   533          "mime":"text/plain; charset=utf-8",
   534          "digest":"12a31b5e662dfa0a572e9fc523eb703f9708de5e2d53aba74f8ebcebbdb706f7",
   535          "payload":"aWJsZWgK"
   536        }
   537      ]
   538    }
   539  }
   540  ```
   541  
   542  ### `Update vetted record`
   543  
   544  Update a vetted record. This call enables a user to update a record by
   545  adding/overwriting files, deleting files and append/overwrite metadata
   546  records. All changes will be recorded as changesets in the backend.
   547  
   548  A new version of the record will be generated and returned. The returned 
   549  censorship record will contain the newly calculated merkle root of the 
   550  entire record.
   551  
   552  Note that metadata streams are NOT part of the official record.  They exist for
   553  the caller to be able to associate pertinent data to the record.  For example,
   554  they can be used to store JSON encoded comments in a proposal system.
   555  
   556  **Route**: `POST /v1/updatevetted`
   557  
   558  **Params**:
   559  
   560  | Parameter | Type | Description | Required |
   561  |-|-|-|-|
   562  | challenge | string | 32 byte hex encoded array. | Yes |
   563  | token | string | 32 byte record identifier. |
   564  | mdappend | array of [`MetadataStream`](#metadatastream) | Append payload to metadata stream(s). | No |
   565  | mdoverwrite | array of [`MetadataStream`](#metadatastream) | Overwrite payload to metadata stream(s). | No |
   566  | filesdel | array of string | Filesnames to remove from record. | No |
   567  | filesadd | array of [`File`](#file) | Files to add/overwrite in record. | No |
   568  
   569  **Results**:
   570  
   571  | | Type | Description |
   572  |-|-|-|
   573  | response | string | hex encoded signature of challenge byte array. |
   574  | record | [Record](#record) | Record, including metadata. |
   575  
   576  **Example**
   577  
   578  Request:
   579  
   580  ```json
   581  {
   582    "challenge":"3d41f60ffd17176e7b456e67a2fb712d3ff7a719edb45db11c87b124b9d9afc1",
   583    "token":"793766f3be00e093318b8f13e6e0e200be209d56b53263ce61c5f9fbb2309321",
   584    "mdappend":
   585    [
   586      {
   587        "id":12,
   588        "payload":"{\"foo\":\"bar\"}"
   589      }
   590    ],
   591    "mdoverwrite":null,
   592    "filesdel":
   593    [
   594      "a"
   595    ],
   596    "filesadd":
   597    [
   598      {
   599      "name":"b",
   600      "mime":"text/plain; charset=utf-8",
   601      "digest":"12a31b5e662dfa0a572e9fc523eb703f9708de5e2d53aba74f8ebcebbdb706f7",
   602      "payload":"aWJsZWgK"
   603      }
   604    ]
   605  }
   606  ```
   607  
   608  Reply:
   609  
   610  ```json
   611  {
   612    "response":"f782a969a49cd5e779a748b8c3aa1be758d19f4af0631519e0a74d8cd26787a8d74ad359e738623985e16f64d2c1d5871273c85627519295afc4058703bd6508",
   613    "record":
   614    {
   615      "status":4,
   616      "timestamp":1513013590,
   617      "version": 2,
   618      "censorshiprecord":
   619      {
   620        "token":"793766f3be00e093318b8f13e6e0e200be209d56b53263ce61c5f9fbb2309321",
   621        "merkle":"77ba3195336398cd9faa7bc8cefe2bbfbb2b4979fef92a400ce6e91e29ef22d2",
   622        "signature":"c94cd71ba065381ad1832d59b5b3d525213012e3a8ed29e8f15646ecaad1ce0109f88cdb343dde516d80c6b32ae69794d897ce6964a719347d61443483b35103"
   623      },
   624      "metadata":
   625      [
   626        {
   627          "id":2,
   628          "payload":"{\"foo\":\"bar\"}"},
   629          {"id":12,"payload":"{\"moo\":\"lala\"}"
   630        }
   631      ],
   632      "files":
   633      [
   634        {
   635          "name":"b",
   636          "mime":"text/plain; charset=utf-8",
   637          "digest":"12a31b5e662dfa0a572e9fc523eb703f9708de5e2d53aba74f8ebcebbdb706f7",
   638          "payload":"aWJsZWgK"
   639        }
   640      ]
   641    }
   642  }
   643  ```
   644  
   645  ### `Update vetted metadata`
   646  
   647  Update a record's metadata.  This call enables a user to update a record's
   648  metadata by appending/overwriting metadata records.
   649  
   650  Note that metadata streams are NOT part of the official record.  They exist for
   651  the caller to be able to associate pertinent data to the record.  For example,
   652  they can be used to store JSON encoded comments in a proposal system.
   653  
   654  The caller must ensure that unvetted metadata does not clash with the vetted
   655  metadata update.  This will lead on undocumented errors.  The metadata streams
   656  should therefore never be updated with multiple calls.  Pick a methodology and
   657  stick with it for that stream.
   658  
   659  This command requires administrator privileges.
   660  
   661  **Route**: `POST /v1/updatevettedmd`
   662  
   663  **Params**:
   664  
   665  | Parameter | Type | Description | Required |
   666  |-|-|-|-|
   667  | challenge | string | 32 byte hex encoded array. | Yes |
   668  | token | string | 32 byte record identifier. |
   669  | mdappend | array of [`MetadataStream`](#metadatastream) | Append payload to metadata stream(s). | No |
   670  | mdoverwrite | array of [`MetadataStream`](#metadatastream) | Overwrite payload to metadata stream(s). | No |
   671  
   672  **Results**:
   673  
   674  | | Type | Description |
   675  |-|-|-|
   676  | response | string | hex encoded signature of challenge byte array. |
   677  
   678  **Example**
   679  
   680  Request:
   681  
   682  ```json
   683  {
   684    "challenge":"3d41f60ffd17176e7b456e67a2fb712d3ff7a719edb45db11c87b124b9d9afc1",
   685    "token":"793766f3be00e093318b8f13e6e0e200be209d56b53263ce61c5f9fbb2309321",
   686    "mdappend":
   687    [
   688      {
   689        "id":12,
   690        "payload":"{\"foo\":\"bar\"}"
   691      }
   692    ],
   693    "mdoverwrite":null,
   694  }
   695  ```
   696  
   697  Reply:
   698  
   699  ```json
   700  {
   701    "response":"ee90b6bc26a899916d80dacef0bef1ba8238b94d9a00edbc04c69372c21faa96abbe3f6f91ece0879ca4616e713951380cdb7762e23c477708f4aba35c366b0c",
   702  }
   703  ```
   704  
   705  ### `Inventory`
   706  
   707  Retrieve all records.  This is a very expensive call.
   708  This command requires administrator privileges.
   709  
   710  **Route**: `POST /v1/inventory`
   711  
   712  **Params**:
   713  
   714  | Parameter | Type | Description | Required |
   715  |-|-|-|-|
   716  
   717  **Results**:
   718  
   719  | | Type | Description |
   720  |-|-|-|
   721  
   722  **Example**
   723  
   724  Request:
   725  
   726  ```json
   727  ```
   728  
   729  Reply:
   730  
   731  ```json
   732  ```
   733  
   734  ### `Error status codes`
   735  
   736  | Status | Value | Description |
   737  |-|-|-|
   738  | <a name="ErrorStatusInvalid">ErrorStatusInvalid</a>| 0 | An invalid status. This shall be considered a bug. |
   739  | <a name="ErrorStatusInvalidRequestPayload">ErrorStatusInvalidRequestPayload</a>| 1 | Invalid requested payload. |
   740  | <a name="ErrorStatusInvalidChallenge">ErrorStatusInvalidChallenge</a>| 2 | Invalid challenge. |
   741  | <a name="ErrorStatusInvalidFilename">ErrorStatusInvalidFilename</a>| 3 | Invalid filename submitted in record. |
   742  | <a name="ErrorStatusInvalidFileDigest">ErrorStatusInvalidFileDigest</a>| 4 | Invalid file digest. |
   743  | <a name="ErrorStatusInvalidBase64">ErrorStatusInvalidBase64</a>| 5 | Payload not base64 encoded. |
   744  | <a name="ErrorStatusInvalidMIMEType">ErrorStatusInvalidMIMEType</a>| 6 | Payload MIME type does not match. |
   745  | <a name="ErrorStatusUnsupportedMIMEType">ErrorStatusUnsupportedMIMEType</a>| 7 | Unsuported MIME type. |
   746  | <a name="ErrorStatusInvalidRecordStatusTransition">ErrorStatusInvalidRecordStatusTransition</a>| 8 | Invalid record status stransition. |
   747  | <a name="ErrorStatusEmpty">ErrorStatusEmpty</a>| 9 | No files in record. |
   748  | <a name="ErrorStatusInvalidMDID">ErrorStatusInvalidMDID</a>| 10 | Invalid metadata stream identifier. Possible values 0..15 |
   749  | <a name="ErrorStatusDuplicateMDID">ErrorStatusDuplicateMDID</a>| 11 | Duplicate metadata stream identifier. |
   750  | <a name="ErrorStatusDuplicateFilename">ErrorStatusDuplicateFilename</a>| 12 | Duplicate filename. |
   751  | <a name="ErrorStatusFileNotFound">ErrorStatusFileNotFound</a>| 13 | File does not exist. |
   752  | <a name="ErrorStatusNoChanges">ErrorStatusNoChanges</a>| 14 | File does not exist. |
   753  
   754  ### `Record status codes`
   755  
   756  | Status | Value | Description |
   757  |-|-|-|
   758  | <a name="RecordStatusInvalid">RecordStatusInvalid</a>| 0 | An invalid status. This shall be considered a bug. |
   759  | <a name="RecordStatusNotFound">RecordStatusNotFound</a>| 1 | Record not found. |
   760  | <a name="RecordStatusNotReviewed">RecordStatusNotReviewed</a>| 2 | Record not reviewed. |
   761  | <a name="RecordStatusCensored">RecordStatusCensored</a>| 3 | Record censored. |
   762  | <a name="RecordStatusPublic">RecordStatusPublic</a>| 4 | Record published. |
   763  | <a name="RecordStatusUnreviewedChanges">RecordStatusUnreviewedChanges</a>| 4 | Record s published but it has unpublished changes. |
   764  
   765  ### `File`
   766  
   767  | | Type | Description |
   768  |-|-|-|
   769  | name | string | Name is the suggested filename. There should be no filenames that are overlapping and the name shall be validated before being used. |
   770  | mime | string | MIME type of the payload. Currently the system only supports md and png files. The server shall reject invalid MIME types. |
   771  | digest | string | Digest is a SHA256 digest of the payload. The digest shall be verified by politeiad. |
   772  | payload | string | Payload is the actual file content. It shall be base64 encoded. |
   773  
   774  ### `Metadata stream`
   775  | | Type | Description |
   776  |-|-|-|
   777  | id | uint64 | ID of the metadata stream. Currently politeiad supports 16 (0..15) streams per record. |
   778  | payload | string | Running metadata records. These are not verified or handled by the server.  They are simply stored alongside the record. |
   779  
   780  ### `Censorship record`
   781  
   782  | | Type | Description |
   783  |-|-|-|
   784  | token | string | The token is a 32 byte random number that was assigned to identify the submitted record. This is the key to later retrieve the submitted record from the system. |
   785  | merkle | string | Merkle root of the record. This is defined as the sorted digests of all files record files. The client should cross verify this value. |
   786  | signature | string | Signature of byte array representations of merkle+token. The token byte array is appended to the merkle root byte array and then signed. The client should verify the signature. |
   787  
   788  ### `Record`
   789  
   790  | | Type | Description |
   791  |-|-|-|
   792  | status | [`Record status`](#record-status) | Current status. |
   793  | timestamp | int64 | Last update. |
   794  | censorshiprecord | [`Censorship record`](#censorship-record) | Censorship record. |
   795  | version | string | Version of this record |
   796  | metadata | [`Metadata stream`](#metadata-stream) | Metadata streams. |
   797  | files | [`Files`](#files) | Files. |