github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/docs/files.md (about)

     1  [Table of contents](README.md#table-of-contents)
     2  
     3  # Virtual File System
     4  
     5  Cozy applications can use files for storing binary content, like photos or bills
     6  in PDF. This service offers a REST API to manipulate easily without having to
     7  know the underlying storage layer. The metadata are kept in CouchDB, but the
     8  binaries can go to the local system, or a Swift instance.
     9  
    10  ## Directories
    11  
    12  A directory is a container for files and sub-directories.
    13  
    14  Its path is the path of its parent, a slash (`/`), and its name. It's case
    15  sensitive.
    16  
    17  ### Root directory
    18  
    19  The root of the virtual file system is a special directory with id
    20  `io.cozy.files.root-dir`.
    21  
    22  You can use it in any request where you would use a directory, except you cannot
    23  delete it.
    24  
    25  ### POST /files/:dir-id
    26  
    27  Create a new directory. The `dir-id` parameter is optional. When it's not given,
    28  the directory is created at the root of the virtual file system.
    29  
    30  #### Query-String
    31  
    32  | Parameter  | Description                         |
    33  | ---------- | ----------------------------------- |
    34  | Type       | `directory`                         |
    35  | Name       | the directory name                  |
    36  | Tags       | an array of tags                    |
    37  | CreatedAt  | the creation date                   |
    38  | MetadataID | the identifier of a metadata object |
    39  
    40  #### HTTP headers
    41  
    42  | Parameter | Description                            |
    43  | --------- | -------------------------------------- |
    44  | Date      | The modification date of the directory |
    45  
    46  #### Request
    47  
    48  ```http
    49  POST /files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81?Type=directory&Name=phone&Tags=bills,konnectors HTTP/1.1
    50  Accept: application/vnd.api+json
    51  Date: Mon, 19 Sep 2016 12:35:08 GMT
    52  ```
    53  
    54  #### Status codes
    55  
    56  - 201 Created, when the directory has been successfully created
    57  - 404 Not Found, when the parent directory does not exist
    58  - 409 Conflict, when a directory with the same name already exists
    59  - 422 Unprocessable Entity, when the `Type`, `Name`, or `MetadataID` parameter
    60    is missing or invalid
    61  
    62  #### Response
    63  
    64  ```http
    65  HTTP/1.1 201 Created
    66  Content-Type: application/vnd.api+json
    67  Location: https://cozy.example.com/files/6494e0ac-dfcb-11e5-88c1-472e84a9cbee
    68  ```
    69  
    70  ```json
    71  {
    72    "data": {
    73      "type": "io.cozy.files",
    74      "id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
    75      "meta": {
    76        "rev": "1-ff3beeb456eb"
    77      },
    78      "attributes": {
    79        "type": "directory",
    80        "name": "phone",
    81        "path": "/Documents/phone",
    82        "created_at": "2016-09-19T12:35:08Z",
    83        "updated_at": "2016-09-19T12:35:08Z",
    84        "tags": ["bills", "konnectors"],
    85        "cozyMetadata": {
    86          "doctypeVersion": "1",
    87          "metadataVersion": 1,
    88          "createdAt": "2016-09-20T18:32:48Z",
    89          "createdByApp": "drive",
    90          "createdOn": "https://cozy.example.com/",
    91          "updatedAt": "2016-09-20T18:32:48Z"
    92        }
    93      },
    94      "relationships": {
    95        "parent": {
    96          "links": {
    97            "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
    98          },
    99          "data": {
   100            "type": "io.cozy.files",
   101            "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   102          }
   103        },
   104        "not_synchronized_on": {
   105          "links": {
   106            "self": "/files/6494e0ac-dfcb-11e5-88c1-472e84a9cbee/relationships/not_synchronized_on"
   107          },
   108          "data": [
   109            {
   110              "type": "io.cozy.oauth.clients",
   111              "id": "653dfdb0-0595-0139-92df-543d7eb8149c"
   112            }
   113          ]
   114        }
   115      },
   116      "links": {
   117        "self": "/files/6494e0ac-dfcb-11e5-88c1-472e84a9cbee"
   118      }
   119    }
   120  }
   121  ```
   122  
   123  **Note**: see [not synchronized directories](not-synchronized-vfs.md) for
   124  more informations about the `not_synchronized_on` field.
   125  
   126  ### POST /files/shared-drives
   127  
   128  This endpoint returns the information about the Shared Drives directory. If the
   129  directory does not exist, it is created.
   130  
   131  #### Request
   132  
   133  ```http
   134  POST /files/shared-drives
   135  Accept: application/vnd.api+json
   136  ```
   137  
   138  #### Response
   139  
   140  ```http
   141  HTTP/1.1 201 Created
   142  Content-Type: application/vnd.api+json
   143  ```
   144  
   145  ```json
   146  {
   147    "data": {
   148      "type": "io.cozy.files",
   149      "id": "io.cozy.files.shared-drives-dir",
   150      "meta": {
   151        "rev": "1-e4abdb5a"
   152      },
   153      "attributes": {
   154        "type": "directory",
   155        "name": "Shared drives",
   156        "path": "/Shared drives",
   157        "created_at": "2024-03-25T15:22:00Z",
   158        "updated_at": "2024-03-25T15:22:00Z",
   159        "cozyMetadata": {
   160          "doctypeVersion": "1",
   161          "metadataVersion": 1,
   162          "createdAt": "2024-03-25T15:22:00Z",
   163          "createdByApp": "drive",
   164          "createdOn": "https://cozy.example.com/",
   165          "updatedAt": "2024-03-25T15:22:00Z"
   166        }
   167      },
   168      "relationships": {
   169        "parent": {
   170          "links": {
   171            "related": "/files/io.cozy.files.root-dir"
   172          },
   173          "data": {
   174            "type": "io.cozy.files",
   175            "id": "io.cozy.files.root-dir"
   176          }
   177        }
   178      },
   179      "links": {
   180        "self": "/files/io.cozy.files.shared-drives-dir"
   181      }
   182    }
   183  }
   184  ```
   185  
   186  ### GET /files/:file-id
   187  
   188  Get a directory or a file informations. In the case of a directory, it contains
   189  the list of files and sub-directories inside it. For a note, its images are
   190  included.
   191  
   192  Contents is paginated following [jsonapi conventions](./http-api.md#pagination).
   193  The default limit is 30 entries.
   194  
   195  #### Request
   196  
   197  ```http
   198  GET /files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81 HTTP/1.1
   199  Accept: application/vnd.api+json
   200  ```
   201  
   202  #### Response
   203  
   204  ```http
   205  HTTP/1.1 200 OK
   206  Content-Type: application/vnd.api+json
   207  ```
   208  
   209  ```json
   210  {
   211    "links": {
   212      "next": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81?page[cursor]=9152d568-7e7c-11e6-a377-37cbfb190b4b"
   213    },
   214    "data": {
   215      "type": "io.cozy.files",
   216      "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81",
   217      "meta": {
   218        "rev": "1-e36ab092"
   219      },
   220      "attributes": {
   221        "type": "directory",
   222        "name": "Documents",
   223        "path": "/Documents",
   224        "created_at": "2016-09-19T12:35:00Z",
   225        "updated_at": "2016-09-19T12:35:00Z",
   226        "tags": [],
   227        "cozyMetadata": {
   228          "doctypeVersion": "1",
   229          "metadataVersion": 1,
   230          "createdAt": "2016-09-20T18:32:47Z",
   231          "createdByApp": "drive",
   232          "createdOn": "https://cozy.example.com/",
   233          "updatedAt": "2016-09-20T18:32:47Z"
   234        }
   235      },
   236      "relationships": {
   237        "contents": {
   238          "data": [
   239            {
   240              "type": "io.cozy.files",
   241              "id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee"
   242            },
   243            {
   244              "type": "io.cozy.files",
   245              "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b"
   246            }
   247          ]
   248        }
   249      },
   250      "links": {
   251        "self": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   252      }
   253    },
   254    "included": [
   255      {
   256        "type": "io.cozy.files",
   257        "id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
   258        "meta": {
   259          "rev": "1-ff3beeb456eb"
   260        },
   261        "attributes": {
   262          "type": "directory",
   263          "name": "phone",
   264          "path": "/Documents/phone",
   265          "created_at": "2016-09-19T12:35:08Z",
   266          "updated_at": "2016-09-19T12:35:08Z",
   267          "tags": ["bills", "konnectors"],
   268          "cozyMetadata": {
   269            "doctypeVersion": "1",
   270            "metadataVersion": 1,
   271            "createdAt": "2016-09-20T18:32:47Z",
   272            "createdByApp": "drive",
   273            "createdOn": "https://cozy.example.com/",
   274            "updatedAt": "2016-09-20T18:32:47Z"
   275          }
   276        },
   277        "relationships": {
   278          "parent": {
   279            "links": {
   280              "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   281            },
   282            "data": {
   283              "type": "io.cozy.files",
   284              "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   285            }
   286          }
   287        },
   288        "links": {
   289          "self": "/files/6494e0ac-dfcb-11e5-88c1-472e84a9cbee"
   290        }
   291      },
   292      {
   293        "type": "io.cozy.files",
   294        "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
   295        "meta": {
   296          "rev": "1-0e6d5b72"
   297        },
   298        "attributes": {
   299          "type": "file",
   300          "name": "hello.txt",
   301          "trashed": false,
   302          "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=",
   303          "created_at": "2016-09-19T12:38:04Z",
   304          "updated_at": "2016-09-19T12:38:04Z",
   305          "tags": [],
   306          "size": 12,
   307          "executable": false,
   308          "class": "document",
   309          "mime": "text/plain",
   310          "cozyMetadata": {
   311            "doctypeVersion": "1",
   312            "metadataVersion": 1,
   313            "createdAt": "2016-09-20T18:32:49Z",
   314            "createdByApp": "drive",
   315            "createdOn": "https://cozy.example.com/",
   316            "updatedAt": "2016-09-20T18:32:49Z",
   317            "uploadedAt": "2016-09-20T18:32:49Z",
   318            "uploadedOn": "https://cozy.example.com/",
   319            "uploadedBy": {
   320              "slug": "drive"
   321            }
   322          }
   323        },
   324        "relationships": {
   325          "parent": {
   326            "links": {
   327              "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   328            },
   329            "data": {
   330              "type": "io.cozy.files",
   331              "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   332            }
   333          }
   334        },
   335        "links": {
   336          "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b"
   337        }
   338      }
   339    ]
   340  }
   341  ```
   342  
   343  ### GET /files/:file-id/size
   344  
   345  This endpoint returns the size taken by the files in a directory, including
   346  those in subdirectories.
   347  
   348  #### Request
   349  
   350  ```http
   351  GET /files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81/size HTTP/1.1
   352  Accept: application/vnd.api+json
   353  ```
   354  
   355  #### Response
   356  
   357  ```http
   358  HTTP/1.1 200 OK
   359  Content-Type: application/vnd.api+json
   360  ```
   361  
   362  ```json
   363  {
   364    "data": {
   365      "type": "io.cozy.files.sizes",
   366      "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81",
   367      "attributes": {
   368        "size": "1234567890"
   369      },
   370      "meta": {}
   371    }
   372  }
   373  ```
   374  
   375  ### GET `/files/_changes`
   376  
   377  This endpoint is similar to the changes feed of CouchDB for io.cozy.files.
   378  There are a few specificities:
   379  
   380  - it is wrapped in the VFS lock to avoid seeing inconsistent results
   381  - it automatically skips design docs
   382  - if the requests is coming from an OAuth client, it excludes the files and directories that are in a not synchronized folder
   383  - it only supports the options `since`, `limit`, and `include_docs` of CouchDB
   384  - it has an option `fields` to only include those fields in the results
   385  - it has an option `include_file_path` to add the `path` for files
   386  - it has two options `skip_deleted` and `skip_trashed` to not send to the client the deleted/trashed files and directories.
   387  
   388  ### Request
   389  
   390  ```http
   391  GET /files/_changes?include_docs=true&fields=type,name,dir_id&skip_deleted=true&limit=3 HTTP/1.1
   392  ```
   393  
   394  ### Response
   395  
   396  ```http
   397  HTTP/1.1 200 OK
   398  Content-Type: application/json
   399  ```
   400  
   401  ```json
   402  {
   403    "last_seq": "13-g1AAAABHeJzLYWBgYMxgTmHgzcvPy09JdcjLz8gvLskBCjMlMuSxMPwHgqwM5kTeXKAQe5Jpmrl5ojG68iwA2MMV1A",
   404    "pending": 24,
   405    "results": [
   406      {
   407        "id": "io.cozy.files.root-dir",
   408        "seq": "11-g1AAAABHeJzLYWBgYMxgTmHgzcvPy09JdcjLz8gvLskBCjMlMuSxMPwHgqwM5kTuXKAQe5Jpmrl5ojG68iwA2IcV0g",
   409        "doc": {
   410          "type": "directory"
   411        },
   412        "changes": [
   413          {
   414            "rev": "1-077f26acac6f0a5e1022f109e8d1dfc4"
   415          }
   416        ]
   417      },
   418      {
   419        "id": "io.cozy.files.trash-dir",
   420        "seq": "12-g1AAAABHeJzLYWBgYMxgTmHgzcvPy09JdcjLz8gvLskBCjMlMuSxMPwHgqwM5kSeXKAQe5Jpmrl5ojG68iwA2KUV0w",
   421        "doc": {
   422          "dir_id": "io.cozy.files.root-dir",
   423          "name": ".cozy_trash",
   424          "type": "directory"
   425        },
   426        "changes": [
   427          {
   428            "rev": "1-de9c11dbc386b5f91adbe2aee4a3e754"
   429          }
   430        ]
   431      },
   432      {
   433        "id": "d30b0dd6e0e8fefdac2a94cb2c00249f",
   434        "seq": "13-g1AAAABHeJzLYWBgYMxgTmHgzcvPy09JdcjLz8gvLskBCjMlMuSxMPwHgqwM5kTeXKAQe5Jpmrl5ojG68iwA2MMV1A",
   435        "doc": {
   436          "dir_id": "io.cozy.files.root-dir",
   437          "name": "Administratif",
   438          "type": "directory"
   439        },
   440        "changes": [
   441          {
   442            "rev": "1-24f2828e8dbe64135913072a4c92d846"
   443          }
   444        ]
   445      }
   446    ]
   447  }
   448  ```
   449  
   450  ### POST `/files/_find`
   451  
   452  Find allows to find documents using a mango selector. You can read more about mango selectors [here](http://docs.couchdb.org/en/stable/api/database/find.html#selector-syntax).
   453  
   454  Note that it returns a
   455  [bookmark](https://github.com/cozy/cozy-stack/blob/master/docs/mango.md#pagination-cookbook)
   456  in the `links`, useful to paginate (following the [JSON-API
   457  pagination](./http-api.md#pagination)). On the last page, there won't be a
   458  `links.next`.
   459  
   460  It is possible to pass a `execution_stats` parameter to get some information about the query execution. See [here](https://docs.couchdb.org/en/stable/api/database/find.html#execution-statistics) for more details.
   461  
   462  ### Request
   463  
   464  ```http
   465  POST /files/_find HTTP/1.1
   466  ```
   467  
   468  
   469  ```json
   470  {
   471      "selector": {
   472          "class": "image",
   473          "trashed": false
   474      },
   475      "limit": 2,
   476      "bookmark": "g1AAAABjeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorpFokG5qaGVqYmCWbGxuYGFkYWhgkmqaZJZsZGpibWhiA9HHA9OWATAJpY83MTUxPTWFgTUvMKU7NygIA7IYZzA",
   477      "use_index": "_design/a5f4711fc9448864a13c81dc71e660b524d7410c",
   478      "execution_stats": true
   479  }
   480  ```
   481  
   482  ### Response
   483  
   484  ```http
   485  HTTP/1.1 200 OK
   486  Date: Mon, 27 Sept 2016 12:28:53 GMT
   487  Content-Length: ...
   488  Content-Type: application/json
   489  ```
   490  
   491  ```json
   492  {
   493    "data": [
   494      {
   495        "type": "io.cozy.files",
   496        "id": "e8c1561846c730428180a5f6c6107914",
   497        "attributes": {
   498          "type": "file",
   499          "name": "nicepic1.jpg",
   500          "dir_id": "f49b4087cbf946dfc759214394009a6c",
   501          "created_at": "2020-02-13T16:35:47.568155477+01:00",
   502          "updated_at": "2020-02-13T16:35:47.568155477+01:00",
   503          "size": "345385",
   504          "md5sum": "12cGYwT+RiNjFxf4f7AmzQ==",
   505          "mime": "image/jpeg",
   506          "class": "image",
   507          "executable": false,
   508          "trashed": false,
   509          "tags": [],
   510          "path": "/Pictures/nicepic1.jpg",
   511          "metadata": {
   512            "datetime": "2020-02-13T16:35:47.568155477+01:00",
   513            "extractor_version": 2,
   514            "height": 1080,
   515            "width": 1920
   516          }
   517        },
   518        "meta": {
   519          "rev": "2-235e715b1d82a93285be1b0bd691b779"
   520        },
   521        "links": {
   522          "self": "/files/e8c1561846c730428180a5f6c6107914",
   523          "tiny": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/tiny",
   524          "small": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/small",
   525          "medium": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/medium",
   526          "large": "/files/e8c1561846c730428180a5f6c6107914/thumbnails/377327a8e20d6a50/large"
   527        },
   528        "relationships": {
   529          "parent": {
   530            "links": {
   531              "related": "/files/f49b4087cbf946dfc759214394009a6c"
   532            },
   533            "data": {
   534              "id": "f49b4087cbf946dfc759214394009a6c",
   535              "type": "io.cozy.files"
   536            }
   537          }
   538        }
   539      },
   540      {
   541        "type": "io.cozy.files",
   542        "id": "e8c1561846c730428180a5f6c6109007",
   543        "attributes": {
   544          "type": "file",
   545          "name": "nicepic2.jpg",
   546          "dir_id": "f49b4087cbf946dfc759214394009a6c",
   547          "created_at": "2020-02-13T16:35:47.845049743+01:00",
   548          "updated_at": "2020-02-13T16:35:47.845049743+01:00",
   549          "size": "323009",
   550          "md5sum": "Fla3ucNXuW2Xw/TK8pfsPA==",
   551          "mime": "image/jpeg",
   552          "class": "image",
   553          "executable": false,
   554          "trashed": false,
   555          "tags": [],
   556          "path": "/Pictures/nicepic2.jpg",
   557          "metadata": {
   558            "datetime": "2020-02-13T16:35:47.845049743+01:00",
   559            "extractor_version": 2,
   560            "height": 1080,
   561            "width": 1920
   562          }
   563        },
   564        "meta": {
   565          "rev": "2-4883d6b8ccad32f8fb056af9b7f8b37f"
   566        },
   567        "links": {
   568          "self": "/files/e8c1561846c730428180a5f6c6109007",
   569          "tiny": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/tiny",
   570          "small": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/small",
   571          "medium": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/medium",
   572          "large": "/files/e8c1561846c730428180a5f6c6109007/thumbnails/58a4aea31b00c99d/large"
   573        },
   574        "relationships": {
   575          "parent": {
   576            "links": {
   577              "related": "/files/f49b4087cbf946dfc759214394009a6c"
   578            },
   579            "data": {
   580              "id": "f49b4087cbf946dfc759214394009a6c",
   581              "type": "io.cozy.files"
   582            }
   583          }
   584        }
   585      }
   586    ],
   587    "links": {
   588      "next": "/files/_find?page[cursor]=g1AAAABjeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorpFokG5qaGVqYmCWbGxuYGFkYWhgkmqaZJZsZGlgaGJiD9HHA9OWATAJpY83MTUxPTWFgTUvMKU7NygIA694ZyA"
   589    },
   590    "meta": {
   591      "count": 2,
   592      "execution_stats": {
   593        "total_docs_examined": 11,
   594        "results_returned": 2,
   595        "execution_time_ms": 8.833
   596      }
   597    }
   598  }
   599  ```
   600  
   601  
   602  ### DELETE /files/:dir-id
   603  
   604  Put a directory and its subtree in the trash. It requires the permissions on
   605  `io.cozy.files` for `PATCH`.
   606  
   607  #### HTTP headers
   608  
   609  It's possible to send the `If-Match` header, with the previous revision of the
   610  file/directory (optional).
   611  
   612  ## Files
   613  
   614  A file is a binary content with some metadata.
   615  
   616  ### POST /files/:dir-id
   617  
   618  Upload a file in the directory identified by `:dir-id`.
   619  
   620  The `created_at` field will be the first valid value in this list:
   621  
   622  - the datetime extracted from the EXIF for a photo
   623  - the `CreatedAt` parameter from the query-string
   624  - the `Date` HTTP header
   625  - the current time from the server.
   626  
   627  The `updated_at` field will be the first value in this list:
   628  
   629  - the datetime extracted from the EXIF for a photo if it is greater than the other values
   630  - the `UpdatedAt` parameter from the query-string
   631  - the `Date` HTTP header
   632  - the current time from the server.
   633  
   634  /!\ If the `updated_at` field is older than the `created_at` one,
   635  then the `updated_at` will be set with the value of the `created_at`.
   636  
   637  #### Query-String
   638  
   639  | Parameter               | Description                                                    |
   640  | ----------------------- | -------------------------------------------------------------- |
   641  | Type                    | `file`                                                         |
   642  | Name                    | the file name                                                  |
   643  | Size                    | the file size (when `Content-Length` can't be used)            |
   644  | Tags                    | an array of tags                                               |
   645  | Executable              | `true` if the file is executable (UNIX permission)             |
   646  | Encrypted               | `true` if the file is client-side encrypted                    |
   647  | Metadata                | a JSON with metadata on this file (_not recommended_)          |
   648  | MetadataID              | the identifier of a metadata object                            |
   649  | CreatedAt               | the creation date of the file                                  |
   650  | UpdatedAt               | the modification date of the file                              |
   651  | SourceAccount           | the id of the source account used by a konnector               |
   652  | SourceAccountIdentifier | the unique identifier of the account targeted by the connector |
   653  
   654  #### HTTP headers
   655  
   656  | Parameter      | Description                                 |
   657  | -------------- | ------------------------------------------- |
   658  | Content-Length | The file size                               |
   659  | Content-MD5    | A Base64-encoded binary MD5 sum of the file |
   660  | Content-Type   | The mime-type of the file                   |
   661  | Date           | The modification date of the file           |
   662  
   663  #### Request
   664  
   665  ```http
   666  POST /files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81?Type=file&Name=hello.txt&CreatedAt=2016-09-18T01:23:45Z HTTP/1.1
   667  Accept: application/vnd.api+json
   668  Content-Length: 12
   669  Content-MD5: hvsmnRkNLIX24EaM7KQqIA==
   670  Content-Type: text/plain
   671  Date: Mon, 19 Sep 2016 12:38:04 GMT
   672  Host: cozy.example.com
   673  
   674  Hello world!
   675  ```
   676  
   677  #### Status codes
   678  
   679  - 201 Created, when the file has been successfully created
   680  - 404 Not Found, when the parent directory does not exist
   681  - 409 Conflict, when a file with the same name already exists
   682  - 412 Precondition Failed, when the md5sum is `Content-MD5` is not equal to
   683    the md5sum computed by the server
   684  - 413 Payload Too Large, when there is not enough available space on the cozy
   685    to upload the file or the file is larger than the server's filesystem maximum
   686    file size
   687  - 422 Unprocessable Entity, when the sent data is invalid (for example, the
   688    parent doesn't exist, `Type`, `Name`, or `MetadataID` parameter is missing or
   689    invalid, etc.)
   690  
   691  #### Response
   692  
   693  ```http
   694  HTTP/1.1 201 Created
   695  Content-Type: application/vnd.api+json
   696  Location: https://cozy.example.com/files/9152d568-7e7c-11e6-a377-37cbfb190b4b
   697  ```
   698  
   699  ```json
   700  {
   701    "data": {
   702      "type": "io.cozy.files",
   703      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
   704      "meta": {
   705        "rev": "4-1482b88a"
   706      },
   707      "attributes": {
   708        "type": "file",
   709        "name": "sunset.jpg",
   710        "trashed": false,
   711        "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=",
   712        "created_at": "2016-09-18T20:38:04Z",
   713        "updated_at": "2016-09-21T12:38:04Z",
   714        "tags": [],
   715        "metadata": {
   716          "datetime": "2016-09-18T20:38:04Z",
   717          "height": 1080,
   718          "width": 1920
   719        },
   720        "size": 12,
   721        "executable": false,
   722        "class": "image",
   723        "mime": "image/jpg",
   724        "cozyMetadata": {
   725          "doctypeVersion": "1",
   726          "metadataVersion": 1,
   727          "createdAt": "2016-09-20T18:32:49Z",
   728          "createdByApp": "drive",
   729          "createdOn": "https://cozy.example.com/",
   730          "updatedAt": "2016-09-21T14:46:37Z",
   731          "uploadedAt": "2016-09-20T18:37:52Z",
   732          "uploadedOn": "https://cozy.example.com/",
   733          "uploadedBy": {
   734            "slug": "drive"
   735          }
   736        }
   737      },
   738      "relationships": {
   739        "parent": {
   740          "links": {
   741            "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   742          },
   743          "data": {
   744            "type": "io.cozy.files",
   745            "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
   746          }
   747        },
   748        "referenced_by": {
   749          "links": {
   750            "self": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81/relationships/references"
   751          },
   752          "data": [
   753            {
   754              "type": "io.cozy.albums",
   755              "id": "94375086-e2e2-11e6-81b9-5bc0b9dd4aa4"
   756            }
   757          ]
   758        },
   759        "old_versions": {
   760          "data": [
   761            {
   762              "type": "io.cozy.files.versions",
   763              "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b/2-fa3a3bec"
   764            },
   765            {
   766              "type": "io.cozy.files.versions",
   767              "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b/1-0e6d5b72"
   768            }
   769          ]
   770        }
   771      },
   772      "links": {
   773        "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b",
   774        "tiny": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/0f9cda56674282ac/tiny",
   775        "small": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/0f9cda56674282ac/small",
   776        "medium": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/0f9cda56674282ac/medium",
   777        "large": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/0f9cda56674282ac/large"
   778      }
   779    },
   780    "included": [
   781      {
   782        "type": "io.cozy.files.versions",
   783        "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b/2-fa3a3bec",
   784        "meta": {
   785          "rev": "1-26a331"
   786        },
   787        "attributes": {
   788          "file_id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
   789          "updated_at": "2016-09-21T10:11:12Z",
   790          "md5sum": "a2lth5syMW+4r7jwNhdk3A==",
   791          "size": 123456,
   792          "tags": [],
   793          "cozyMetadata": {
   794            "doctypeVersion": "1",
   795            "metadataVersion": 1,
   796            "createdAt": "2016-09-20T18:37:52Z",
   797            "createdByApp": "drive",
   798            "createdOn": "https://cozy.example.com/",
   799            "updatedAt": "2016-09-20T18:37:52Z",
   800            "uploadedAt": "2016-09-20T18:37:52Z",
   801            "uploadedOn": "https://cozy.example.com/",
   802            "uploadedBy": {
   803              "slug": "drive"
   804            }
   805          }
   806        }
   807      },
   808      {
   809        "type": "io.cozy.files.versions",
   810        "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b/1-0e6d5b72",
   811        "meta": {
   812          "rev": "1-57b3e2"
   813        },
   814        "attributes": {
   815          "file_id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
   816          "updated_at": "2016-09-18T20:38:04Z",
   817          "md5sum": "FBA89XXOZKFhdv37iILb2Q==",
   818          "size": 159753,
   819          "tags": [],
   820          "cozyMetadata": {
   821            "doctypeVersion": "1",
   822            "metadataVersion": 1,
   823            "createdAt": "2016-09-20T18:32:49Z",
   824            "createdByApp": "drive",
   825            "createdOn": "https://cozy.example.com/",
   826            "updatedAt": "2016-09-20T18:32:49Z",
   827            "uploadedAt": "2016-09-20T18:32:49Z",
   828            "uploadedOn": "https://cozy.example.com/",
   829            "uploadedBy": {
   830              "slug": "drive"
   831            }
   832          }
   833        }
   834      }
   835    ]
   836  }
   837  ```
   838  
   839  **Note**: see [references of documents in VFS](references-docs-in-vfs.md) for
   840  more informations about the references field.
   841  
   842  ### POST /files/upload/metadata
   843  
   844  Send a metadata object that can be associated to a file (or directory) uploaded
   845  after that, via the `MetadataID` query parameter. The `MetadataID` parameter is
   846  only valid for 10 minutes, and will expire after that.
   847  
   848  **Note:** a special permission on `io.cozy.certified.carbon_copy` is required
   849  to send a request with `carbonCopy` as key in the `attributes` map. Same for
   850  `electronicSafe`.
   851  
   852  See the [metadata doctype](https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.files_metadata/) to know more about metadata attributes that can be set, notably for images and document qualification.
   853  
   854  #### Request
   855  
   856  ```http
   857  POST /files/upload/metadata HTTP/1.1
   858  Content-Type: application/vnd.api+json
   859  ```
   860  
   861  ```json
   862  {
   863    "data": {
   864      "type": "io.cozy.files.metadata",
   865      "attributes": {
   866        "qualification": {
   867          "label": "telecom_invoice",
   868          "purpose": "invoice",
   869          "sourceCategory": "telecom"
   870        },
   871        "datetime": "2017-04-22T01:00:00-05:00"
   872      }
   873    }
   874  }
   875  ```
   876  
   877  #### Response
   878  
   879  ```http
   880  HTTP/1.1 201 Created
   881  Content-Type: application/vnd.api+json
   882  ```
   883  
   884  ```json
   885  {
   886    "data": {
   887      "type": "io.cozy.files.metadata",
   888      "id": "42E6BD48",
   889      "attributes": {
   890        "qualification": {
   891          "label": "telecom_invoice",
   892          "purpose": "invoice",
   893          "sourceCategory": "telecom"
   894        },
   895        "datetime": "2017-04-22T01:00:00-05:00"
   896      }
   897    }
   898  }
   899  ```
   900  
   901  ### GET /files/download/:file-id
   902  
   903  Download the file content.
   904  
   905  By default the `content-disposition` will be `inline`, but it will be
   906  `attachment` if the query string contains the parameter `Dl=1`
   907  
   908  #### Request
   909  
   910  ```http
   911  GET /files/download/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81 HTTP/1.1
   912  ```
   913  
   914  #### Response
   915  
   916  ```http
   917  HTTP/1.1 200 OK
   918  Content-Length: 12
   919  Content-Disposition: inline; filename="hello.txt"
   920  Content-Type: text/plain
   921  
   922  Hello world!
   923  ```
   924  
   925  ### GET /files/download
   926  
   927  Download the file content from its path.
   928  
   929  By default the `content-disposition` will be `inline`, but it will be
   930  `attachment` if the query string contains the parameter `Dl=1`
   931  
   932  #### Request
   933  
   934  ```http
   935  GET /files/download?Path=/Documents/hello.txt&Dl=1 HTTP/1.1
   936  ```
   937  
   938  ### GET /files/:file-id/icon/:secret
   939  
   940  Get an image that shows the first page of a PDF in a small resolution (96x96).
   941  
   942  **Note:** this route is deprecated, you should use thumbnails instead.
   943  
   944  ### GET /files/:file-id/preview/:secret
   945  
   946  Get an image that shows the first page of a PDF (at most 1080x1920).
   947  
   948  **Note:** this route is deprecated, you should use thumbnails instead.
   949  
   950  ### GET /files/:file-id/thumbnails/:secret/:format
   951  
   952  Get a thumbnail of a file (for an image & pdf only). `:format` can be `tiny` (96x96)
   953  `small` (640x480), `medium` (1280x720), or `large` (1920x1080).
   954  
   955  This API does not require authentication because the secret acts as a token. 
   956  This secret is valid for 10 minutes, after which the link will return an error. 
   957  To retrieve a new functional link, you must query the files API again to obtain
   958  a new secret.
   959  
   960  ### PUT /files/:file-id
   961  
   962  Overwrite a file
   963  
   964  The `updated_at` field will be the first value in this list:
   965  
   966  - the datetime extracted from the EXIF for a photo if it is greater than the other values
   967  - the `UpdatedAt` parameter from the query-string
   968  - the `Date` HTTP header
   969  - the current time from the server.
   970  
   971  /!\ If the `updated_at` field is older than the `created_at` one, then the
   972  `updated_at` will be set with the value of the `created_at`.
   973  
   974  #### Query-String
   975  
   976  | Parameter               | Description                                                    |
   977  | ----------------------- | -------------------------------------------------------------- |
   978  | Size                    | the file size (when `Content-Length` can't be used)            |
   979  | Tags                    | an array of tags                                               |
   980  | Executable              | `true` if the file is executable (UNIX permission)             |
   981  | Encrypted               | `true` if the file is client-side encrypted                    |
   982  | MetadataID              | the identifier of a metadata object                            |
   983  | UpdatedAt               | the modification date of the file                              |
   984  | SourceAccount           | the id of the source account used by a konnector               |
   985  | SourceAccountIdentifier | the unique identifier of the account targeted by the connector |
   986  
   987  #### HTTP headers
   988  
   989  The HTTP headers are the same than for uploading a file. There is one additional
   990  header, `If-Match`, with the previous revision of the file (optional).
   991  
   992  #### Request
   993  
   994  ```http
   995  PUT /files/9152d568-7e7c-11e6-a377-37cbfb190b4b HTTP/1.1
   996  Accept: application/vnd.api+json
   997  Content-Length: 12
   998  Content-MD5: hvsmnRkNLIX24EaM7KQqIA==
   999  Content-Type: text/plain
  1000  If-Match: 1-0e6d5b72
  1001  
  1002  HELLO WORLD!
  1003  ```
  1004  
  1005  #### Status codes
  1006  
  1007  - 200 OK, when the file has been successfully overwritten
  1008  - 404 Not Found, when the file wasn't existing
  1009  - 412 Precondition Failed, when the `If-Match` header is set and doesn't match
  1010    the last revision of the file
  1011  - 413 Payload Too Large, when there is not enough available space on the cozy
  1012    to upload the file or the file is larger than the server's filesystem maximum
  1013    file size
  1014  - 422 Unprocessable Entity, when the sent data is invalid (for example, the
  1015    `MetadataID` parameter has expired)
  1016  
  1017  #### Response
  1018  
  1019  ```http
  1020  HTTP/1.1 200 OK
  1021  Content-Type: application/vnd.api+json
  1022  ```
  1023  
  1024  ```json
  1025  {
  1026    "data": {
  1027      "type": "io.cozy.files",
  1028      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1029      "meta": {
  1030        "rev": "2-d903b54c"
  1031      },
  1032      "attributes": {
  1033        "type": "file",
  1034        "name": "hello.pdf",
  1035        "trashed": false,
  1036        "md5sum": "YjU5YmMzN2Q2NDQxZDk2Nwo=",
  1037        "created_at": "2016-09-19T12:38:04Z",
  1038        "updated_at": "2016-09-19T12:38:04Z",
  1039        "tags": [],
  1040        "size": 12,
  1041        "executable": false,
  1042        "class": "pdf",
  1043        "mime": "application/pdf",
  1044        "cozyMetadata": {
  1045          "doctypeVersion": "1",
  1046          "metadataVersion": 1,
  1047          "createdAt": "2016-09-20T18:32:49Z",
  1048          "createdByApp": "drive",
  1049          "createdOn": "https://cozy.example.com/",
  1050          "updatedAt": "2016-09-21T04:27:50Z",
  1051          "uploadedAt": "2016-09-21T04:27:50Z",
  1052          "uploadedOn": "https://cozy.example.com/",
  1053          "uploadedBy": {
  1054            "slug": "drive"
  1055          }
  1056        }
  1057      },
  1058      "relationships": {
  1059        "parent": {
  1060          "links": {
  1061            "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1062          },
  1063          "data": {
  1064            "type": "io.cozy.files",
  1065            "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1066          }
  1067        }
  1068      },
  1069      "links": {
  1070        "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1071        "icon": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/icon/543d7eb8",
  1072        "preview": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/preview/77e117e0",
  1073        "tiny": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/93fd0a5d96b22e9d/tiny",
  1074        "small": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/93fd0a5d96b22e9d/small",
  1075        "medium": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/93fd0a5d96b22e9d/medium",
  1076        "large": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b/thumbnails/93fd0a5d96b22e9d/large"
  1077      }
  1078    }
  1079  }
  1080  ```
  1081  
  1082  ### POST /files/:file-id/copy
  1083  
  1084  Create a copy of a file in the same directory with a copy suffix in its name
  1085  
  1086  #### Query-String
  1087  
  1088  | Parameter  | Description                                        |
  1089  | ---------- | -------------------------------------------------- |
  1090  | Name       | the file copy name (optional)                      |
  1091  | DirID      | the destination directory id (optional)            |
  1092  
  1093  #### Request
  1094  
  1095  ```http
  1096  POST /files/9152d568-7e7c-11e6-a377-37cbfb190b4b/copy HTTP/1.1
  1097  Accept: application/vnd.api+json
  1098  ```
  1099  
  1100  #### Status codes
  1101  
  1102  - 201 Created, when the file has been successfully copied
  1103  - 404 Not Found, when the file does not exist
  1104  - 409 Conflict, when a file with the same name as the copy would have already exists
  1105  - 413 Payload Too Large, when there is not enough available space on the cozy
  1106    to copy the file
  1107  
  1108  #### Response
  1109  
  1110  ```http
  1111  HTTP/1.1 201 Created
  1112  Content-Type: application/vnd.api+json
  1113  ```
  1114  
  1115  ```json
  1116  {
  1117    "data": {
  1118      "type": "io.cozy.files",
  1119      "id": "7382f28a-21d4-12d9-4438-3fd53e98a219",
  1120      "meta": {
  1121        "rev": "1-83a82e9"
  1122      },
  1123      "attributes": {
  1124        "type": "file",
  1125        "name": "hello (copy).pdf",
  1126        "trashed": false,
  1127        "md5sum": "YjU5YmMzN2Q2NDQxZDk2Nwo=",
  1128        "created_at": "2022-10-18T18:33:24Z",
  1129        "updated_at": "2022-10-18T18:33:24Z",
  1130        "tags": [],
  1131        "size": 12,
  1132        "executable": false,
  1133        "class": "pdf",
  1134        "mime": "application/pdf",
  1135        "cozyMetadata": {
  1136          "doctypeVersion": "1",
  1137          "metadataVersion": 1,
  1138          "createdAt": "2022-10-18T18:33:24Z",
  1139          "createdByApp": "drive",
  1140          "createdOn": "https://cozy.example.com/",
  1141          "updatedAt": "2022-10-18T18:33:24Z"
  1142        }
  1143      },
  1144      "relationships": {
  1145        "parent": {
  1146          "links": {
  1147            "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1148          },
  1149          "data": {
  1150            "type": "io.cozy.files",
  1151            "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1152          }
  1153        }
  1154      },
  1155      "links": {
  1156        "self": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219",
  1157        "icon": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/icon/543d7eb8",
  1158        "preview": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/preview/77e117e0",
  1159        "tiny": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/thumbnails/93fd0a5d96b22e9d/tiny",
  1160        "small": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/thumbnails/93fd0a5d96b22e9d/small",
  1161        "medium": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/thumbnails/93fd0a5d96b22e9d/medium",
  1162        "large": "/files/7382f28a-21d4-12d9-4438-3fd53e98a219/thumbnails/93fd0a5d96b22e9d/large"
  1163      }
  1164    }
  1165  }
  1166  ```
  1167  
  1168  ### DELETE /files/:file-id
  1169  
  1170  Put a file in the trash.
  1171  
  1172  ## Common
  1173  
  1174  ### GET /files/metadata
  1175  
  1176  Same as `/files/:file-id` but to retrieve informations from a path.
  1177  
  1178  #### Request
  1179  
  1180  ```http
  1181  GET /files/metadata?Path=/Documents/hello.txt HTTP/1.1
  1182  ```
  1183  
  1184  #### Response
  1185  
  1186  ```http
  1187  HTTP/1.1 200 OK
  1188  Content-Type: application/vnd.api+json
  1189  Location: https://cozy.example.com/files/9152d568-7e7c-11e6-a377-37cbfb190b4b
  1190  ```
  1191  
  1192  ```json
  1193  {
  1194    "data": {
  1195      "type": "io.cozy.files",
  1196      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1197      "meta": {
  1198        "rev": "1-0e6d5b72"
  1199      },
  1200      "attributes": {
  1201        "type": "file",
  1202        "name": "hello.txt",
  1203        "trashed": false,
  1204        "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=",
  1205        "created_at": "2016-09-19T12:38:04Z",
  1206        "updated_at": "2016-09-19T12:38:04Z",
  1207        "tags": [],
  1208        "size": 12,
  1209        "executable": false,
  1210        "class": "document",
  1211        "mime": "text/plain",
  1212        "cozyMetadata": {
  1213          "doctypeVersion": "1",
  1214          "metadataVersion": 1,
  1215          "createdAt": "2016-09-20T18:32:49Z",
  1216          "createdByApp": "drive",
  1217          "createdOn": "https://cozy.example.com/",
  1218          "updatedAt": "2016-09-20T18:32:49Z",
  1219          "uploadedAt": "2016-09-20T18:32:49Z",
  1220          "uploadedOn": "https://cozy.example.com/",
  1221          "uploadedBy": {
  1222            "slug": "drive"
  1223          }
  1224        }
  1225      },
  1226      "relationships": {
  1227        "parent": {
  1228          "links": {
  1229            "related": "/files/fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1230          },
  1231          "data": {
  1232            "type": "io.cozy.files",
  1233            "id": "fce1a6c0-dfc5-11e5-8d1a-1f854d4aaf81"
  1234          }
  1235        }
  1236      },
  1237      "links": {
  1238        "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b"
  1239      }
  1240    }
  1241  }
  1242  ```
  1243  
  1244  ### PATCH /files/:file-id and PATCH /files/metadata
  1245  
  1246  Both endpoints can be used to update the metadata of a file or directory, or to
  1247  rename/move it. The difference is the first one uses an id to identify the
  1248  file/directory to update, and the second one uses the path.
  1249  
  1250  Some specific attributes of the patch can be used:
  1251  
  1252  - `dir_id` attribute can be updated to move a file or directory
  1253  - `move_to_trash` boolean to specify that the file needs to be moved to the
  1254    trash
  1255  - `permanent_delete` boolean to specify that the files needs to be deleted
  1256    (after being trashed)
  1257  - `cozyMetadata.favorite` boolean attribute to put/remove a file from the
  1258    favorites
  1259  
  1260  #### HTTP headers
  1261  
  1262  It's possible to send the `If-Match` header, with the previous revision of the
  1263  file/directory (optional).
  1264  
  1265  #### Request
  1266  
  1267  ```http
  1268  PATCH /files/9152d568-7e7c-11e6-a377-37cbfb190b4b HTTP/1.1
  1269  Accept: application/vnd.api+json
  1270  Content-Type: application/vnd.api+json
  1271  ```
  1272  
  1273  ```json
  1274  {
  1275    "data": {
  1276      "type": "io.cozy.files",
  1277      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1278      "attributes": {
  1279        "type": "file",
  1280        "name": "hi.txt",
  1281        "dir_id": "f2f36fec-8018-11e6-abd8-8b3814d9a465",
  1282        "tags": ["poem"],
  1283        "cozyMetadata": {
  1284          "favorite": true
  1285        }
  1286      }
  1287    }
  1288  }
  1289  ```
  1290  
  1291  #### Status codes
  1292  
  1293  - 200 OK, when the file or directory metadata has been successfully updated
  1294  - 400 Bad Request, when a the directory is asked to move to one of its
  1295    sub-directories
  1296  - 404 Not Found, when the file/directory wasn't existing
  1297  - 412 Precondition Failed, when the `If-Match` header is set and doesn't match
  1298    the last revision of the file/directory
  1299  - 422 Unprocessable Entity, when the sent data is invalid (for example, the
  1300    parent doesn't exist)
  1301  
  1302  #### Response
  1303  
  1304  ```http
  1305  HTTP/1.1 200 OK
  1306  Content-Type: application/vnd.api+json
  1307  Location: https://cozy.example.com/files/9152d568-7e7c-11e6-a377-37cbfb190b4b
  1308  ```
  1309  
  1310  ```json
  1311  {
  1312    "data": {
  1313      "type": "io.cozy.files",
  1314      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1315      "meta": {
  1316        "rev": "1-0e6d5b72"
  1317      },
  1318      "attributes": {
  1319        "type": "file",
  1320        "name": "hi.txt",
  1321        "trashed": false,
  1322        "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=",
  1323        "created_at": "2016-09-19T12:38:04Z",
  1324        "updated_at": "2016-09-19T12:38:04Z",
  1325        "tags": ["poem"],
  1326        "size": 12,
  1327        "executable": false,
  1328        "class": "document",
  1329        "mime": "text/plain",
  1330        "cozyMetadata": {
  1331          "doctypeVersion": "1",
  1332          "metadataVersion": 1,
  1333          "createdAt": "2016-09-20T18:32:49Z",
  1334          "createdByApp": "drive",
  1335          "createdOn": "https://cozy.example.com/",
  1336          "updatedAt": "2016-09-22T13:32:51Z",
  1337          "uploadedAt": "2016-09-21T04:27:50Z",
  1338          "uploadedOn": "https://cozy.example.com/",
  1339          "uploadedBy": {
  1340            "slug": "drive"
  1341          }
  1342        }
  1343      },
  1344      "relationships": {
  1345        "parent": {
  1346          "links": {
  1347            "related": "/files/f2f36fec-8018-11e6-abd8-8b3814d9a465"
  1348          },
  1349          "data": {
  1350            "type": "io.cozy.files",
  1351            "id": "f2f36fec-8018-11e6-abd8-8b3814d9a465"
  1352          }
  1353        }
  1354      },
  1355      "links": {
  1356        "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b"
  1357      }
  1358    }
  1359  }
  1360  ```
  1361  
  1362  ### PATCH /files/
  1363  
  1364  Endpoint to update the metadata of files and directories in batch. It can be
  1365  used, for instance, to move many files in a single request.
  1366  
  1367  #### Request
  1368  
  1369  ```http
  1370  PATCH /files/ HTTP/1.1
  1371  Content-Type: application/vnd.api+json
  1372  ```
  1373  
  1374  ```json
  1375  {
  1376    "data": [
  1377      {
  1378        "type": "io.cozy.files",
  1379        "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1380        "meta": {"rev": "1-0e6d5b72"},
  1381        "attributes": {"dir_id": "f2f36fec-8018-11e6-abd8-8b3814d9a465"}
  1382      },
  1383      {
  1384        "type": "io.cozy.files",
  1385        "id": "9152d568-7e7c-11e6-a377-37cbfb190b4c",
  1386        "meta": {"rev": "2-123123"},
  1387        "attributes": {"move_to_trash": true}
  1388      }
  1389    ]
  1390  }
  1391  ```
  1392  
  1393  #### Status codes
  1394  
  1395  The same status codes can be encountered as the `PATCH /files/:file-id` route.
  1396  
  1397  ### POST /files/archive
  1398  
  1399  Create an archive. The body of the request lists the files and directories that
  1400  will be included in the archive. For directories, it includes all the files and
  1401  sub-directories in the archive.
  1402  
  1403  It's possible to give a file by its id (in the `ids` array) or by its path (in
  1404  the `files` array).
  1405  
  1406  The generated archive is temporary and is not persisted.
  1407  
  1408  #### Request
  1409  
  1410  ```http
  1411  POST /files/archive HTTP/1.1
  1412  Content-Type: application/vnd.api+json
  1413  ```
  1414  
  1415  ```json
  1416  {
  1417    "data": {
  1418      "type": "io.cozy.files.archives",
  1419      "attributes": {
  1420        "name": "project-X",
  1421        "ids": ["a51aeeea-4f79-11e7-9dc4-83f67e9494ab"],
  1422        "files": [
  1423          "/Documents/bills",
  1424          "/Documents/images/sunset.jpg",
  1425          "/Documents/images/eiffel-tower.jpg"
  1426        ]
  1427      }
  1428    }
  1429  }
  1430  ```
  1431  
  1432  #### Response
  1433  
  1434  ```http
  1435  HTTP/1.1 200 OK
  1436  Content-Type: application/vnd.api+json
  1437  ```
  1438  
  1439  ```json
  1440  {
  1441    "links": {
  1442      "related": "/files/archive/4521DC87/project-X.zip"
  1443    },
  1444    "data": {
  1445      "type": "io.cozy.files.archives",
  1446      "id": "4521DC87",
  1447      "attributes": {
  1448        "href": "/files/archive/4521DC87/project-X.zip"
  1449      }
  1450    }
  1451  }
  1452  ```
  1453  
  1454  ### GET /files/archive/:key/:name
  1455  
  1456  Download a previously created archive. The name parameter is not used in the
  1457  stack but aims to allow setting a name even for browser / downloader that do not
  1458  support Content-Disposition filename.
  1459  
  1460  **This route does not require Basic Authentification**
  1461  
  1462  ```http
  1463  GET /files/archive/4521DC87/project-X.zip HTTP/1.1
  1464  Accept: application/zip
  1465  Content-Length: 12345
  1466  Content-Disposition: attachment; filename="project-X.zip"
  1467  Content-Type: application/zip
  1468  ```
  1469  
  1470  ### POST /files/downloads?Path=file_path
  1471  
  1472  Create a file download. The Path query parameter specifies the file to download.
  1473  The response json API links contains a `related` link for downloading the file,
  1474  see below.
  1475  
  1476  ### POST /files/downloads?Id=file_id
  1477  
  1478  Also create a file download. But it takes the id of the file and not its path.
  1479  
  1480  ### POST /files/downloads?VersionId=file_id/version_id
  1481  
  1482  This is a third way to create a file download. But, this time, it is for
  1483  downloading an old version of a file.
  1484  
  1485  These 3 routes also accept a `Filename=...` parameter in the query-string to
  1486  change the filename that will be used for the downloaded file.
  1487  
  1488  ### GET /files/downloads/:secret/:name
  1489  
  1490  Allows to download a file with a secret created from the route above.
  1491  
  1492  The name parameter is not used in the stack but aims to allow setting a name
  1493  even for browser / downloader that do not support Content-Disposition filename.
  1494  
  1495  By default the `content-disposition` will be `inline`, but it will be
  1496  `attachment` if the query string contains the parameter `Dl=1`
  1497  
  1498  **This route does not require Basic Authentification**
  1499  
  1500  ## Versions
  1501  
  1502  The identifier of the `io.cozy.files.versions` is composed of the `file-id` and
  1503  another string called the `version-id`, separated by a `/`. So, when a route
  1504  makes reference to `/something/:file-id/:version-id`, you can use the identifier
  1505  of the version document (without having to prepend the file identifier).
  1506  
  1507  ### GET /files/download/:file-id/:version-id
  1508  
  1509  Download an old version of the file content
  1510  
  1511  By default the `content-disposition` will be `inline`, but it will be
  1512  `attachment` if the query string contains the parameter `Dl=1`
  1513  
  1514  #### Request
  1515  
  1516  ```http
  1517  GET /files/download/9152d568-7e7c-11e6-a377-37cbfb190b4b/1-0e6d5b72 HTTP/1.1
  1518  ```
  1519  
  1520  ### POST /files/:file-id/versions
  1521  
  1522  Create a new version of a file, with the same content but new metadata. It
  1523  requires a permission for PUT on the file, as it is equivalent to upload the
  1524  same content of the file.
  1525  
  1526  #### Query-String
  1527  
  1528  | Parameter | Description        |
  1529  | --------- | ------------------ |
  1530  | Tags      | an array of tags   |
  1531  
  1532  #### Request
  1533  
  1534  ```http
  1535  POST /files/9152d568-7e7c-11e6-a377-37cbfb190b4b/metadata HTTP/1.1
  1536  Content-Type: application/vnd.api+json
  1537  ```
  1538  
  1539  ```json
  1540  {
  1541    "data": {
  1542      "type": "io.cozy.files.metadata",
  1543      "attributes": {
  1544        "qualification": {
  1545          "label": "telecom_invoice",
  1546          "purpose": "invoice",
  1547          "sourceCategory": "telecom"
  1548        },
  1549        "datetime": "2017-04-22T01:00:00-05:00",
  1550      }
  1551    }
  1552  }
  1553  ```
  1554  
  1555  ### POST /files/revert/:file-id/:version-id
  1556  
  1557  This endpoint can be used to revert to an old version of the content for a
  1558  file.
  1559  
  1560  #### Request
  1561  
  1562  ```http
  1563  POST /files/revert/9152d568-7e7c-11e6-a377-37cbfb190b4b/2-fa3a3bec HTTP/1.1
  1564  ```
  1565  
  1566  ### PATCH /files/:file-id/:version-id
  1567  
  1568  This endpoint can be used to edit the tags of a previous version of the file.
  1569  
  1570  #### Request
  1571  
  1572  ```http
  1573  PATCH /files/9152d568-7e7c-11e6-a377-37cbfb190b4b/1-0e6d5b72 HTTP/1.1
  1574  Accept: application/vnd.api+json
  1575  Content-Type: application/vnd.api+json
  1576  ```
  1577  
  1578  
  1579  ```json
  1580  {
  1581    "data": {
  1582      "type": "io.cozy.files.versions",
  1583      "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b/1-0e6d5b72",
  1584      "attributes": {
  1585        "tags": ["poem"]
  1586      }
  1587    }
  1588  }
  1589  ```
  1590  
  1591  ### DELETE /files/:file-id/:version-id
  1592  
  1593  This endpoint can be used to delete an old version of the content for a file.
  1594  
  1595  #### Request
  1596  
  1597  ```http
  1598  DELETE /files/9152d568-7e7c-11e6-a377-37cbfb190b4b/2-fa3a3bec HTTP/1.1
  1599  ```
  1600  
  1601  #### Response
  1602  
  1603  ```http
  1604  HTTP/1.1 204 No Content
  1605  ```
  1606  
  1607  ### DELETE /files/versions
  1608  
  1609  Deletes all the old versions of all files to make space for new files.
  1610  
  1611  #### Request
  1612  
  1613  ```http
  1614  DELETE /files/versions HTTP/1.1
  1615  ```
  1616  
  1617  #### Response
  1618  
  1619  ```http
  1620  HTTP/1.1 204 No Content
  1621  ```
  1622  
  1623  
  1624  ## Trash
  1625  
  1626  When a file is deleted, it is first moved to the trash. In the trash, it can be
  1627  restored. Or, after some time, it will be removed from the trash and permanently
  1628  destroyed.
  1629  
  1630  The file `trashed` attribute will be set to true.
  1631  
  1632  ### GET /files/trash
  1633  
  1634  List the files inside the trash. It's paginated.
  1635  
  1636  ### Query-String
  1637  
  1638  | Parameter    | Description                           |
  1639  | ------------ | ------------------------------------- |
  1640  | page[cursor] | the last id of the results            |
  1641  | page[limit]  | the number of entries (30 by default) |
  1642  
  1643  #### Request
  1644  
  1645  ```http
  1646  GET /files/trash HTTP/1.1
  1647  Accept: application/vnd.api+json
  1648  ```
  1649  
  1650  #### Response
  1651  
  1652  ```http
  1653  HTTP/1.1 200 OK
  1654  Content-Type: application/vnd.api+json
  1655  ```
  1656  
  1657  ```json
  1658  {
  1659    "data": [
  1660      {
  1661        "type": "io.cozy.files",
  1662        "id": "df24aac0-7f3d-11e6-81c0-d38812bfa0a8",
  1663        "meta": {
  1664          "rev": "1-3b75377c"
  1665        },
  1666        "attributes": {
  1667          "type": "file",
  1668          "dir_id": "io.cozy.files.trash-dir",
  1669          "name": "foo.txt",
  1670          "trashed": true,
  1671          "restore_path": "/previous_parent",
  1672          "md5sum": "YjAxMzQxZTc4MDNjODAwYwo=",
  1673          "created_at": "2016-09-19T12:38:04Z",
  1674          "updated_at": "2016-09-19T12:38:04Z",
  1675          "tags": [],
  1676          "size": 123,
  1677          "executable": false,
  1678          "class": "document",
  1679          "mime": "text/plain",
  1680          "cozyMetadata": {
  1681            "doctypeVersion": "1",
  1682            "metadataVersion": 1,
  1683            "createdAt": "2016-09-20T18:32:49Z",
  1684            "createdByApp": "drive",
  1685            "createdOn": "https://cozy.example.com/",
  1686            "updatedAt": "2016-09-20T18:32:49Z",
  1687            "uploadedAt": "2016-09-20T18:32:49Z",
  1688            "uploadedOn": "https://cozy.example.com/",
  1689            "uploadedBy": {
  1690              "slug": "drive"
  1691            }
  1692          }
  1693        },
  1694        "links": {
  1695          "self": "/files/trash/df24aac0-7f3d-11e6-81c0-d38812bfa0a8"
  1696        }
  1697      },
  1698      {
  1699        "type": "io.cozy.files",
  1700        "id": "4a4fc582-7f3e-11e6-b9ca-278406b6ddd4",
  1701        "meta": {
  1702          "rev": "1-4a09030e"
  1703        },
  1704        "attributes": {
  1705          "type": "file",
  1706          "dir_id": "io.cozy.files.trash-dir",
  1707          "name": "bar.txt",
  1708          "trashed": true,
  1709          "restore_path": "/other_parent",
  1710          "md5sum": "YWVhYjg3ZWI0OWQzZjRlMAo=",
  1711          "created_at": "2016-09-19T12:38:04Z",
  1712          "updated_at": "2016-09-19T12:38:04Z",
  1713          "tags": [],
  1714          "size": 456,
  1715          "executable": false,
  1716          "class": "document",
  1717          "mime": "text/plain",
  1718          "cozyMetadata": {
  1719            "doctypeVersion": "1",
  1720            "metadataVersion": 1,
  1721            "createdAt": "2016-09-20T18:32:49Z",
  1722            "createdByApp": "drive",
  1723            "createdOn": "https://cozy.example.com/",
  1724            "updatedAt": "2016-09-20T18:32:49Z",
  1725            "uploadedAt": "2016-09-20T18:32:49Z",
  1726            "uploadedOn": "https://cozy.example.com/",
  1727            "uploadedBy": {
  1728              "slug": "drive"
  1729            }
  1730          }
  1731        },
  1732        "links": {
  1733          "self": "/files/trash/4a4fc582-7f3e-11e6-b9ca-278406b6ddd4"
  1734        }
  1735      }
  1736    ]
  1737  }
  1738  ```
  1739  
  1740  ### POST /files/trash/:file-id
  1741  
  1742  Restore the file with the `file-id` identifiant into its `restore_path`. If a file already exists at the restore path with the same name, a suffix will be added to avoid any conflict.
  1743  
  1744  The file's `trashed` attributes will be set to false.
  1745  
  1746  ### DELETE /files/trash/:file-id
  1747  
  1748  Destroy the file and make it unrecoverable (it will still be available in
  1749  backups).
  1750  
  1751  ### DELETE /files/trash
  1752  
  1753  Clear out the trash.
  1754  
  1755  ## Trashed attribute
  1756  
  1757  All files that are inside the trash will have a `trashed: true` attribute. This
  1758  attribute can be used in mango queries to only get "interesting" files.
  1759  
  1760  ## Real-time via websockets
  1761  
  1762  In addition to the normal events for files, the stack also injects some events
  1763  when a thumbnail is generated. A permission on `io.cozy.files` is required to
  1764  subscribe to those events on `io.cozy.files.thumbnails`.
  1765  
  1766  ### Example
  1767  
  1768  ```
  1769  client > {"method": "AUTH",
  1770            "payload": "xxAppOrAuthTokenxx="}
  1771  client > {"method": "SUBSCRIBE",
  1772            "payload": {"type": "io.cozy.files.thumbnails"}}
  1773  server > {"event": "CREATED",
  1774            "payload": {"id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1775                        "type": "io.cozy.files.thumbnails",
  1776                        "doc": {"format": "large"}}}
  1777  server > {"event": "CREATED",
  1778            "payload": {"id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1779                        "type": "io.cozy.files.thumbnails",
  1780                        "doc": {"format": "medium"}}}
  1781  server > {"event": "CREATED",
  1782            "payload": {"id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1783                        "type": "io.cozy.files.thumbnails",
  1784                        "doc": {"format": "small"}}}
  1785  server > {"event": "CREATED",
  1786            "payload": {"id": "9152d568-7e7c-11e6-a377-37cbfb190b4b",
  1787                        "type": "io.cozy.files.thumbnails",
  1788                        "doc": {"format": "tiny"}}}
  1789  ```