github.com/cozy/cozy-stack@v0.0.0-20240327093429-939e4a21320e/docs/bitwarden.md (about)

     1  [Table of contents](README.md#table-of-contents)
     2  
     3  # Bitwarden
     4  
     5  Cozy-stack exposes an API compatible with
     6  [Bitwarden](https://github.com/bitwarden) on `/bitwarden`.
     7  
     8  The author of the [unofficial Bitwarden-ruby
     9  server](https://github.com/jcs/rubywarden) did some reverse engineering and
    10  wrote a short [API
    11  documentation](https://github.com/jcs/rubywarden/blob/master/API.md).
    12  
    13  ## Setup
    14  
    15  The signup is disabled, there is one account per Cozy instance, with the email
    16  `me@<domain>`. When the user chooses his/her password (onboarding), an encryption key
    17  is also generated to keep safe the secrets in the bitwarden vault.
    18  
    19  ![Setting a new passphrase](diagrams/bitwarden-onboarding.png)
    20  
    21  A cozy organization is also created: it will be used to share some passwords
    22  with the stack, to be used for the konnectors.
    23  
    24  ![Creating the organization key](diagrams/bitwarden-organization.png)
    25  
    26  The bitwarden clients can connect to the cozy-stack APIs by setting their URL
    27  to `https://<instance>/bitwarden`.
    28  
    29  ## Routes for accounts and connect
    30  
    31  ### POST /bitwarden/api/accounts/prelogin & POST /bitwarden/identity/accounts/prelogin
    32  
    33  It allows the client to know the number of KDF iterations to apply when hashing
    34  the master password. It can also tell if the login via OIDC is mandatory, if
    35  the vault is empty (when both conditions are true, the onboarding process is a
    36  bit different), and if flat or nested subdomains are used.
    37  
    38  There are 2 routes for the same endpoint, as Bitwarden has moved from the first
    39  to the second, and we want to ensure a smooth migration for clients.
    40  
    41  #### Request
    42  
    43  ```http
    44  POST /bitwarden/identity/accounts/prelogin HTTP/1.1
    45  Host: alice.example.com
    46  Content-Type: application/json
    47  ```
    48  
    49  ```json
    50  {
    51    "email": "me@alice.example.com"
    52  }
    53  ```
    54  
    55  #### Response
    56  
    57  ```http
    58  HTTP/1.1 200 OK
    59  Content-Type: application/json
    60  ```
    61  
    62  ```json
    63  {
    64    "Kdf": 0,
    65    "KdfIterations": 10000,
    66    "OIDC": false,
    67    "HasCiphers": true,
    68    "FlatSubdomains": true
    69  }
    70  ```
    71  
    72  ### POST /bitwarden/identity/connect/token
    73  
    74  #### Request (initial connection)
    75  
    76  ```http
    77  POST /bitwarden/identity/connect/token HTTP/1.1
    78  Host: alice.example.com
    79  Content-Type: application/x-www-form-urlencoded
    80  ```
    81  
    82  ```
    83  grant_type=password&
    84  username=me@alice.example.com&
    85  password=r5CFRR+n9NQI8a525FY+0BPR0HGOjVJX0cR1KEMnIOo=&
    86  scope=api offline_access&
    87  client_id=browser&
    88  deviceType=3&
    89  deviceIdentifier=aac2e34a-44db-42ab-a733-5322dd582c3d&
    90  deviceName=firefox&
    91  clientName=Cozy&
    92  devicePushToken=
    93  ```
    94  
    95  If authentication with two factors is enabled on the instance and the 
    96  user not logged through a web session, this request will fail with a 
    97  400 status, but it will send an email with the code. The request can 
    98  be retried with an additional paramter: `twoFactorToken`.
    99  
   100  **Note:** the `clientName` parameter is optional, and is not sent by the
   101  official bitwarden clients (a default value is used).
   102  
   103  #### Response
   104  
   105  ```http
   106  HTTP/1.1 200 OK
   107  Content-Type: application/json
   108  ```
   109  
   110  ```json
   111  {
   112    "client_id": "f05671e159450b44d5c78cebbd0260b5",
   113    "registration_access_token": "J9l-ZhwP[...omitted for brevity...]",
   114    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkJDMz[...](JWT string)",
   115    "expires_in": 3600,
   116    "token_type": "Bearer",
   117    "refresh_token": "28fb1911ef6db24025ce1bae5aa940e117eb09dfe609b425b69bff73d73c03bf",
   118    "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ=",
   119    "PrivateKey": null
   120  }
   121  ```
   122  
   123  #### Request (refresh token)
   124  
   125  ```http
   126  POST /bitwarden/identity/connect/token HTTP/1.1
   127  Host: alice.example.com
   128  Content-Type: application/x-www-form-urlencoded
   129  ```
   130  
   131  ```
   132  grant_type=refresh_token&
   133  client_id=browser&
   134  refresh_token=28fb1911ef6db24025ce1bae5aa940e117eb09dfe609b425b69bff73d73c03bf
   135  ```
   136  
   137  #### Response
   138  
   139  ```http
   140  HTTP/1.1 200 OK
   141  Content-Type: application/json
   142  ```
   143  
   144  ```json
   145  {
   146    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkJDMz[...](JWT string)",
   147    "expires_in": 3600,
   148    "token_type": "Bearer",
   149    "refresh_token": "28fb1911ef6db24025ce1bae5aa940e117eb09dfe609b425b69bff73d73c03bf",
   150    "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ="
   151  }
   152  ```
   153  
   154  ### POST /bitwarden/api/accounts/password-hint
   155  
   156  #### Request
   157  
   158  ```http
   159  POST /bitwarden/api/accounts/password-hint HTTP/1.1
   160  Host: alice.example.com
   161  Content-Type: application/json
   162  ```
   163  
   164  ```json
   165  {
   166    "email": "me@alice.example.com"
   167  }
   168  ```
   169  
   170  #### Response
   171  
   172  ```http
   173  HTTP/1.1 200 OK
   174  ```
   175  
   176  ### GET /bitwarden/api/accounts/profile
   177  
   178  #### Request
   179  
   180  ```http
   181  GET /bitwarden/api/accounts/profile HTTP/1.1
   182  Host: alice.example.com
   183  ```
   184  
   185  #### Response
   186  
   187  ```http
   188  HTTP/1.1 200 OK
   189  Content-Type: application/json
   190  ```
   191  
   192  ```json
   193  {
   194    "Id": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
   195    "Name": "Alice",
   196    "Email": "me@alice.example.com",
   197    "EmailVerified": false,
   198    "Premium": false,
   199    "MasterPasswordHint": null,
   200    "Culture": "en-US",
   201    "TwoFactorEnabled": false,
   202    "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ=",
   203    "PrivateKey": null,
   204    "SecurityStamp": "5d203c3f-bc89-499e-85c4-4431248e1196",
   205    "Organizations": [],
   206    "Object": "profile"
   207  }
   208  ```
   209  
   210  ### PUT /bitwarden/api/accounts/profile
   211  
   212  This route allows to change the profile (currently, only the hint for the
   213  master password). It can also be called with a `POST` (I think it is used by
   214  the web vault).
   215  
   216  #### Request
   217  
   218  ```http
   219  PUT /bitwarden/api/accounts/profile HTTP/1.1
   220  Host: alice.example.com
   221  Content-Type: application/json
   222  ```
   223  
   224  ```json
   225  {
   226    "masterPasswordHint": "blah blah blah"
   227  }
   228  ```
   229  
   230  #### Response
   231  
   232  ```http
   233  HTTP/1.1 200 OK
   234  Content-Type: application/json
   235  ```
   236  
   237  ```json
   238  {
   239    "Id": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
   240    "Name": "Alice",
   241    "Email": "me@alice.example.com",
   242    "EmailVerified": false,
   243    "Premium": false,
   244    "MasterPasswordHint": "blah blah blah",
   245    "Culture": "en-US",
   246    "TwoFactorEnabled": false,
   247    "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ=",
   248    "PrivateKey": null,
   249    "SecurityStamp": "5d203c3f-bc89-499e-85c4-4431248e1196",
   250    "Organizations": [],
   251    "Object": "profile"
   252  }
   253  ```
   254  
   255  ### POST /bitwarden/api/accounts/keys
   256  
   257  This route is used to save a key pair (public and private keys), to be used
   258  with organizations.
   259  
   260  #### Request
   261  
   262  ```http
   263  POST /bitwarden/api/accounts/keys HTTP/1.1
   264  Host: alice.example.com
   265  Content-Type: application/json
   266  ```
   267  
   268  ```json
   269  {
   270    "encryptedPrivateKey": "2.wZuKkufLV31Cpw1v1TQUDA==|u6bUNTaaGxu...y7s=",
   271    "publicKey": "MIIBIjANBgkqhkiG9w...AQAB"
   272  }
   273  ```
   274  
   275  #### Response
   276  
   277  ```http
   278  HTTP/1.1 200 OK
   279  Content-Type: application/json
   280  ```
   281  
   282  ```json
   283  {
   284    "Id": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
   285    "Name": "Alice",
   286    "Email": "me@alice.example.com",
   287    "EmailVerified": false,
   288    "Premium": false,
   289    "MasterPasswordHint": null,
   290    "Culture": "en-US",
   291    "TwoFactorEnabled": false,
   292    "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ=",
   293    "PrivateKey": "2.wZuKkufLV31Cpw1v1TQUDA==|u6bUNTaaGxu...y7s=",
   294    "SecurityStamp": "5d203c3f-bc89-499e-85c4-4431248e1196",
   295    "Organizations": [],
   296    "Object": "profile"
   297  }
   298  ```
   299  
   300  ### POST /bitwarden/api/accounts/security-stamp
   301  
   302  It allows to set a new security stamp, which has the effect to disconnect all
   303  the clients. It can be used, for example, if the encryption key is changed to
   304  avoid the clients to corrupt the vault with ciphers encrypted with the old key.
   305  
   306  #### Request
   307  
   308  ```http
   309  POST /bitwarden/api/accounts/security-stamp HTTP/1.1
   310  Host: alice.example.com
   311  Content-Type: application/json
   312  ```
   313  
   314  ```json
   315  {
   316    "masterPasswordHash": "r5CFRR+n9NQI8a525FY+0BPR0HGOjVJX0cR1KEMnIOo="
   317  }
   318  ```
   319  
   320  #### Response
   321  
   322  ```http
   323  HTTP/1.1 204 No Content
   324  ```
   325  
   326  ### GET /bitwarden/api/accounts/revision-date
   327  
   328  It returns the date of the last change on the server, as a number of
   329  milliseconds since epoch (sic). It is used by the clients to know if they have
   330  to do a sync or if they are already up-to-date.
   331  
   332  #### Request
   333  
   334  ```http
   335  GET /bitwarden/api/accounts/revision-date HTTP/1.1
   336  Host: alice.example.com
   337  ```
   338  
   339  #### Response
   340  
   341  ```http
   342  HTTP/1.1 200 OK
   343  
   344  1569571388892
   345  ```
   346  
   347  ### PUT /bitwarden/api/settings/domains
   348  
   349  This route is also available via a `POST`, for compatibility with the web vault.
   350  
   351  #### Request
   352  
   353  ```http
   354  PUT /bitwarden/api/settings/domains HTTP/1.1
   355  Host: alice.example.com
   356  Content-Type: application/json
   357  ```
   358  
   359  ```json
   360  {
   361    "equivalentDomains": [
   362      ["stackoverflow.com", "serverfault.com", "superuser.com"]
   363    ],
   364    "globalEquivalentDomains": [42, 69]
   365  }
   366  ```
   367  
   368  #### Response
   369  
   370  ```http
   371  HTTP/1.1 200 OK
   372  Content-Type: application/json
   373  ```
   374  
   375  ```json
   376  {
   377    "EquivalentDomains": [
   378      ["stackoverflow.com", "serverfault.com", "superuser.com"]
   379    ],
   380    "GlobalEquivalentDomains": [
   381      { "Type": 2, "Domains": ["ameritrade.com", "tdameritrade.com"], "Excluded": false },
   382      { "Type": 3, "Domains": ["bankofamerica.com", "bofa.com", "mbna.com", "usecfo.com"], "Excluded": false },
   383      { "Type": 42, "Domains": ["playstation.com", "sonyentertainmentnetwork.com"], "Excluded": true },
   384      { "Type": 69, "Domains": ["morganstanley.com", "morganstanleyclientserv.com"], "Excluded": true }
   385    ],
   386    "Object": "domains"
   387  }
   388  ```
   389  
   390  ### GET /bitwarden/api/settings/domains
   391  
   392  #### Request
   393  
   394  ```http
   395  GET /bitwarden/api/settings/domains HTTP/1.1
   396  Host: alice.example.com
   397  ```
   398  
   399  #### Response
   400  
   401  ```http
   402  HTTP/1.1 200 OK
   403  Content-Type: application/json
   404  ```
   405  
   406  ```json
   407  {
   408    "EquivalentDomains": [
   409      ["stackoverflow.com", "serverfault.com", "superuser.com"]
   410    ],
   411    "GlobalEquivalentDomains": [
   412      { "Type": 2, "Domains": ["ameritrade.com", "tdameritrade.com"], "Excluded": false },
   413      { "Type": 3, "Domains": ["bankofamerica.com", "bofa.com", "mbna.com", "usecfo.com"], "Excluded": false },
   414      { "Type": 42, "Domains": ["playstation.com", "sonyentertainmentnetwork.com"], "Excluded": true },
   415      { "Type": 69, "Domains": ["morganstanley.com", "morganstanleyclientserv.com"], "Excluded": true }
   416    ],
   417    "Object": "domains"
   418  }
   419  ```
   420  
   421  ## Route for sync
   422  
   423  ### GET /bitwarden/api/sync
   424  
   425  The main action of the client is a one-way sync, which just fetches all objects
   426  from the server and updates its local database.
   427  
   428  #### Request
   429  
   430  ```http
   431  GET /bitwarden/api/sync HTTP/1.1
   432  ```
   433  
   434  #### Response
   435  
   436  ```http
   437  HTTP/1.1 200 OK
   438  Content-Type: application/json
   439  ```
   440  
   441  ```json
   442  {
   443    "Profile": {
   444      "Id": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
   445      "Name": "Alice",
   446      "Email": "me@alice.example.com",
   447      "EmailVerified": false,
   448      "Premium": false,
   449      "MasterPasswordHint": null,
   450      "Culture": "en-US",
   451      "TwoFactorEnabled": false,
   452      "Key": "0.uRcMe+Mc2nmOet4yWx9BwA==|PGQhpYUlTUq/vBEDj1KOHVMlTIH1eecMl0j80+Zu0VRVfFa7X/MWKdVM6OM/NfSZicFEwaLWqpyBlOrBXhR+trkX/dPRnfwJD2B93hnLNGQ=",
   453      "PrivateKey": null,
   454      "SecurityStamp": "5d203c3f-bc89-499e-85c4-4431248e1196",
   455      "Organizations": [
   456        {
   457          "Id": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   458          "Name": "Cozy",
   459          "Key": "4.HUzVDQVAFc4JOpW3/j/QwZeET0mXOiDW5s/HdpxLZ2GFnGcxOm1FE4XD2p7XTSwORXO/Lo8y0A87UhXKEXzfHZmpJR04pbpUPr4NJbjRKv/cSkNFlvm0rIUw/m0Jkft/gew9v3QfkVSGdSZk5XIimwkTQ5WM+WCStxbQJIKAH+AoEA5q6t9mpNNlTAQvMgqs8u7CJwSjeZ7qbabfEUVX1HIPgxC3BtVUkySRSws/gUNeMwY23kAJJQYT+uuMooZUr7umU6YkEHG2RQZwCCjVHX4czxZRWsVo/xQOYoNr7DjgCf92D7OrJlFmDtQjzSy2BjotN6vn+1SwtHbeDILWaQ==",
   460          "BillingEmail": "me@cozy.localhost",
   461          "Plan": "TeamsAnnually",
   462          "PlanType": 5,
   463          "Seats": 2,
   464          "MaxCollections": 1,
   465          "MaxStorageGb": 1,
   466          "SelfHost": true,
   467          "Use2fa": true,
   468          "UseDirectory": false,
   469          "UseEvents": false,
   470          "UseGroups": false,
   471          "UseTotp": true,
   472          "UsersGetPremium": true,
   473          "Enabled": true,
   474          "Status": 2,
   475          "Type": 2,
   476          "Object": "profileOrganization"
   477        }
   478      ],
   479      "Object": "profile"
   480    },
   481    "Folders": [
   482      {
   483        "Id": "14220912-d002-471d-a364-a82a010cb8f2",
   484        "Name": "2.tqb+y2z4ChCYHj4romVwGQ==|E8+D7aR5CNnd+jF7fdb9ow==|wELCxyy341G2F+w8bTb87PAUi6sdXeIFTFb4N8tk3E0=",
   485        "RevisionDate": "2017-11-13T16:20:56.5633333",
   486        "Object": "folder"
   487      }
   488    ],
   489    "Ciphers": [
   490      {
   491        "FolderId": null,
   492        "Favorite": false,
   493        "Edit": true,
   494        "Id": "0f01a66f-7802-42bc-9647-a82600f11e10",
   495        "OrganizationId": null,
   496        "Type": 1,
   497        "Login": {
   498          "Uris": [
   499            {
   500              "Uri": "2.6DmdNKlm3a+9k/5DFg+pTg==|7q1Arwz/ZfKEx+fksV3yo0HMQdypHJvyiix6hzgF3gY=|7lSXqjfq5rD3/3ofNZVpgv1ags696B2XXJryiGjDZvk=",
   501              "Match": null
   502            }
   503          ],
   504          "Username": "2.4Dwitdv4Br85MABzhMJ4hg==|0BJtHtXbfZWwQXbFcBn0aA==|LM4VC+qNpezmub1f4l1TMLDb9g/Q+sIis2vDbU32ZGA=",
   505          "Password": "2.OOlWRBGib6G8WRvBOziKzQ==|Had/obAdd2/6y4qzM1Kc/A==|LtHXwZc5PkiReFhkzvEHIL01NrsWGvintQbmqwxoXSI=",
   506          "Totp": null
   507        },
   508        "Name": "2.zAgCKbTvGowtaRn1er5WGA==|oVaVLIjfBQoRr5EvHTwfhQ==|lHSTUO5Rgfkjl3J/zGJVRfL8Ab5XrepmyMv9iZL5JBE=",
   509        "Notes": "2.NLkXMHtgR8u9azASR4XPOQ==|6/9QPcnoeQJDKBZTjcBAjVYJ7U/ArTch0hUSHZns6v8=|p55cl9FQK/Hef+7yzM7Cfe0w07q5hZI9tTbxupZepyM=",
   510        "Fields": null,
   511        "Attachments": null,
   512        "OrganizationUseTotp": false,
   513        "RevisionDate": "2017-11-09T14:37:52.9033333",
   514        "Object": "cipher"
   515      }
   516    ],
   517    "Collections": [
   518      {
   519        "Id": "385aaa2a-d48d-11e9-bb5f-6b31dfebcb4d",
   520        "OrganizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   521        "Name": "2.PowfE263ZLz7+Jqrpuezqw==|OzuXDsJnQdfa/eMKxsms6Q==|RpEB7qqs26X9dqa+KaxSE5+52TFVs4dAdfU7DCu3QXM=",
   522        "Object": "collection",
   523        "ReadOnly": false
   524      }
   525    ],
   526    "Domains": {
   527      "EquivalentDomains": null,
   528      "GlobalEquivalentDomains": null,
   529      "Object": "domains"
   530    },
   531    "Object": "sync"
   532  }
   533  ```
   534  
   535  ## Routes for ciphers
   536  
   537  ### GET /bitwarden/api/ciphers
   538  
   539  It retrieves the list of ciphers.
   540  
   541  #### Request
   542  
   543  ```http
   544  GET /bitwarden/api/ciphers HTTP/1.1
   545  ```
   546  
   547  #### Response
   548  
   549  ```http
   550  HTTP/1.1 200 OK
   551  Content-Type: application/json
   552  ```
   553  
   554  ```json
   555  {
   556    "Data": [
   557      {
   558        "Object": "cipher",
   559        "Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   560        "Type": 1,
   561        "Favorite": false,
   562        "Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   563        "FolderId": null,
   564        "OrganizationId": null,
   565        "Notes": null,
   566        "Login": {
   567          "Uris": [
   568            {
   569              "Uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   570              "Match": null
   571            }
   572          ]
   573        },
   574        "Username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   575        "Password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   576        "Totp": null,
   577        "Fields": null,
   578        "Attachments": null,
   579        "RevisionDate": "2017-11-07T22:12:22.235914Z",
   580        "Edit": true,
   581        "OrganizationUseTotp": false
   582      }
   583    ],
   584    "Object": "list"
   585  }
   586  ```
   587  
   588  ### POST /bitwarden/api/ciphers
   589  
   590  When a new item (login, secure note, etc.) is created on a device, it is sent
   591  to the server with its fields encrypted via this route.
   592  
   593  #### Request
   594  
   595  ```http
   596  POST /bitwarden/api/ciphers HTTP/1.1
   597  Host: alice.example.com
   598  Content-Type: application/json
   599  ```
   600  
   601  ```json
   602  {
   603  	"type": 1,
   604  	"favorite": false,
   605  	"name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   606  	"folderId": null,
   607  	"organizationId": null,
   608  	"notes": null,
   609  	"login": {
   610  		"uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   611  		"username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   612  		"password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   613  		"totp": null
   614  	}
   615  }
   616  ```
   617  
   618  #### Response
   619  
   620  ```http
   621  HTTP/1.1 200 OK
   622  Content-Type: application/json
   623  ```
   624  
   625  ```json
   626  {
   627  	"Object": "cipher",
   628  	"Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   629  	"Type": 1,
   630  	"Favorite": false,
   631  	"Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   632  	"FolderId": null,
   633  	"OrganizationId": null,
   634  	"Notes": null,
   635  	"Login": {
   636  		"Uris": [
   637  			{
   638  				"Uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   639  				"Match": null
   640  			}
   641  		]
   642  	},
   643  	"Username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   644  	"Password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   645  	"Totp": null,
   646  	"Fields": null,
   647  	"Attachments": null,
   648  	"RevisionDate": "2017-11-07T22:12:22.235914Z",
   649  	"Edit": true,
   650  	"OrganizationUseTotp": false
   651  }
   652  ```
   653  
   654  ### POST /bitwarden/api/ciphers/create
   655  
   656  This route also allows to create a cipher, but this time, it is for a cipher
   657  shared with an organization.
   658  
   659  #### Request
   660  
   661  ```http
   662  POST /bitwarden/api/ciphers/create HTTP/1.1
   663  Host: alice.example.com
   664  Content-Type: application/json
   665  ```
   666  
   667  ```json
   668  {
   669    "cipher": {
   670      "type": 1,
   671      "favorite": false,
   672      "name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   673      "folderId": null,
   674      "organizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   675      "notes": null,
   676      "login": {
   677        "uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   678        "username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   679        "password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   680        "totp": null
   681      }
   682    },
   683    "collectionIds": ["385aaa2a-d48d-11e9-bb5f-6b31dfebcb4d"]
   684  }
   685  ```
   686  
   687  #### Response
   688  
   689  ```http
   690  HTTP/1.1 200 OK
   691  Content-Type: application/json
   692  ```
   693  
   694  ```json
   695  {
   696  	"Object": "cipher",
   697  	"Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   698  	"Type": 1,
   699  	"Favorite": false,
   700  	"Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   701  	"FolderId": null,
   702  	"OrganizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   703  	"Notes": null,
   704  	"Login": {
   705  		"Uris": [
   706  			{
   707  				"Uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   708  				"Match": null
   709  			}
   710  		]
   711  	},
   712  	"Username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   713  	"Password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   714  	"Totp": null,
   715  	"Fields": null,
   716  	"Attachments": null,
   717  	"RevisionDate": "2017-11-07T22:12:22.235914Z",
   718  	"Edit": true,
   719  	"OrganizationUseTotp": false
   720  }
   721  ```
   722  
   723  ### GET /bitwarden/api/ciphers/:id and /bitwarden/api/ciphers/:id/details
   724  
   725  #### Request
   726  
   727  ```http
   728  GET /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251 HTTP/1.1
   729  ```
   730  
   731  #### Response
   732  
   733  ```http
   734  HTTP/1.1 200 OK
   735  Content-Type: application/json
   736  ```
   737  
   738  ```json
   739  {
   740  	"Object": "cipher",
   741  	"Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   742  	"Type": 1,
   743  	"Favorite": false,
   744  	"Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
   745  	"FolderId": null,
   746  	"OrganizationId": null,
   747  	"Notes": null,
   748  	"Login": {
   749  		"Uris": [
   750  			{
   751  				"Uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
   752  				"Match": null
   753  			}
   754  		]
   755  	},
   756  	"Username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
   757  	"Password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
   758  	"Totp": null,
   759  	"Fields": null,
   760  	"Attachments": null,
   761  	"RevisionDate": "2017-11-07T22:12:22.235914Z",
   762  	"Edit": true,
   763  	"OrganizationUseTotp": false
   764  }
   765  ```
   766  
   767  ### PUT /bitwarden/api/ciphers/:id
   768  
   769  This route is used to change a cipher. It can also be called via
   770  `POST /bitwarden/api/ciphers/:id` (I think it is used by the web vault).
   771  
   772  #### Request
   773  
   774  ```http
   775  PUT /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251 HTTP/1.1
   776  Host: alice.example.com
   777  Content-Type: application/json
   778  ```
   779  
   780  ```json
   781  {
   782  	"type": 2,
   783  	"favorite": true,
   784  	"name": "2.G38TIU3t1pGOfkzjCQE7OQ==|Xa1RupttU7zrWdzIT6oK+w==|J3C6qU1xDrfTgyJD+OrDri1GjgGhU2nmRK75FbZHXoI=",
   785  	"folderId": "14220912-d002-471d-a364-a82a010cb8f2",
   786  	"organizationId": null,
   787  	"notes": "2.rSw0uVQEFgUCEmOQx0JnDg==|MKqHLD25aqaXYHeYJPH/mor7l3EeSQKsI7A/R+0bFTI=|ODcUScISzKaZWHlUe4MRGuTT2S7jpyDmbOHl7d+6HiM=",
   788  	"secureNote": {
   789  		"type": 0
   790  	}
   791  }
   792  ```
   793  
   794  #### Response
   795  
   796  ```http
   797  HTTP/1.1 200 OK
   798  Content-Type: application/json
   799  ```
   800  
   801  ```json
   802  {
   803  	"Object": "cipher",
   804  	"Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   805  	"Type": 2,
   806  	"Favorite": true,
   807  	"Name": "2.G38TIU3t1pGOfkzjCQE7OQ==|Xa1RupttU7zrWdzIT6oK+w==|J3C6qU1xDrfTgyJD+OrDri1GjgGhU2nmRK75FbZHXoI=",
   808  	"FolderId": "14220912-d002-471d-a364-a82a010cb8f2",
   809  	"OrganizationId": null,
   810  	"Notes": "2.rSw0uVQEFgUCEmOQx0JnDg==|MKqHLD25aqaXYHeYJPH/mor7l3EeSQKsI7A/R+0bFTI=|ODcUScISzKaZWHlUe4MRGuTT2S7jpyDmbOHl7d+6HiM=",
   811    "SecureNote": {
   812      "Type": 0
   813    },
   814  	"Fields": null,
   815  	"Attachments": null,
   816  	"RevisionDate": "2017-11-07T22:12:22.235914Z",
   817  	"Edit": true,
   818  	"OrganizationUseTotp": false
   819  }
   820  ```
   821  
   822  ### POST /bitwarden/api/ciphers/:id/share
   823  
   824  This route is used to share a cipher with an organization. The fields must be
   825  encrypted with the organization key.
   826  
   827  #### Request
   828  
   829  ```http
   830  POST /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251/share HTTP/1.1
   831  Host: alice.example.com
   832  Content-Type: application/json
   833  ```
   834  
   835  ```json
   836  {
   837    "cipher": {
   838      "type": 2,
   839      "favorite": true,
   840      "name": "2.d00W2bB8LhE86LybnoPnEQ==|QqJqmzMMv2Cdm9wieUH66Q==|TV++tKNF0+4/axjAeRXMxAkTdRBuIsXnCuhOKE0ESh0=",
   841      "organizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   842      "notes": "2.9m3XIbiJLk86thmF3UsO/A==|YC7plTgNQuMCkzYZC3iRjQ==|o8wZNQ3czr9sdeGXjOCalQwgPWsqOHZVnA2utZ+o/l4=",
   843      "secureNote": {
   844        "type": 0
   845      }
   846    },
   847    "collectionIds": ["385aaa2a-d48d-11e9-bb5f-6b31dfebcb4d"]
   848  }
   849  ```
   850  
   851  #### Response
   852  
   853  ```http
   854  HTTP/1.1 200 OK
   855  Content-Type: application/json
   856  ```
   857  
   858  ```json
   859  {
   860  	"Object": "cipher",
   861  	"Id": "4c2869dd-0e1c-499f-b116-a824016df251",
   862  	"Type": 2,
   863  	"Favorite": true,
   864    "Name": "2.d00W2bB8LhE86LybnoPnEQ==|QqJqmzMMv2Cdm9wieUH66Q==|TV++tKNF0+4/axjAeRXMxAkTdRBuIsXnCuhOKE0ESh0=",
   865    "OrganizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
   866    "Notes": "2.9m3XIbiJLk86thmF3UsO/A==|YC7plTgNQuMCkzYZC3iRjQ==|o8wZNQ3czr9sdeGXjOCalQwgPWsqOHZVnA2utZ+o/l4=",
   867    "SecureNote": {
   868      "Type": 0
   869    },
   870  	"Fields": null,
   871  	"Attachments": null,
   872  	"RevisionDate": "2017-11-07T22:12:22.235914Z",
   873  	"Edit": true,
   874  	"OrganizationUseTotp": false
   875  }
   876  ```
   877  
   878  ### DELETE /bitwarden/api/ciphers/:id
   879  
   880  This route is used to delete a cipher. It can also be called via
   881  `POST /bitwarden/api/ciphers/:id/delete` (I think it is used by the web vault).
   882  
   883  #### Request
   884  
   885  ```http
   886  DELETE /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251 HTTP/1.1
   887  Host: alice.example.com
   888  ```
   889  
   890  #### Response
   891  
   892  ```http
   893  HTTP/1.1 200 OK
   894  ```
   895  
   896  ### DELETE /bitwarden/api/ciphers
   897  
   898  This route is used to delete ciphers in bulk. It can also be called via
   899  `POST /bitwarden/api/ciphers/delete`.
   900  
   901  #### Request
   902  
   903  ```http
   904  DELETE /bitwarden/api/ciphers HTTP/1.1
   905  Host: alice.example.com
   906  Content-Type: application/json
   907  ```
   908  
   909  ```json
   910  {
   911    "ids": [
   912      "4c2869dd-0e1c-499f-b116-a824016df251",
   913      "205c22f0-8642-0139-c874-543d7eb8149c"
   914    ]
   915  }
   916  ```
   917  
   918  #### Response
   919  
   920  ```http
   921  HTTP/1.1 200 OK
   922  ```
   923  
   924  ### PUT /bitwarden/api/ciphers/:id/delete
   925  
   926  This route is used to soft delete a cipher, by adding a `deletedDate`
   927  attribute on it.
   928  
   929  #### Request
   930  
   931  ```http
   932  PUT /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251/delete HTTP/1.1
   933  Host: alice.example.com
   934  ```
   935  
   936  #### Response
   937  
   938  ```http
   939  HTTP/1.1 204 No Content
   940  ```
   941  
   942  ### PUT /bitwarden/api/ciphers/delete
   943  
   944  This route is used to soft delete ciphers in bulk.
   945  
   946  #### Request
   947  
   948  ```http
   949  PUT /bitwarden/api/ciphers/delete HTTP/1.1
   950  Host: alice.example.com
   951  Content-Type: application/json
   952  ```
   953  
   954  ```json
   955  {
   956    "ids": [
   957      "4c2869dd-0e1c-499f-b116-a824016df251",
   958      "205c22f0-8642-0139-c874-543d7eb8149c"
   959    ]
   960  }
   961  ```
   962  
   963  #### Response
   964  
   965  ```http
   966  HTTP/1.1 200 OK
   967  ```
   968  
   969  ### PUT /bitwarden/api/ciphers/:id/restore
   970  
   971  This route is used to restore a soft-deleted cipher, by removing the
   972  `deletedDate` attribute.
   973  
   974  #### Request
   975  
   976  ```http
   977  PUT /bitwarden/api/ciphers/4c2869dd-0e1c-499f-b116-a824016df251/restore HTTP/1.1
   978  Host: alice.example.com
   979  ```
   980  
   981  #### Response
   982  
   983  ```http
   984  HTTP/1.1 204 No Content
   985  ```
   986  
   987  ### PUT /bitwarden/api/ciphers/restore
   988  
   989  This route is used to restore ciphers in bulk.
   990  
   991  #### Request
   992  
   993  ```http
   994  PUT /bitwarden/api/ciphers/restore HTTP/1.1
   995  Host: alice.example.com
   996  Content-Type: application/json
   997  ```
   998  
   999  ```json
  1000  {
  1001    "ids": [
  1002      "4c2869dd-0e1c-499f-b116-a824016df251",
  1003      "205c22f0-8642-0139-c874-543d7eb8149c"
  1004    ]
  1005  }
  1006  ```
  1007  
  1008  #### Response
  1009  
  1010  ```http
  1011  HTTP/1.1 200 OK
  1012  Content-Type: application/json
  1013  ```
  1014  
  1015  ```json
  1016  {
  1017    "Data": [
  1018      {
  1019        "Object": "cipher",
  1020        "Id": "4c2869dd-0e1c-499f-b116-a824016df251",
  1021        "Type": 1,
  1022        "Favorite": false,
  1023        "Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
  1024        "FolderId": null,
  1025        "OrganizationId": null,
  1026        "Notes": null,
  1027        "Login": {
  1028          "Uris": [
  1029            {
  1030              "Uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
  1031              "Match": null
  1032            }
  1033          ]
  1034        },
  1035        "Username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
  1036        "Password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
  1037        "Totp": null,
  1038        "Fields": null,
  1039        "Attachments": null,
  1040        "RevisionDate": "2021-04-23T12:58:01Z",
  1041        "Edit": true,
  1042        "OrganizationUseTotp": false
  1043      },
  1044      {
  1045        "Object": "cipher",
  1046        "Id": "205c22f0-8642-0139-c874-543d7eb8149c",
  1047        "Type": 2,
  1048        "Favorite": true,
  1049        "Name": "2.G38TIU3t1pGOfkzjCQE7OQ==|Xa1RupttU7zrWdzIT6oK+w==|J3C6qU1xDrfTgyJD+OrDri1GjgGhU2nmRK75FbZHXoI=",
  1050        "FolderId": null,
  1051        "OrganizationId": null,
  1052        "Notes": "2.rSw0uVQEFgUCEmOQx0JnDg==|MKqHLD25aqaXYHeYJPH/mor7l3EeSQKsI7A/R+0bFTI=|ODcUScISzKaZWHlUe4MRGuTT2S7jpyDmbOHl7d+6HiM=",
  1053        "RevisionDate": "2021-04-23T12:58:01Z",
  1054        "Edit": true,
  1055        "OrganizationUseTotp": false
  1056      }
  1057    ],
  1058    "Object": "list"
  1059  }
  1060  ```
  1061  
  1062  
  1063  ### POST /bitwarden/api/ciphers/import
  1064  
  1065  This route can be used to import several ciphers and folders in bulk.
  1066  
  1067  In `folderRelationships`, the `key` is the index of the cipher in the `ciphers`
  1068  list, and the `value` is the index of the folder in the `folders` list.
  1069  
  1070  #### Request
  1071  
  1072  ```http
  1073  POST /bitwarden/api/ciphers/import HTTP/1.1
  1074  Host: alice.example.com
  1075  Content-Type: application/json
  1076  ```
  1077  
  1078  ```json
  1079  {
  1080    "ciphers": [{
  1081      "type": 2,
  1082      "favorite": true,
  1083      "name": "2.G38TIU3t1pGOfkzjCQE7OQ==|Xa1RupttU7zrWdzIT6oK+w==|J3C6qU1xDrfTgyJD+OrDri1GjgGhU2nmRK75FbZHXoI=",
  1084      "folderId": null,
  1085      "organizationId": null,
  1086      "notes": "2.rSw0uVQEFgUCEmOQx0JnDg==|MKqHLD25aqaXYHeYJPH/mor7l3EeSQKsI7A/R+0bFTI=|ODcUScISzKaZWHlUe4MRGuTT2S7jpyDmbOHl7d+6HiM=",
  1087      "secureNote": {
  1088        "type": 0
  1089      }
  1090    }, {
  1091      "type": 1,
  1092      "favorite": false,
  1093      "name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
  1094      "folderId": null,
  1095      "organizationId": null,
  1096      "notes": null,
  1097      "login": {
  1098        "uri": "2.T57BwAuV8ubIn/sZPbQC+A==|EhUSSpJWSzSYOdJ/AQzfXuUXxwzcs/6C4tOXqhWAqcM=|OWV2VIqLfoWPs9DiouXGUOtTEkVeklbtJQHkQFIXkC8=",
  1099        "username": "2.JbFkAEZPnuMm70cdP44wtA==|fsN6nbT+udGmOWv8K4otgw==|JbtwmNQa7/48KszT2hAdxpmJ6DRPZst0EDEZx5GzesI=",
  1100        "password": "2.e83hIsk6IRevSr/H1lvZhg==|48KNkSCoTacopXRmIZsbWg==|CIcWgNbaIN2ix2Fx1Gar6rWQeVeboehp4bioAwngr0o=",
  1101        "totp": null
  1102      }
  1103    }],
  1104    "folders": [{
  1105      "name": "2.FQAwIBaDbczEGnEJw4g4hw==|7KreXaC0duAj0ulzZJ8ncA==|nu2sEvotjd4zusvGF8YZJPnS9SiJPDqc1VIfCrfve/o="
  1106    }],
  1107    "folderRelationships": [
  1108      {"key": 1, "value": 0}
  1109    ]
  1110  }
  1111  ```
  1112  
  1113  #### Response
  1114  
  1115  ```http
  1116  HTTP/1.1 204 No Content
  1117  ```
  1118  
  1119  ## Routes for folders
  1120  
  1121  ### GET /bitwarden/api/folders
  1122  
  1123  It retrieves the list of folders.
  1124  
  1125  #### Request
  1126  
  1127  ```http
  1128  GET /bitwarden/api/folders HTTP/1.1
  1129  ```
  1130  
  1131  #### Response
  1132  
  1133  ```http
  1134  HTTP/1.1 200 OK
  1135  Content-Type: application/json
  1136  ```
  1137  
  1138  ```json
  1139  {
  1140    "Data": [
  1141      {
  1142        "Id": "14220912-d002-471d-a364-a82a010cb8f2",
  1143        "Name": "2.FQAwIBaDbczEGnEJw4g4hw==|7KreXaC0duAj0ulzZJ8ncA==|nu2sEvotjd4zusvGF8YZJPnS9SiJPDqc1VIfCrfve/o=",
  1144        "RevisionDate": "2017-11-13T16:18:23.3078169Z",
  1145        "Object": "folder"
  1146      }
  1147    ],
  1148    "Object": "list"
  1149  }
  1150  ```
  1151  
  1152  ### POST /bitwarden/api/folders
  1153  
  1154  It adds a new folder on the server. The name is encrypted on client-side.
  1155  
  1156  #### Request
  1157  
  1158  ```http
  1159  POST /bitwarden/api/folders HTTP/1.1
  1160  Host: alice.example.com
  1161  Content-Type: application/json
  1162  ```
  1163  
  1164  ```json
  1165  {
  1166    "name": "2.FQAwIBaDbczEGnEJw4g4hw==|7KreXaC0duAj0ulzZJ8ncA==|nu2sEvotjd4zusvGF8YZJPnS9SiJPDqc1VIfCrfve/o="
  1167  }
  1168  ```
  1169  
  1170  #### Response
  1171  
  1172  ```http
  1173  HTTP/1.1 200 OK
  1174  Content-Type: application/json
  1175  ```
  1176  
  1177  ```json
  1178  {
  1179  	"Id": "14220912-d002-471d-a364-a82a010cb8f2",
  1180  	"Name": "2.FQAwIBaDbczEGnEJw4g4hw==|7KreXaC0duAj0ulzZJ8ncA==|nu2sEvotjd4zusvGF8YZJPnS9SiJPDqc1VIfCrfve/o=",
  1181  	"RevisionDate": "2017-11-13T16:18:23.3078169Z",
  1182  	"Object": "folder"
  1183  }
  1184  ```
  1185  
  1186  ### GET /bitwarden/api/folders/:id
  1187  
  1188  #### Request
  1189  
  1190  ```http
  1191  GET /bitwarden/api/folders/14220912-d002-471d-a364-a82a010cb8f2 HTTP/1.1
  1192  ```
  1193  
  1194  #### Response
  1195  
  1196  ```http
  1197  HTTP/1.1 200 OK
  1198  Content-Type: application/json
  1199  ```
  1200  
  1201  ```json
  1202  {
  1203  	"Id": "14220912-d002-471d-a364-a82a010cb8f2",
  1204  	"Name": "2.FQAwIBaDbczEGnEJw4g4hw==|7KreXaC0duAj0ulzZJ8ncA==|nu2sEvotjd4zusvGF8YZJPnS9SiJPDqc1VIfCrfve/o=",
  1205  	"RevisionDate": "2017-11-13T16:18:23.3078169Z",
  1206  	"Object": "folder"
  1207  }
  1208  ```
  1209  
  1210  ### PUT /bitwarden/api/folders/:id
  1211  
  1212  This route is used to rename a folder. It can also be called via
  1213  `POST /bitwarden/api/folders/:id` (I think it is used by the web vault).
  1214  
  1215  #### Request
  1216  
  1217  ```http
  1218  PUT /bitwarden/api/folders/14220912-d002-471d-a364-a82a010cb8f2 HTTP/1.1
  1219  Host: alice.example.com
  1220  Content-Type: application/json
  1221  ```
  1222  
  1223  ```json
  1224  {
  1225    "name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io="
  1226  }
  1227  ```
  1228  
  1229  #### Response
  1230  
  1231  ```http
  1232  HTTP/1.1 200 OK
  1233  Content-Type: application/json
  1234  ```
  1235  
  1236  ```json
  1237  {
  1238  	"Id": "14220912-d002-471d-a364-a82a010cb8f2",
  1239  	"Name": "2.d7MttWzJTSSKx1qXjHUxlQ==|01Ath5UqFZHk7csk5DVtkQ==|EMLoLREgCUP5Cu4HqIhcLqhiZHn+NsUDp8dAg1Xu0Io=",
  1240  	"RevisionDate": "2017-11-13T16:18:23.3078169Z",
  1241  	"Object": "folder"
  1242  }
  1243  ```
  1244  
  1245  ### DELETE /bitwarden/api/folders/:id
  1246  
  1247  This route is used to delete a folder. It can also be called via
  1248  `POST /bitwarden/api/folders/:id/delete` (I think it is used by the web vault).
  1249  
  1250  #### Request
  1251  
  1252  ```http
  1253  DELETE /bitwarden/api/folders/14220912-d002-471d-a364-a82a010cb8f2 HTTP/1.1
  1254  Host: alice.example.com
  1255  ```
  1256  
  1257  #### Response
  1258  
  1259  ```http
  1260  HTTP/1.1 200 OK
  1261  ```
  1262  
  1263  ## Organizations and Collections
  1264  
  1265  ### GET /bitwarden/organizations/cozy
  1266  
  1267  This route can be used to get information about the Cozy Organization. It
  1268  requires a permission on the whole `com.bitwarden.organizations` doctype to
  1269  access it. In particular, it gives the key to encrypt/decrypt the ciphers in
  1270  this organization (encoded in base64).
  1271  
  1272  #### Request
  1273  
  1274  ```http
  1275  GET /bitwarden/organizations/cozy HTTP/1.1
  1276  Host: alice.example.com
  1277  ```
  1278  
  1279  #### Response
  1280  
  1281  ```http
  1282  HTTP/1.1 200 OK
  1283  Content-Type: application/json
  1284  ```
  1285  
  1286  ```json
  1287  {
  1288    "organizationId": "38ac39d0-d48d-11e9-91bf-f37e45d48c79",
  1289    "collectionId": "385aaa2a-d48d-11e9-bb5f-6b31dfebcb4d",
  1290    "organizationKey": "oWeRYokoCMFsAja6lrp3RQ1PYOrex4tgAMECP4nX+a4IXdijbejQscvWqy9bMgLsX0HRc2igqBRMWdsPuFK0PQ=="
  1291  }
  1292  ```
  1293  
  1294  ### POST /bitwarden/api/organizations
  1295  
  1296  This route can be used to create an organization, with a collection.
  1297  
  1298  #### Request
  1299  
  1300  ```http
  1301  POST /bitwarden/api/organizations HTTP/1.1
  1302  Host: alice.example.com
  1303  Content-Type: application/json
  1304  ```
  1305  
  1306  ```json
  1307  {
  1308    "name": "Family",
  1309    "key": "4.bmFjbF53D9mrdGbVqQzMB54uIg678EIpU/uHFYjynSPSA6vIv5/6nUy4Uk22SjIuDB3pZ679wLE3o7R/Imzn47OjfT6IrJ8HaysEhsZA25Dn8zwEtTMtgNepUtH084wAMgNeIcElW24U/MfRscjAk8cDUIm5xnzyi2vtJfe9PcHTmzRXyng=",
  1310    "collectionName": "2.rrpSDDODsWZqL7EhLVsu/Q==|OSuh+MmmR89ppdb/A7KxBg==|kofpAocL2G4a3P1C2R1U+i9hWbhfKfsPKM6kfoyCg/M="
  1311  }
  1312  ```
  1313  
  1314  #### Response
  1315  
  1316  ```http
  1317  HTTP/1.1 200 OK
  1318  Content-Type: application/json
  1319  ```
  1320  
  1321  ```json
  1322  {
  1323    "Id": "724db920-cc4b-0139-6ab2-543d7eb8149c",
  1324    "Name": "Family",
  1325    "Key": "4.bmFjbF53D9mrdGbVqQzMB54uIg678EIpU/uHFYjynSPSA6vIv5/6nUy4Uk22SjIuDB3pZ679wLE3o7R/Imzn47OjfT6IrJ8HaysEhsZA25Dn8zwEtTMtgNepUtH084wAMgNeIcElW24U/MfRscjAk8cDUIm5xnzyi2vtJfe9PcHTmzRXyng=",
  1326    "BillingEmail": "me@cozy.localhost",
  1327    "Plan": "TeamsAnnually",
  1328    "PlanType": 9,
  1329    "Seats": 10,
  1330    "MaxCollections": 1,
  1331    "MaxStorageGb": 1,
  1332    "SelfHost": true,
  1333    "Use2fa": true,
  1334    "UseDirectory": false,
  1335    "UseEvents": false,
  1336    "UseGroups": false,
  1337    "UseTotp": true,
  1338    "UseApi": false,
  1339    "UsePolicies": false,
  1340    "UseSSO": false,
  1341    "UseResetPass": false,
  1342    "HasPublicAndPrivateKeys": false,
  1343    "ResetPasswordEnrolled": false,
  1344    "UsersGetPremium": true,
  1345    "Enabled": true,
  1346    "Status": 2,
  1347    "Type": 2,
  1348    "Object": "profileOrganization"
  1349  }
  1350  ```
  1351  
  1352  ### GET /bitwarden/api/organizations/:id
  1353  
  1354  This route can be used to fetch information about an organization.
  1355  
  1356  #### Request
  1357  
  1358  ```http
  1359  GET /bitwarden/api/organizations/724db920-cc4b-0139-6ab2-543d7eb8149c HTTP/1.1
  1360  Host: alice.example.com
  1361  ```
  1362  
  1363  #### Response
  1364  
  1365  ```http
  1366  HTTP/1.1 200 OK
  1367  Content-Type: application/json
  1368  ```
  1369  
  1370  ```json
  1371  {
  1372    "Id": "724db920-cc4b-0139-6ab2-543d7eb8149c",
  1373    "Name": "Family",
  1374    "Key": "4.bmFjbF53D9mrdGbVqQzMB54uIg678EIpU/uHFYjynSPSA6vIv5/6nUy4Uk22SjIuDB3pZ679wLE3o7R/Imzn47OjfT6IrJ8HaysEhsZA25Dn8zwEtTMtgNepUtH084wAMgNeIcElW24U/MfRscjAk8cDUIm5xnzyi2vtJfe9PcHTmzRXyng=",
  1375    "BillingEmail": "me@cozy.localhost",
  1376    "Plan": "TeamsAnnually",
  1377    "PlanType": 9,
  1378    "Seats": 10,
  1379    "MaxCollections": 1,
  1380    "MaxStorageGb": 1,
  1381    "SelfHost": true,
  1382    "Use2fa": true,
  1383    "UseDirectory": false,
  1384    "UseEvents": false,
  1385    "UseGroups": false,
  1386    "UseTotp": true,
  1387    "UseApi": false,
  1388    "UsePolicies": false,
  1389    "UseSSO": false,
  1390    "UseResetPass": false,
  1391    "HasPublicAndPrivateKeys": false,
  1392    "ResetPasswordEnrolled": false,
  1393    "UsersGetPremium": true,
  1394    "Enabled": true,
  1395    "Status": 2,
  1396    "Type": 2,
  1397    "Object": "profileOrganization"
  1398  }
  1399  ```
  1400  
  1401  ### GET /bitwarden/api/organizations/:id/collections
  1402  
  1403  This route can be used to fetch information about the collections inside an
  1404  organization.
  1405  
  1406  #### Request
  1407  
  1408  ```http
  1409  GET /bitwarden/api/organizations/724db920-cc4b-0139-6ab2-543d7eb8149c/collections HTTP/1.1
  1410  Host: alice.example.com
  1411  ```
  1412  
  1413  #### Response
  1414  
  1415  ```http
  1416  HTTP/1.1 200 OK
  1417  Content-Type: application/json
  1418  ```
  1419  
  1420  ```json
  1421  {
  1422    "Data": [
  1423      {
  1424        "Id": "62080a40-d75d-0139-21f1-543d7eb8149c",
  1425        "OrganizationId": "724db920-cc4b-0139-6ab2-543d7eb8149c",
  1426        "Name": "2.rrpSDDODsWZqL7EhLVsu/Q==|OSuh+MmmR89ppdb/A7KxBg==|kofpAocL2G4a3P1C2R1U+i9hWbhfKfsPKM6kfoyCg/M=",
  1427        "Object": "collection"
  1428      }
  1429    ],
  1430    "Object": "list"
  1431  }
  1432  ```
  1433  
  1434  ### DELETE /bitwarden/api/organizations/:id
  1435  
  1436  This route can be used to delete an organization by its owner.
  1437  
  1438  #### Request
  1439  
  1440  ```http
  1441  DELETE /bitwarden/api/organizations/724db920-cc4b-0139-6ab2-543d7eb8149c HTTP/1.1
  1442  Host: alice.example.com
  1443  Content-Type: application/json
  1444  ```
  1445  
  1446  ```json
  1447  {
  1448    "masterPasswordHash": "r5CFRR+n9NQI8a525FY+0BPR0HGOjVJX0cR1KEMnIOo="
  1449  }
  1450  ```
  1451  
  1452  #### Response
  1453  
  1454  ```http
  1455  HTTP/1.1 200 OK
  1456  ```
  1457  
  1458  ### GET /bitwarden/api/organizations/:id/users
  1459  
  1460  This route returns the list of users in the given organization.
  1461  
  1462  #### Request
  1463  
  1464  ```http
  1465  GET /bitwarden/api/organizations/724db920-cc4b-0139-6ab2-543d7eb8149c/users HTTP/1.1
  1466  Host: alice.example.com
  1467  ```
  1468  
  1469  #### Response
  1470  
  1471  ```http
  1472  HTTP/1.1 200 OK
  1473  Content-Type: application/json
  1474  ```
  1475  
  1476  ```json
  1477  {
  1478    "Data": [
  1479      {
  1480        "Object": "organizationUserUserDetails",
  1481        "Id": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
  1482        "UserId": "0fbfc68d-ba11-416a-ac8a-a82600f0e601",
  1483        "Type": 0,
  1484        "Status": 2,
  1485        "AccessAll": true,
  1486        "Name": "Alice",
  1487        "Email": "alice@example.com"
  1488      },
  1489      {
  1490        "Object": "organizationUserUserDetails",
  1491        "Id": "89d99af0db1c0139605b543d7eb8149c",
  1492        "UserId": "89d99af0db1c0139605b543d7eb8149c",
  1493        "Type": 2,
  1494        "Status": 1,
  1495        "AccessAll": true,
  1496        "Name": "Bob",
  1497        "Email": "bob@example.com"
  1498      }
  1499    ],
  1500    "Object": "list"
  1501  }
  1502  ```
  1503  
  1504  ### POST /bitwarden/api/organizations/:id/users/:user-id/confirm
  1505  
  1506  This route is used by the owner of an organization to confirm that another user
  1507  can use this sharing. The caller must check the fingerprint of the new member
  1508  and encrypt the organization key with their public key.
  1509  
  1510  #### Request
  1511  
  1512  ```http
  1513  POST /bitwarden/api/organizations/724db920-cc4b-0139-6ab2-543d7eb8149c/users/89d99af0db1c0139605b543d7eb8149c/confirm HTTP/1.1
  1514  Host: alice.example.com
  1515  Content-Type: application/json
  1516  ```
  1517  
  1518  ```json
  1519  {
  1520    "key": "4.UT/TVY6qmAjNdax2WT9JcA97wSWvEudAlqpjfxrFUieOoGA88MxzbYjpCXajEST/PehD1I7KC93jwthng772extu+lLHSd/Ce+a5Qw8+pRxL7je8QgS8gmP0FhfRLc4bl5hUMTfQcUDiuiiNaDez6E9czOzk9iuVaGpEjK4YAYgQy25m3eGc+DTPv8206NJZ/lr8CpPyhwUHjtDhlOZnDWAf+a28x2EAj1ogZKKJGAUcRENitV8Joa7OGRO6dmxtTTnWOuPDk5DajGgzpIQURNuotVHcpBtCL8HzNAduQ9vtrPKJtyAsHRdjau2SwEnaLZmxAvp7d9VG3t5nDYtgWA=="
  1521  }
  1522  ```
  1523  
  1524  #### Response
  1525  
  1526  ```http
  1527  HTTP/1.1 200 OK
  1528  ```
  1529  
  1530  ### GET /bitwarden/api/users/:id/public-key
  1531  
  1532  This route gives the public key of a user.
  1533  
  1534  #### Request
  1535  
  1536  ```http
  1537  GET /bitwarden/api/users/89d99af0db1c0139605b543d7eb8149c/public-key HTTP/1.1
  1538  Host: alice.example.com
  1539  ```
  1540  
  1541  #### Response
  1542  
  1543  ```http
  1544  HTTP/1.1 200 OK
  1545  Content-Type: application/json
  1546  ```
  1547  
  1548  ```json
  1549  {
  1550    "UserId": "89d99af0db1c0139605b543d7eb8149c",
  1551    "PublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1LwbnLsT8w2OBPR/zy/zRQNH+jZzD6v4qUGAJg0NfoUkBSgtq9yjor2GgeRtdf8VuNTn1kcNrUIU4f9vE3ppNJgmUss4O29OP9/ATqtC/4ri4UCWTV0DPCF4gRU1SbgTg9O3yC2UYWmrs47SgU0wwT+f5AjfDC7GzhjyX68UYIIIeKSMZasjcy+wIPVAW0hYhcEoK3Coq2O1wVwM+b2fXPIMzn38onUTbMCrkVY+FzGg6NtZbKzPvVZ0iyfQ6BxvttqSViNPOpyz7gryDhgYKokV+kwj5ARDZWL6ml73U2lL7uapk5meNKZf8w7TJGepFiewGLm08VMht6lnIZBuDQIDAQAB"
  1552  }
  1553  ```
  1554  
  1555  ### DELETE /bitwarden/contacts/:id
  1556  
  1557  This route can be used to refuse to give access to a user to shared ciphers.
  1558  The contact will be deleted, and they will be revoked from all sharings.
  1559  
  1560  #### Request
  1561  
  1562  ```http
  1563  GET /bitwarden/contacts/89d99af0db1c0139605b543d7eb8149c HTTP/1.1
  1564  Host: alice.example.com
  1565  ```
  1566  
  1567  #### Response
  1568  
  1569  ```http
  1570  HTTP/1.1 204 No-Content
  1571  ```
  1572  
  1573  ## Icons
  1574  
  1575  ### GET /bitwarden/icons/:domain/icon.png
  1576  
  1577  This route returns an icon for the given domain, that can be used by the
  1578  bitwarden clients. No authorization token is required.
  1579  
  1580  If no favicon has been found for the domain, a fallback will be used, depending
  1581  of the `fallback` parameter in the query-string:
  1582  
  1583  - `default`: a default icon is returned
  1584  - `404`: just a 404 - Not found error.
  1585  
  1586  #### Request
  1587  
  1588  ```http
  1589  GET /bitwarden/icons/cozy.io/icon.png HTTP/1.1
  1590  Host: alice.example.com
  1591  ```
  1592  
  1593  ## Hub
  1594  
  1595  The hub is a way to get notifications in real-time about cipher and folder
  1596  changes.
  1597  
  1598  ### POST /bitwarden/notifications/hub/negotiate
  1599  
  1600  Before connecting to the hub, the client make a request to this endpoint to
  1601  know what are the transports and formats supported by the server.
  1602  
  1603  #### Request
  1604  
  1605  ```http
  1606  POST /bitwarden/notifications/hub/negotiate HTTP/1.1
  1607  Host: alice.example.com
  1608  ```
  1609  
  1610  #### Response
  1611  
  1612  ```http
  1613  HTTP/1.1 200 OK
  1614  Content-Type: application/json
  1615  ```
  1616  
  1617  ```json
  1618  {
  1619    "connectionId": "NzhhYjU4NjgtZTA1NC0xMWU5LWIzNzAtM2I1YzM3YWQyOTc1Cg",
  1620    "availableTransports": [
  1621      { "Transport": "WebSockets", "Formats": ["Binary"] }
  1622    ]
  1623  }
  1624  ```
  1625  
  1626  ### GET /bitwarden/notifications/hub
  1627  
  1628  This endpoint is used for WebSockets to get the notifications in real-time. The
  1629  client must do 3 things, in this order:
  1630  
  1631  1. Make the HTTP request, with the token in the query string (`access_token`)
  1632  2. Upgrade the connection to WebSockets
  1633  3. Send JSON payload with `{"protocol": "messagepack", "version": 1}`.