Skip to content
Hoody.com

The WebDAV endpoints on this page expose a container’s own storage as a WebDAV share. Any WebDAV-capable tool (Finder, Explorer, or a standalone WebDAV client) can mount the share using the container’s files URL and credentials. The verbs OPTIONS, COPY, MOVE, LOCK, UNLOCK, PROPFIND, and PROPPATCH are served at /{path} on the files service URL, with no /api/files/webdav/ prefix. The share has no credentials of its own: a WebDAV request is authorised exactly like every other request to the container’s files URL.

GET /{path}?type=webdav is a separate, one-off read of a remote WebDAV server using the credentials supplied on the request. Nothing is stored and it configures nothing that the verbs below use.

The verbs below are served at /{path} and address the container’s own storage. Mounting the share from a WebDAV client uses the same URL.

Returns the HTTP methods and WebDAV capabilities supported at a given path. WebDAV clients use this for capability discovery before issuing other verbs. The response is answered the same way for any query, including a request that names a remote backend with the type query parameter: this verb connects to nothing, so it is never refused while the service cannot connect to remote backends.

NameInTypeRequiredDescription
pathpathstringYesPath to query for capabilities

The response carries no body. Advertised methods and DAV compliance class live in the response headers.

HeaderTypeDescription
AllowstringComma-separated list of supported HTTP methods. WebDAV-root paths advertise the full WebDAV verb set; /api/v1/* paths advertise the simple HTTP set.
DAVstringWebDAV compliance class. Set to 1 on WebDAV-root OPTIONS responses; absent on /api/v1/* OPTIONS responses.
MS-Author-ViastringAuthoring-protocol hint for Microsoft WebDAV clients. Set to DAV on WebDAV-root OPTIONS responses.
Terminal window
curl -X OPTIONS 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data' \
-H 'Authorization: Bearer <token>'

Copies a file to a new location specified by the Destination header. Send Overwrite: F to refuse a destination that already exists. The source must be a regular file: copying a directory with COPY is refused.

NameInTypeRequiredDescription
pathpathstringYesSource file path
DestinationheaderstringYesDestination URL for the copy
OverwriteheaderstringNoT (default) replaces an existing destination; F refuses one, answering 412 and leaving it untouched. A request refused for another reason is answered for that reason instead, whatever this header says: copying a resource onto itself is 403, and so is a source that is not a regular file.

The destination did not exist and was created.

Terminal window
curl -X COPY 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/report.txt' \
-H 'Authorization: Bearer <token>' \
-H 'Destination: https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/report-backup.txt' \
-H 'Overwrite: T'

Moves a file or directory to a new location specified by the Destination header. Send Overwrite: F to refuse a destination that already exists. Requires both upload and delete permissions.

NameInTypeRequiredDescription
pathpathstringYesSource file or directory path
DestinationheaderstringYesDestination URL for the move
OverwriteheaderstringNoT (default) replaces an existing destination; F refuses one, answering 412 and leaving it untouched. A request refused for another reason is answered for that reason instead, whatever this header says: moving a resource onto itself is 403.

The destination did not exist and was created.

Terminal window
curl -X MOVE 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/old-name.txt' \
-H 'Authorization: Bearer <token>' \
-H 'Destination: https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/new-name.txt' \
-H 'Overwrite: T'

Returns a lock token for WebDAV client compatibility. This is a compatibility stub: locks are not enforced server-side. The Depth header is accepted but ignored.

NameInTypeRequiredDescription
pathpathstringYesPath of the file to lock
DepthheaderstringNoDepth of the lock: 0 (resource only) or infinity (recursive). Declared for WebDAV compatibility; the handler does not read this header.

The request may carry an XML body describing the requested lock. The server does not read the body and answers the same with or without one.

<?xml version="1.0" encoding="utf-8"?>
<D:lockinfo xmlns:D="DAV:">
<D:locktype><D:write/></D:locktype>
<D:lockscope><D:exclusive/></D:lockscope>
<D:depth>infinity</D:depth>
<D:owner>
<D:href>mailto:user@example.com</D:href>
</D:owner>
<D:timeout>Second-1800</D:timeout>
</D:lockinfo>

A lock token is issued. The response body is XML carrying only the lock token and the lock root, and the lock-token response header carries the same token wrapped in angle brackets (lock-token: <opaquelocktoken:b7f3c2a1-5d4e-4f6a-9b8c-0d1e2f3a4b5c>).

<?xml version="1.0" encoding="utf-8"?>
<D:prop xmlns:D="DAV:"><D:lockdiscovery><D:activelock>
<D:locktoken><D:href>opaquelocktoken:b7f3c2a1-5d4e-4f6a-9b8c-0d1e2f3a4b5c</D:href></D:locktoken>
<D:lockroot><D:href>/data/report.txt</D:href></D:lockroot>
</D:activelock></D:lockdiscovery></D:prop>
HeaderTypeDescription
lock-tokenstringOpaque lock token issued by the server. Returned on LOCK responses for WebDAV client compatibility.
Terminal window
curl -X LOCK 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/report.txt' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="utf-8"?>
<D:lockinfo xmlns:D="DAV:">
<D:locktype><D:write/></D:locktype>
<D:lockscope><D:exclusive/></D:lockscope>
<D:depth>infinity</D:depth>
<D:owner>
<D:href>mailto:user@example.com</D:href>
</D:owner>
<D:timeout>Second-1800</D:timeout>
</D:lockinfo>'

Releases a lock token. This is a no-op compatibility stub: the server reads no headers on this verb, so no lock token is required.

NameInTypeRequiredDescription
pathpathstringYesPath of the file to unlock

Lock released (no-op).

The response has no body.

Terminal window
curl -X UNLOCK 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/report.txt' \
-H 'Authorization: Bearer <token>'

Retrieves properties (metadata) for a file or directory. Returns a 207 Multi-Status response. Supports the Depth header (default 1) to control recursion into directories.

NameInTypeRequiredDescription
pathpathstringYesPath of the file or directory
DepthheaderstringNoDepth of property retrieval: 0 (resource only) or 1 (immediate children). Defaults to 1. Any other value, including infinity, is refused with 400 (“Invalid depth: only 0 and 1 are allowed.”).

The request may carry an XML body listing the properties to retrieve. The server does not read the body and answers the same with or without one.

<?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getcontentlength/>
<D:getlastmodified/>
<D:resourcetype/>
<D:getetag/>
</D:prop>
</D:propfind>

Multi-Status response with resource properties in WebDAV XML format.

<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>/data/report.txt</D:href>
<D:propstat>
<D:prop>
<D:getcontentlength>1024</D:getcontentlength>
<D:getlastmodified>Mon, 01 Jan 2024 12:00:00 GMT</D:getlastmodified>
<D:resourcetype/>
<D:getcontenttype>text/plain</D:getcontenttype>
<D:getetag>"abc123"</D:getetag>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Terminal window
curl -X PROPFIND 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data' \
-H 'Authorization: Bearer <token>' \
-H 'Depth: 1' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="utf-8"?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:getcontentlength/>
<D:getlastmodified/>
<D:resourcetype/>
<D:getetag/>
</D:prop>
</D:propfind>'

Modifies properties on a file or directory. Returns a 207 Multi-Status response. This is a compatibility response for WebDAV clients: the server stores nothing, and every property in the multistatus is reported as HTTP/1.1 403 Forbidden.

NameInTypeRequiredDescription
pathpathstringYesPath of the file or directory

The request may carry an XML body with set and remove instructions. The server does not read the body and answers the same with or without one.

<?xml version="1.0" encoding="utf-8"?>
<D:propertyupdate xmlns:D="DAV:">
<D:set>
<D:prop>
<D:displayname>New Name</D:displayname>
</D:prop>
</D:set>
</D:propertyupdate>

Multi-Status response confirming property changes. Every property in the response is reported as HTTP/1.1 403 Forbidden.

<?xml version="1.0" encoding="utf-8" ?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>/data/report.txt</D:href>
<D:propstat>
<D:prop>
</D:prop>
<D:status>HTTP/1.1 403 Forbidden</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Terminal window
curl -X PROPPATCH 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/data/report.txt' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/xml' \
-d '<?xml version="1.0" encoding="utf-8"?>
<D:propertyupdate xmlns:D="DAV:">
<D:set>
<D:prop>
<D:displayname>New Name</D:displayname>
</D:prop>
</D:set>
</D:propertyupdate>'

The endpoint in this section reads from a remote WebDAV server (Nextcloud, ownCloud, etc.) using the credentials supplied on the request. Nothing is stored and nothing is configured for the verbs above.

Reads a file or directory listing from a remote WebDAV server. The server, user, and pass query parameters identify the remote server and the account to authenticate as. The webdav_path parameter (default /) names the path on the remote server. The service connects to https://{server}{webdav_path} and reads path relative to webdav_path.

NameInTypeRequiredDescription
pathpathstringYesPath on the remote WebDAV server, relative to webdav_path
typequerystringYesMust be webdav
serverquerystringYesBare host or host:port of the remote WebDAV server. Do not include a scheme (the service connects to https://{server}{webdav_path}; a value such as https://... fails as an invalid port)
userquerystringNoUsername for the remote server
passquerystringNoPassword for the remote server, base64-encoded
webdav_pathquerystringNoWebDAV endpoint path on the remote server. Defaults to /.

File content or directory listing from the remote WebDAV server.

Terminal window
curl 'https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/remote/file.txt?type=webdav&server=nextcloud.example.com&user=admin&pass=c2VjcmV0&webdav_path=/' \
-H 'Authorization: Bearer <token>'