Shared drives¶
A shared drive is a folder that is shared between several cozy instances. A member doesn’t have the files in their Cozy, but can access them via the stack playing a proxy role.
To create a shared drive (typically on the organization Cozy), we need the following steps:
- Ensure that the
/Drives
folder exists in the cozy instance with thePOST /files/shared-drives
route. - Create a folder inside it, with the name of shared drive.
- Create a sharing with the
drive: true
attribute, and one rule for shared folder (withnone
foradd
,update
andremove
attributes).
Managing shared drives¶
GET /sharings/drives¶
The GET /sharings/drives
route returns the list of shared drives.
Request¶
GET /sharings/drives HTTP/1.1 Host: acme.example.net Accept: application/vnd.api+json
Response¶
HTTP/1.1 200 OK Content-Type: application/vnd.api+json
{ "data": [ { "type": "io.cozy.sharings", "id": "aae62886e79611ef8381fb83ff72e425", "attributes": { "drive": true, "owner": true, "description": "Drive for the product team", "app_slug": "drive", "created_at": "2025-02-10T11:08:08Z", "updated_at": "2025-02-10T12:10:43Z", "members": [ { "status": "owner", "public_name": "ACME", "email": "admin@acme.example.net", "instance": "acme.example.net" }, { "status": "pending", "name": "Alice", "email": "alice@example.net" }, { "status": "pending", "name": "Bob", "email": "bob@example.net" } ], "rules": [ { "title": "Product team", "doctype": "io.cozy.files", "values": [ "357665ec-e797-11ef-94fb-f3d08ccb3ff5" ], "add": "none", "update": "none", "remove": "none" } ] }, "meta": { "rev": "1-272ba74b868f" }, "links": { "self": "/sharings/aae62886e79611ef8381fb83ff72e425" } } ] }
Files and directories¶
Unless stated otherwise, a permission on the whole io.cozy.files
doctype is
required to use the following routes.
GET /sharings/drives/:id/download/:file-id¶
Download a file via a drive share.
Identical call to GET /files/download/:file-id
but over a shared drive.
See there for request and response examples
GET /sharings/drives/:id/_changes¶
Get the change feed for a drive.
Identical call to GET /files/_changes
but over a shared drive.
See there for request and response examples, differences are the URL and:
- Any item that changed for that owner but isn’t under that shared drive is presented as a deletion.
- Paths are truncated to the shared drive, and formatted accordingly:
eg: //io.cozy.files.shared-drives-dir/1/ba3b516812f636fc022f3968f991357a/Meetings/Checklist.txt
Schema and it’s version, followed by the shared drive ID, and the path within
GET /sharings/drives/:id/:file-id¶
Get a directory or a file informations inside a shared drive. In the case of a directory, it contains the list of files and sub-directories inside it. For a note, its images are included.
Request¶
GET /sharings/drives/aae62886e79611ef8381fb83ff72e425/af1e1b66e92111ef8ddd5fbac4938703 HTTP/1.1 Accept: application/vnd.api+json
Response¶
HTTP/1.1 200 OK Content-Type: application/vnd.api+json
{ "data": { "type": "io.cozy.files", "id": "af1e1b66e92111ef8ddd5fbac4938703", "meta": { "rev": "1-e36ab092" }, "attributes": { "type": "directory", "name": "Streams", "path": "/Product team/Streams", "created_at": "2016-09-19T12:35:00Z", "updated_at": "2016-09-19T12:35:00Z", "tags": [], "cozyMetadata": { "doctypeVersion": "1", "metadataVersion": 1, "createdAt": "2016-09-20T18:32:47Z", "createdByApp": "drive", "createdOn": "https://cozy.example.com/", "updatedAt": "2016-09-20T18:32:47Z" }, "driveId": "aae62886e79611ef8381fb83ff72e425" }, "relationships": { "contents": { "data": [ { "type": "io.cozy.files", "id": "a2843318f52411ef8e7ab79eae2f09ab" }, { "type": "io.cozy.files", "id": "b1db1642f52411efbe0b3bfc5fc0b437" } ] } }, "links": { "self": "/files/af1e1b66e92111ef8ddd5fbac4938703" } }, "included": [ { "type": "io.cozy.files", "id": "a2843318f52411ef8e7ab79eae2f09ab", "meta": { "rev": "1-ff3beeb456eb" }, "attributes": { "type": "directory", "name": "Authentication", "path": "/Product team/Streams/Authentication", "created_at": "2016-09-19T12:35:08Z", "updated_at": "2016-09-19T12:35:08Z", "cozyMetadata": { "doctypeVersion": "1", "metadataVersion": 1, "createdAt": "2016-09-20T18:32:47Z", "createdByApp": "drive", "createdOn": "https://cozy.example.com/", "updatedAt": "2016-09-20T18:32:47Z" } } }, { "type": "io.cozy.files", "id": "b1db1642f52411efbe0b3bfc5fc0b437", "meta": { "rev": "1-0e6d5b72" }, "attributes": { "type": "file", "name": "REAMDE.md", "trashed": false, "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=", "created_at": "2016-09-19T12:38:04Z", "updated_at": "2016-09-19T12:38:04Z", "tags": [], "size": 12, "executable": false, "class": "document", "mime": "text/plain", "cozyMetadata": { "doctypeVersion": "1", "metadataVersion": 1, "createdAt": "2016-09-20T18:32:49Z", "createdByApp": "drive", "createdOn": "https://cozy.example.com/", "updatedAt": "2016-09-20T18:32:49Z", "uploadedAt": "2016-09-20T18:32:49Z", "uploadedOn": "https://cozy.example.com/", "uploadedBy": { "slug": "drive" } } } } ] }
GET /sharings/drives/:id/:file-id/size¶
This endpoint returns the size taken by the files in a directory inside a shared drive, including those in subdirectories.
Request¶
GET /sharings/drives/aae62886e79611ef8381fb83ff72e425/af1e1b66e92111ef8ddd5fbac4938703/size HTTP/1.1 Accept: application/vnd.api+json
Response¶
HTTP/1.1 200 OK Content-Type: application/vnd.api+json
{ "data": { "type": "io.cozy.files.sizes", "id": "af1e1b66e92111ef8ddd5fbac4938703", "attributes": { "size": "1234567890" }, "meta": {} } }
POST /sharings/drives/:id/:file-id/copy¶
Duplicates a file.
Identical call to POST /files/:file-id/copy
but over a shared drive.
See there for request and response examples, the only difference is the URL.
PATCH /sharings/drives/:id/:file-id¶
This endpoint can be used to update the metadata of a file or directory, to rename it or to move it within the same shared drive.
Some specific attributes of the patch can be used:
dir_id
attribute can be updated to move a file or directory (the new directory needs to be in the same shared drive as the old one)
HTTP headers¶
It’s possible to send the If-Match
header, with the previous revision of the
file/directory (optional).
Request¶
PATCH /sharings/drives/aae62886e79611ef8381fb83ff72e425/9152d568-7e7c-11e6-a377-37cbfb190b4b HTTP/1.1 Accept: application/vnd.api+json Content-Type: application/vnd.api+json
{ "data": { "type": "io.cozy.files", "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b", "attributes": { "type": "file", "name": "hi.txt", "dir_id": "f2f36fec-8018-11e6-abd8-8b3814d9a465", "tags": ["poem"] } } }
Status codes¶
- 200 OK, when the file or directory metadata has been successfully updated
- 400 Bad Request, when a the destination directory does not exist
- 403 Forbidden, when the file or directory cannot be modified or the
- destination directory is not accessible
- 404 Not Found, when the file/directory does not exist
- 412 Precondition Failed, when the
If-Match
header is set and doesn’t match the last revision of the file/directory - 422 Unprocessable Entity, when the sent data is invalid (for example, the parent doesn’t exist)
Response¶
HTTP/1.1 200 OK Content-Type: application/vnd.api+json Location: https://cozy.example.com/sharings/drives/aae62886e79611ef8381fb83ff72e425/9152d568-7e7c-11e6-a377-37cbfb190b4b
{ "data": { "type": "io.cozy.files", "id": "9152d568-7e7c-11e6-a377-37cbfb190b4b", "meta": { "rev": "1-0e6d5b72" }, "attributes": { "type": "file", "name": "hi.txt", "trashed": false, "md5sum": "ODZmYjI2OWQxOTBkMmM4NQo=", "created_at": "2016-09-19T12:38:04Z", "updated_at": "2016-09-19T12:38:04Z", "tags": ["poem"], "size": 12, "executable": false, "class": "document", "mime": "text/plain", "cozyMetadata": { "doctypeVersion": "1", "metadataVersion": 1, "createdAt": "2016-09-20T18:32:49Z", "createdByApp": "drive", "createdOn": "https://cozy.example.com/", "updatedAt": "2016-09-22T13:32:51Z", "uploadedAt": "2016-09-21T04:27:50Z", "uploadedOn": "https://cozy.example.com/", "uploadedBy": { "slug": "drive" } } }, "relationships": { "parent": { "links": { "related": "/files/f2f36fec-8018-11e6-abd8-8b3814d9a465" }, "data": { "type": "io.cozy.files", "id": "f2f36fec-8018-11e6-abd8-8b3814d9a465" } } }, "links": { "self": "/files/9152d568-7e7c-11e6-a377-37cbfb190b4b" } } }
Versions¶
The identifier of the io.cozy.files.versions
is composed of the file-id
and
another string called the version-id
, separated by a /
. So, when a route
makes reference to /something/:file-id/:version-id
, you can use the identifier
of the version document (without having to prepend the file identifier).
GET /sharings/drives/:id/download/:file-id/:version-id¶
Downloads an old version of the file content.
Identical call to GET /files/download/:file-id/:version-id
but over a shared drive. See there for request and response examples, the only
difference is the URL.
Notes¶
POST /sharings/drives/:id/notes¶
Create a note inside a shared drive. Identical to POST /notes
.
GET /sharings/drives/:id/notes/:file-id/open¶
Return the parameters to build the URL where the note can be opened.
Identical to GET /notes/:file-id/open
.
Office¶
GET /sharings/drives/:id/office/:file-id/open¶
Returns the parameters to open an office document. Identical to
GET /office/:file-id/open
.
Realtime¶
GET /sharings/drives/:id/realtime¶
Get the changes inside a shared drive in real-time from a websocket.
Identical to GET /realtime
, except subscribing to the shared drive is automatically done.
client > {"method": "AUTH", "payload": "xxAppOrAuthTokenxx="} server > {"event": "UPDATED", "payload": {"id": "idB", "rev": "6-457...", "type": "io.cozy.files", "doc": {embeded doc ...}}}