The notion of document type does not exist in Couchdb.
Cozy-stack introduce this notion through a special _type
field.
This type name cannot contain /
, and it should be unique among all developers,
it is recommended to use the Java naming convention with a domain you own.
All CozyCloud types will be prefixed by io.cozy and be pluralized. Example:
/data/io.cozy.events/6494e0ac-dfcb-11e5-88c1-472e84a9cbee
Where, io.cozy.
is
the developer specific prefix, events
the actual type, and
6494e0ac-dfcb-11e5-88c1-472e84a9cbee
the document's unique id .
GET /data/:type/:id HTTP/1.1
GET /data/io.cozy.events/6494e0ac-dfcb-11e5-88c1-472e84a9cbee HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 27 Sept 2016 12:28:53 GMT
Content-Length: ...
Content-Type: application/json
Etag: "3-6494e0ac6494e0ac"
{
"_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"_type": "io.cozy.events",
"_rev": "3-6494e0ac6494e0ac",
"startdate": "20160823T150000Z",
"enddate": "20160923T160000Z",
"summary": "A long month",
"description": "I could go on and on and on ...."
}
HTTP/1.1 404 Not Found
Content-Length: ...
Content-Type: application/json
{
"status": 404,
"error": "not_found",
"reason": "deleted",
"title": "Event deleted",
"details": "Event 6494e0ac-dfcb-11e5-88c1-472e84a9cbee was deleted",
"links": { "about": "https://cozy.github.io/cozy-stack/errors.md#deleted" }
}
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 404 not_found
- reason: missing
- reason: deleted
- 500 internal server error
POST /data/:type/_all_docs HTTP/1.1
POST /data/io.cozy.files/_all_docs?include_docs=true HTTP/1.1
Content-Length: ...
Content-Type: application/json
Accept: application/json
{
"keys": [
"7f46ed4ed2a775494da3b0b44e00314f",
"7f46ed4ed2a775494da3b0b44e003b18"
]
}
HTTP/1.1 200 OK
Date: Mon, 27 Sept 2016 12:28:53 GMT
Content-Length: ...
Content-Type: application/json
Etag: "3-6494e0ac6494e0ac"
{
"total_rows": 11,
"rows": [
{
"id": "7f46ed4ed2a775494da3b0b44e00314f",
"key": "7f46ed4ed2a775494da3b0b44e00314f",
"value": {
"rev": "1-870e58f8a1b2130c3a41e767f9c7d93a"
},
"doc": {
"_id": "7f46ed4ed2a775494da3b0b44e00314f",
"_rev": "1-870e58f8a1b2130c3a41e767f9c7d93a",
"type": "directory",
"name": "Uploaded from Cozy Photos",
"dir_id": "7f46ed4ed2a775494da3b0b44e0027df",
"created_at": "2017-07-04T06:49:12.844631837Z",
"updated_at": "2017-07-04T06:49:12.844631837Z",
"tags": [],
"path": "/Photos/Uploaded from Cozy Photos"
}
},
{
"key": "7f46ed4ed2a775494da3b0b44e003b18",
"error": "not_found"
}
]
}
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 500 internal server error
When some keys don't match an existing document, the response still has a status
200 and the errors are included in the rows
field (see above, same behavior as
CouchDB).
POST /data/:type/ HTTP/1.1
POST /data/io.cozy.events/ HTTP/1.1
Content-Length: ...
Content-Type: application/json
Accept: application/json
{
"startdate": "20160712T150000",
"enddate": "20160712T150000"
}
HTTP/1.1 201 Created
Content-Length: ...
Content-Type: application/json
{
"id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"type": "io.cozy.events",
"ok": true,
"rev": "1-6494e0ac6494e0ac",
"data": {
"_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"_type": "io.cozy.events",
"_rev": "1-6494e0ac6494e0ac",
"startdate": "20160712T150000",
"enddate": "20160712T150000"
}
}
- 400 bad request
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 500 internal server error
- A doc cannot contain an
_id
field, if so an error 400 is returned - A doc cannot contain any field starting with
_
, those are reserved for future cozy & couchdb api evolution
PUT /data/:type/:id HTTP/1.1
PUT /data/io.cozy.events/6494e0ac-dfcb-11e5-88c1-472e84a9cbee HTTP/1.1
Content-Length: ...
Content-Type: application/json
Accept: application/json
{
"_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"_type": "io.cozy.events",
"_rev": "1-6494e0ac6494e0ac",
"startdate": "20160712T150000",
"enddate": "20160712T200000"
}
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/json
{
"id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"type": "io.cozy.events",
"ok": true,
"rev": "2-056f5f44046ecafc08a2bc2b9c229e20",
"data": {
"_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"_type": "io.cozy.events",
"_rev": "2-056f5f44046ecafc08a2bc2b9c229e20",
"startdate": "20160712T150000",
"enddate": "20160712T200000"
}
}
- 400 bad request
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 404 not_found
- reason: missing
- reason: deleted
- 409 Conflict (see Conflict prevention section below)
- 500 internal server error
The client MUST give a _rev
field in the document. If this field is different
from the one in the current version of the document, an error 409 Conflict will
be returned.
- If no id is provided in URL, an error 400 is returned
- If the id provided in URL is not the same than the one in document, an error 400 is returned.
PUT /data/:type/:id HTTP/1.1
PUT /data/io.cozy.events/6494e0ac-dfcb-11e5-88c1-472e84a9cbee HTTP/1.1
Content-Length: ...
Content-Type: application/json
Accept: application/json
{
"startdate": "20160712T150000",
"enddate": "20160712T200000"
}
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/json
{
"id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"type": "io.cozy.events",
"ok": true,
"rev": "1-056f5f44046ecafc08a2bc2b9c229e20",
"data": {
"_id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"_type": "io.cozy.events",
"_rev": "1-056f5f44046ecafc08a2bc2b9c229e20",
"startdate": "20160712T150000",
"enddate": "20160712T200000"
}
}
- 400 bad request
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 404 not_found
- reason: missing
- reason: deleted
- 409 Conflict (see Conflict prevention section below)
- 500 internal server error
- No id should be provide in the document itself
DELETE /data/:type/:id?rev=:rev HTTP/1.1
DELETE /data/io.cozy.events/6494e0ac-dfcb-11e5-88c1-472e84a9cbee?rev=1-82a7144c9ec228c9a851b8a1c1aa225b HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Length: ...
Content-Type: application/json
{
"id": "6494e0ac-dfcb-11e5-88c1-472e84a9cbee",
"type": "io.cozy.events",
"ok": true,
"rev": "2-056f5f44046ecafc08a2bc2b9c229e20",
"_deleted": true
}
- 400 bad request
- 401 unauthorized (no authentication has been provided)
- 403 forbidden (the authentication does not provide permissions for this action)
- 404 not_found
- reason: missing
- reason: deleted
- 409 Conflict (see Conflict prevention section below)
- 500 internal server error
It is possible to use either a rev
query string parameter or a HTTP If-Match
header to prevent conflict on deletion:
- If none is passed or they are different, an error 400 is returned
- If only one is passed or they are equals, the document will only be deleted
if its
_rev
match the passed one. Otherwise, an error 409 is returned.
- If no id is provided in URL, an error 400 is returned
We have added a non-standard _normal_docs
endpoint since
_all_docs
endpoint sends the design docs in the response
and that it makes it hard to use pagination on it.
This _normal_docs
endpoint skip the design docs (and does
not count them in thetotal_rows
). It accepts three parameters
in the query string: limit
(default: 100), skip
(default: 0),
and bookmark
(default: '').
The response format looks like a _find
response with mango.
And, like for _find
, the limit cannot be more than 1000.
The pagination
is also the same: both bookmark
and skip
can be used, but
bookmark
is recommended for performances.
GET /data/io.cozy.events/_normal_docs?limit=100&bookmark=g1AAAAB2eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGKQYpVqaJRoZm1paWFiapFkamhknGpilJiampZkYJRmC9HHA9OUAdTASpS0rCwAlah76 HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"rows": [
{
"_id": "16e458537602f5ef2a710089dffd9453",
"_rev": "1-967a00dff5e02add41819138abb3284d",
"field": "value"
},
{
"_id": "f4ca7773ddea715afebc4b4b15d4f0b3",
"_rev": "2-7051cbe5c8faecd085a3fa619e6e6337",
"field": "other-value"
},
...
],
"total_rows": 202,
"bookmark": "g1AAAAB2eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGKQYpVqaJRoZm1paWFiapFkamhknGpilJiampZkYJRmC9HHA9OUAdTASpS0rCwAlah76"
}
You can use _all_docs
endpoint to get the list of all the documents.
In some cases the use of this route is legitimate, but we recommend to
avoid it as much as possible.
The stack also supports a Fields
query parameter to only include those fields
in the response (with an uppercase F
to avoid collusion with a possible
future fields
by CouchDB), and a DesignDocs
query parameter to skip design
docs. Example: ?Fields=name,metadata.title,tags&DesignDocs=false
.
GET /data/io.cozy.events/_all_docs?include_docs=true HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"offset": 0,
"rows": [
{
"id": "16e458537602f5ef2a710089dffd9453",
"key": "16e458537602f5ef2a710089dffd9453",
"value": {
"rev": "1-967a00dff5e02add41819138abb3284d"
},
"doc": {
"field": "value"
}
},
{
"id": "f4ca7773ddea715afebc4b4b15d4f0b3",
"key": "f4ca7773ddea715afebc4b4b15d4f0b3",
"value": {
"rev": "2-7051cbe5c8faecd085a3fa619e6e6337"
},
"doc": {
"field": "other-value"
}
}
],
"total_rows": 2
}
A permission on io.cozy.doctypes
for GET
is needed to query this endoint.
GET /data/_all_doctypes HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
["io.cozy.files", "io.cozy.jobs", "io.cozy.triggers", "io.cozy.settings"]
- The creation and usage of Mango indexes is possible.
- CouchDB behaviors are not always straight forward: see some quirks for more details.
A design document is a special CouchDB document that represents a view or Mango index definition.
GET /data/:type/_design/:ddoc HTTP/1.1
GET /data/io.cozy.events/_design/c4a8fa4a4660b8eed43137881500265c HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"_id": "_design/c4a8fa4a4660b8eed43137881500265c",
"_rev": "1-56cf55098fc69450f84a22a632ffafb9",
"language": "query",
"views": {
"by-startdate-and-enddate": {
"map": {
"fields": {
"startdate": "asc",
"enddate": "asc",
},
"partial_filter_selector": {}
},
"reduce": "_count",
"options": {
"def": {
"fields": [
"startdate",
"enddate",
"metadata.datetime"
]
}
}
}
}
}
GET /data/:type/_design_docs HTTP/1.1
GET /data/io.cozy.events/_design_docs HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"total_rows": 123,
"offset": 57,
"rows": [
...
]
}
DELETE /data/:type/_design/:ddoc HTTP/1.1
DELETE /data/io.cozy.events/_design/c4a8fa4a4660b8eed43137881500265c?rev=1-1aa097a2eef904db9b1842342e6c6f50 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"ok": true,
"id": "_design/c4a8fa4a4660b8eed43137881500265c",
"rev": "2-2ad11c9dc32df12a4b24f994807408ba"
}
This is useful to duplicate a view or Mango index definition, without having to recompute the whole B-Tree. The original and the copy will both use the same index on disk.
POST /data/:type/_design/:ddoc/copy HTTP/1.1
POST /data/io.cozy.events/_design/c4a8fa4a4660b8eed43137881500265c/copy?rev=1-1aa097a2eef904db9b1842342e6c6f50 HTTP/1.1
Destination: _design/d7349ab71c0859c408a725ebbfd453b18aa94ec7
HTTP/1.1 201 Created
Content-Type: application/json
{
"ok": true,
"id": "_design/d7349ab71c0859c408a725ebbfd453b18aa94ec7",
"rev": "1-1aa097a2eef904db9b1842342e6c6f50"
}
DELETE /data/:type/ HTTP/1.1
DELETE /data/io.cozy.events/ HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"ok": true,
"deleted": true
}