Skip to content
Hoody.com

The Files service exposes a directory-and-archive surface rooted at the container’s files instance. This page documents the directory operations (create directory), the archive operations (full extract, selective extract, preview, read a member, download a directory as ZIP), and the extraction status endpoints (list active jobs, history, and cancel). All requests target the container’s files instance on the per-container subdomain.

Create a directory at the given path. The path is relative to the served root and is created as a new directory. The request takes no body.

NameInTypeRequiredDescription
pathpathstringYesDirectory path to create under the served root
Terminal window
curl -X MKCOL "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/projects/new-project" \
-H "Authorization: Bearer $HOODY_TOKEN"

The directory was created.

Error CodeTitleDescriptionResolution

The archive operations read or extract ZIP, plain TAR, and compressed TAR (.tar.gz, .tar.bz2, .tar.xz) files. Empty values for the extract and extract_file query parameters trigger full extraction; non-empty values select the matching path inside the archive.

Extract a ZIP, TAR, or compressed TAR archive to a destination directory. Pass ?extract (empty) to extract all entries, or ?extract=<path> to selectively extract only entries matching the given prefix (for example ?extract=src/).

A large archive can take a long time to extract. The SDK and CLI wait up to 12 hours and 1 minute for the answer unless you set your own timeout; if the client stops waiting, the extraction keeps running on the server. Follow it under Extractions.

NameInTypeRequiredDescription
archivepathstringYesPath to the archive file under the served root
extractquerystringYesEmpty for full extraction; path for selective (e.g. src/ or lib/)
destquerystringNoDestination directory name (default: archive name)

This GET operation takes no owner parameter. The SDK’s client.files.archives.extract() also accepts an optional owner option (create-time owner for newly-created inodes as user[:group] or uid[:gid]; requires the deployment to have enabled chown, must resolve to one of the owners it permits, and refuses root). When owner is given, the SDK sends the extraction through the file-operation endpoint (files_postFileOperation, see File operations) with extract and owner in the query, and refuses the query options backend, mkdir, download_from, filename, timeout, move_to, copy_to and overwrite on that call.

Terminal window
# Full extraction
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?extract" \
-H "Authorization: Bearer $HOODY_TOKEN"
# Selective extraction
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?extract=src/&dest=data-src" \
-H "Authorization: Bearer $HOODY_TOKEN"

The extraction completed successfully. Archive entries that were left out are listed in skipped (path, reason; at most 1000): symbolic and hard links (links are never created from an archive), entries that are not a file or a folder (a pipe, a socket, a device), entries whose name is not valid UTF-8 (path shows the name with invalid bytes replaced) and later entries with a path an earlier entry already took. skipped_count counts every entry left out, including any beyond those listed.

{
"destination": "data",
"extracted_bytes": 1048576,
"extracted_files": 24,
"extraction_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "Extraction complete",
"skipped": [
{ "path": "data/latest", "reason": "symbolic link (links are not extracted)" }
],
"skipped_count": 1,
"success": true
}
Error CodeTitleDescriptionResolution

Extract a single file or directory from inside a ZIP, TAR, or compressed TAR archive to a destination directory. Only the specified entry (and its children if a directory) is extracted, leaving other archive contents untouched. The extract parameter is required and names the entry inside the archive.

The extract_file flag only names this operation and is ignored: the entry is chosen by extract=<entry path>. ?extract_file alone downloads the archive itself, and ?extract without a value extracts the whole archive (see GET /{archive}?extract above).

The SDK and CLI wait up to 12 hours and 1 minute for the answer unless you set your own timeout; if the client stops waiting, the extraction keeps running on the server. Follow it under Extractions.

NameInTypeRequiredDescription
archivepathstringYesPath to archive file
extractquerystringYesPath of the file or directory inside the archive to extract (e.g. src/ or lib/)
destquerystringNoDestination directory name (default: archive name)
Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?extract_file&extract=README.md&dest=readme-out" \
-H "Authorization: Bearer $HOODY_TOKEN"

The selective extraction completed successfully.

{
"destination": "readme-out",
"extracted_bytes": 4096,
"extracted_files": 1,
"extraction_id": "550e8400-e29b-41d4-a716-446655440001",
"message": "Selective extraction complete",
"selective": true,
"selective_path": "README.md",
"success": true
}
Error CodeTitleDescriptionResolution

List the contents of a ZIP, TAR, or compressed TAR archive without extracting, or read a specific file from the archive. With an empty ?preview (or ?contents), the response is a JSON listing of all entries. With ?preview=<path> (or ?contents=<path>), the raw content of that file from the archive is returned. The two query parameters are aliases for each other.

NameInTypeRequiredDescription
archivepathstringYesPath to archive file
previewquerystringNoEmpty value lists archive contents; non-empty value reads a specific file from the archive (alias: ?contents)
contentsquerystringNoAlias for ?preview
Terminal window
# List contents
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?preview" \
-H "Authorization: Bearer $HOODY_TOKEN"
# Read a specific member (alias)
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?contents=src/index.js" \
-H "Authorization: Bearer $HOODY_TOKEN"

The archive contents are returned as a JSON listing of entries.

{
"entries": [
{
"compressed_size": 4096,
"entry_type": "file",
"is_dir": false,
"modified_time": 1700000000,
"path": "README.md",
"permissions": 33188,
"size": 8192
},
{
"compressed_size": 0,
"entry_type": "directory",
"is_dir": true,
"modified_time": 1700000000,
"path": "src/",
"permissions": 16877,
"size": 0
}
],
"format": "zip",
"total_compressed_size": 4096,
"total_files": 2,
"total_size": 8192
}
Error CodeTitleDescriptionResolution

Read and return a single file from inside a ZIP, TAR, or compressed TAR archive without extracting the entire archive. The preview parameter is required and names the entry inside the archive. The view_file flag only names this operation and is ignored: the entry is chosen by preview=<entry path>. ?view_file alone downloads the archive itself, and ?preview without a value lists the archive’s contents (see GET /{archive}?preview above). The response body is the raw member bytes; the Content-Type is the member’s own type, guessed from its name (text/plain for README.txt, application/json for package.json, image/png, and so on). Read the body as bytes, not by that type. HTML, SVG, XML, and JavaScript members come as attachments.

NameInTypeRequiredDescription
archivepathstringYesPath to archive file
previewquerystringYesPath of the file inside the archive to view (e.g. src/ or README.md)
Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/uploads/data.zip?view_file&preview=README.md" \
-H "Authorization: Bearer $HOODY_TOKEN" \
--output readme.md

The member’s bytes. The body is a raw byte stream, not JSON. Treat the body as bytes; the Content-Type header is the member’s type, guessed from its name (application/octet-stream when unknown).

binary
Error CodeTitleDescriptionResolution

Create and download a directory as a ZIP archive. The archive holds the folder whole: a folder of more than 100000 files, of more than 1000000 files and folders in all, or with folders nested deeper than 50 levels is refused with 422 ARCHIVE_TOO_LARGE before anything is sent. A file that cannot be read, or that changes while it is added, is named in a __hoody-files_zip_errors__.txt entry at the end of the archive. With per-account path rules, the results hold only what the account may read: paths outside its rules, and symlinks that lead there, are left out.

NameInTypeRequiredDescription
directorypathstringYesPath to the directory to download
zipquerystringYesEmpty literal value triggers ZIP download
Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/projects/my-project?zip" \
-H "Authorization: Bearer $HOODY_TOKEN" \
--output my-project.zip

The body is a ZIP archive containing the directory. Treat the response as raw bytes.

binary
Error CodeTitleDescriptionResolution

Two distinct endpoints report active extractions, and a separate endpoint reports history. The active-extractions list returned by either endpoint contains only jobs whose every path (directory and file, or archive and destination) the caller may read. A rule that only lists a directory does not count: with /alice:rw the root is only listed, so the caller sees no job outside /alice.

Get the progress of every running archive extraction on this container, whether started with POST /api/v1/files/{path}?extract or on the WebDAV-style surface. The endpoint takes no parameters.

Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/extractions" \
-H "Authorization: Bearer $HOODY_TOKEN"

The list of currently running extractions.

{
"extractions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"archive_path": "/uploads/data.zip",
"dest_path": "/uploads/data",
"extracted_bytes": 524288,
"extracted_files": 12,
"total_bytes": 1048576,
"total_files": 24,
"percentage": 50.0,
"selective": false,
"start_time": 1700000000,
"status": "extracting"
}
]
}
Error CodeTitleDescriptionResolution

Get the progress of currently running archive extractions from or into the directory requested. This is the path-scoped variant of the active-extractions listing. The extractions query parameter is required and must be the empty string.

NameInTypeRequiredDescription
extractionsquerystringYesEmpty literal value triggers the active-extractions listing for this path
Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/projects/my-project?extractions" \
-H "Authorization: Bearer $HOODY_TOKEN"

The list of currently running extractions that touch this path.

{
"extractions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"archive_path": "/projects/my-project/data.zip",
"dest_path": "/projects/my-project/data",
"extracted_bytes": 524288,
"extracted_files": 12,
"total_bytes": 1048576,
"total_files": 24,
"percentage": 50.0,
"selective": false,
"start_time": 1700000000,
"status": "extracting"
}
]
}
Error CodeTitleDescriptionResolution

Get the history of past extractions (successful and failed), wherever they ran. Lists only the jobs whose every path (directory and file, or archive and destination) the caller may read. A rule that only lists a directory does not count: with /alice:rw the root is only listed, so the caller sees no job outside /alice. The extraction_history query parameter is required and must be the empty string.

NameInTypeRequiredDescription
extraction_historyquerystringYesEmpty literal value triggers the extraction history listing
Terminal window
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/projects/my-project?extraction_history" \
-H "Authorization: Bearer $HOODY_TOKEN"

The extraction history, including successful and failed jobs. Each history record’s status is one of active, completed, failed, cancelled, or interrupted (where interrupted means the server stopped while the job ran).

{
"history": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"archive_path": "/projects/my-project/data.zip",
"dest_path": "/projects/my-project/data",
"extracted_bytes": 1048576,
"extracted_files": 24,
"start_time": 1700000000,
"end_time": 1700000010,
"status": "completed",
"selective": false,
"selective_path": null,
"total_bytes": 1048576,
"total_files": 24,
"skipped": [],
"skipped_count": 0,
"error": null
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"archive_path": "/projects/my-project/bad.zip",
"dest_path": "/projects/my-project/bad",
"extracted_bytes": 0,
"extracted_files": 0,
"start_time": 1700000020,
"end_time": 1700000021,
"status": "failed",
"selective": true,
"selective_path": "src/",
"total_bytes": 1048576,
"total_files": 24,
"error": "Invalid archive format"
}
]
}
Error CodeTitleDescriptionResolution

Stop a running extraction, whether it was started on the REST surface or the WebDAV-style one. The request that started it then answers 409 with its error field naming the cancellation, and its history record has status cancelled. This operation needs write permission on the root.

NameInTypeRequiredDescription
idpathstringYesThe id listed by GET /api/v1/extractions
Terminal window
curl -X DELETE "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/extractions/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $HOODY_TOKEN"

The extraction was told to stop.

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"message": "Extraction cancellation requested",
"success": true
}
Error CodeTitleDescriptionResolution