The Hoody Files API provides operations for working with directories and archive files (ZIP, TAR, and compressed TAR variants). This page covers extraction history and active progress, full and selective archive extraction, previewing archive contents, reading individual files from inside archives, downloading directories as ZIP archives, and creating new directories.
Archives
Section titled “Archives”Extraction history and progress
Section titled “Extraction history and progress”Use these endpoints to monitor past and ongoing archive extractions. The history endpoint returns completed and failed runs, while the active endpoints return progress for extractions currently underway.
GET /?extraction_history
Section titled “GET /?extraction_history”Returns the history of past archive extractions, including both successful and failed runs. Use this to audit what archives have been opened or to investigate extraction failures.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
extraction_history | query | string | Yes | Literal empty string flag (value must be "") that enables extraction history listing |
Request
curl "https://api.example.com/?extraction_history="await client.files.archives.getHistory({ extraction_history: "" });Response
{ "history": [ { "id": "a3f1b2c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c", "archive_path": "/uploads/release-v2.1.zip", "dest_path": "/uploads/release-v2.1", "status": "completed", "selective": false, "selective_path": null, "start_time": 1703001234, "end_time": 1703001245, "extracted_bytes": 52428800, "extracted_files": 142, "total_bytes": 52428800, "total_files": 142, "error": null }, { "id": "b4c5d6e7-8f9a-0b1c-2d3e-4f5a6b7c8d9e", "archive_path": "/uploads/dataset.tar.gz", "dest_path": "/uploads/dataset-failed", "status": "failed", "selective": true, "selective_path": "lib/", "start_time": 1702900000, "end_time": 1702900010, "extracted_bytes": 0, "extracted_files": 0, "total_bytes": 104857600, "total_files": 512, "error": "ZIP_BOMB_DETECTED" } ]}GET /?extractions
Section titled “GET /?extractions”Returns progress for archive extractions currently running within this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
extractions | query | string | Yes | Literal empty string flag (value must be "") that enables listing active extractions |
Request
curl "https://api.example.com/?extractions="await client.files.archives.listActive({ extractions: "" });Response
{ "extractions": [ { "id": "c5d6e7f8-9a0b-1c2d-3e4f-5a6b7c8d9e0f", "archive_path": "/uploads/dataset.tar.gz", "dest_path": "/uploads/dataset", "status": "extracting", "percentage": 45.2, "start_time": 1703001400, "extracted_bytes": 23592960, "extracted_files": 56, "total_bytes": 52428800, "total_files": 124, "selective": false, "selective_path": null } ]}GET /api/v1/extractions
Section titled “GET /api/v1/extractions”Returns progress for archive extractions currently running across the server as a whole.
This endpoint takes no parameters.
Request
curl "https://api.example.com/api/v1/extractions"await client.files.archives.listGlobal();Response
{ "extractions": [ { "id": "d6e7f8a9-0b1c-2d3e-4f5a-6b7c8d9e0f1a", "archive_path": "/uploads/dataset.tar.gz", "dest_path": "/uploads/dataset", "status": "extracting", "percentage": 45.2, "start_time": 1703001400, "extracted_bytes": 23592960, "extracted_files": 56, "total_bytes": 52428800, "total_files": 124, "selective": false, "selective_path": null } ]}Extracting archives
Section titled “Extracting archives”Use these endpoints to extract ZIP, TAR, or compressed TAR archives. The full extraction endpoint supports extracting an entire archive or a selective subset by prefix. The single-file endpoint extracts only one entry (and its children if it is a directory) from inside the archive.
GET /{archive}?extract
Section titled “GET /{archive}?extract”Extracts a ZIP, TAR, or compressed TAR archive to a destination directory. Pass ?extract with an empty value to extract the entire archive, or ?extract=<path> to extract only entries matching the given prefix.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
archive | path | string | Yes | Path to the archive file to extract |
extract | query | string | Yes | Empty value for full extraction; a path (e.g. src/ or lib/) for selective extraction |
dest | query | string | No | Destination directory name (defaults to the archive name) |
Request
curl "https://api.example.com/uploads/release-v2.1.zip?extract=src/&dest=release-v2.1-src"await client.files.archives.extract({ archive: "/uploads/release-v2.1.zip", extract: "src/", dest: "release-v2.1-src"});Response
{ "success": true, "message": "Archive extracted successfully", "extraction_id": "e7f8a9b0-1c2d-3e4f-5a6b-7c8d9e0f1a2b", "destination": "/uploads/release-v2.1-src", "extracted_files": 18, "extracted_bytes": 1048576, "selective": true, "selective_path": "src/"}{ "success": false, "message": "Extraction failed", "extraction_id": "e7f8a9b0-1c2d-3e4f-5a6b-7c8d9e0f1a2b", "destination": "/uploads/release-v2.1", "extracted_files": 0, "extracted_bytes": 0, "error": "INVALID_ARCHIVE_FORMAT", "selective": false, "selective_path": null}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_ARCHIVE_FORMAT | Invalid archive format | File is not a valid archive or format is unsupported | Verify file is a supported archive format (zip, tar, tar.gz, tar.bz2, tar.xz) |
ARCHIVE_TOO_LARGE | Archive exceeds size limit | Archive total size exceeds configured maximum extraction size | Contact administrator to increase extraction size limit or extract manually |
TOO_MANY_FILES | Too many files in archive | Archive contains more files than allowed maximum | Contact administrator to increase file count limit or extract in smaller batches |
ZIP_BOMB_DETECTED | Potential zip bomb detected | Archive has suspicious compression ratio indicating potential zip bomb | Verify archive source is trusted, contact administrator if legitimate |
PATH_TRAVERSAL_BLOCKED | Path traversal attempt blocked | Archive contains files attempting to escape extraction directory | Archive may be malicious, verify source and re-create archive without path traversal |
{ "success": false, "error": "EXTRACTION_FORBIDDEN"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
EXTRACTION_FORBIDDEN | Extraction not allowed | Server is not configured to allow archive extraction | Contact administrator to enable --allow-extract flag |
GET /{archive}?extract_file
Section titled “GET /{archive}?extract_file”Extracts 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 it is a directory) is extracted, leaving the rest of the archive contents untouched.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
archive | path | string | Yes | Path to archive file |
extract | query | string | Yes | Path of the file or directory inside the archive to extract (e.g. src/ or lib/) |
dest | query | string | No | Destination directory name (defaults to the archive name) |
Request
curl "https://api.example.com/uploads/release-v2.1.zip?extract_file&extract=src/main.rs&dest=release-v2.1"await client.files.archives.extractFile({ archive: "/uploads/release-v2.1.zip", extract: "src/main.rs", dest: "release-v2.1"});Response
{ "success": true, "message": "Entry extracted successfully", "extraction_id": "f8a9b0c1-2d3e-4f5a-6b7c-8d9e0f1a2b3c", "destination": "/uploads/release-v2.1", "extracted_files": 1, "extracted_bytes": 4096, "selective": true, "selective_path": "src/main.rs"}{ "success": false, "message": "Extraction failed", "extraction_id": "f8a9b0c1-2d3e-4f5a-6b7c-8d9e0f1a2b3c", "destination": "/uploads/release-v2.1", "extracted_files": 0, "extracted_bytes": 0, "error": "INVALID_SELECTIVE_PATH", "selective": true, "selective_path": "../etc/passwd"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_ARCHIVE_FORMAT | Invalid archive format | File is not a valid archive or format is unsupported | Verify file is a supported archive format (zip, tar, tar.gz, tar.bz2, tar.xz) |
INVALID_SELECTIVE_PATH | Invalid entry path | The entry path is invalid (empty, absolute, contains traversal, or null bytes) | Use a relative path without .. components (e.g. src/ or lib/) |
NO_MATCHING_ENTRIES | No matching entries | No entries in the archive matched the specified path | Use previewArchive to list archive contents and verify the entry path |
PATH_TRAVERSAL_BLOCKED | Path traversal attempt blocked | Archive contains files attempting to escape extraction directory | Archive may be malicious, verify source and re-create archive without path traversal |
{ "success": false, "error": "EXTRACTION_FORBIDDEN"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
EXTRACTION_FORBIDDEN | Extraction not allowed | Server is not configured to allow archive extraction | Contact administrator to enable --allow-extract flag |
{ "success": false, "error": "Archive file not found"}Previewing and reading archives
Section titled “Previewing and reading archives”Use these endpoints to inspect archive contents or read a single file without extracting the entire archive. The preview endpoint accepts an empty flag to list all entries, or a path to read a specific file. The viewFile endpoint always reads a single file and returns its raw content with an auto-detected MIME type.
GET /{archive}?preview
Section titled “GET /{archive}?preview”Lists the contents of a ZIP, TAR, or compressed TAR archive, or reads a single file from it. With an empty ?preview value, returns a JSON listing of all entries. With ?preview=<path>, returns the raw content of that file. The ?preview and ?contents query parameters are aliases.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
archive | path | string | Yes | Path to archive file |
preview | query | string | No | Empty value lists archive contents; non-empty value reads a specific file from the archive (alias for ?contents) |
contents | query | string | No | Alias for ?preview |
Request
curl "https://api.example.com/uploads/release-v2.1.zip?preview="await client.files.archives.preview({ archive: "/uploads/release-v2.1.zip", preview: ""});Response
{ "format": "zip", "total_files": 142, "total_size": 52428800, "total_compressed_size": 31457280, "entries": [ { "path": "src/", "is_dir": true, "entry_type": "directory", "size": 0, "compressed_size": null, "modified_time": 1702000000, "permissions": 16877, "link_target": null }, { "path": "src/main.rs", "is_dir": false, "entry_type": "file", "size": 4096, "compressed_size": 1024, "modified_time": 1702000000, "permissions": 33188, "link_target": null } ]}{ "success": false, "error": "INVALID_ARCHIVE_FORMAT"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_ARCHIVE_FORMAT | Invalid archive format | File is not a valid ZIP, TAR, or compressed TAR archive | Verify file is a valid archive and format is supported (zip, tar, tar.gz, tar.bz2, tar.xz) |
CORRUPTED_ARCHIVE | Corrupted archive | Archive file is corrupted or incomplete | Re-download or re-upload the archive file |
{ "success": false, "error": "Archive entry is password-protected"}{ "success": false, "error": "Archive file or entry not found"}{ "success": false, "error": "File too large for preview"}GET /{archive}?view_file
Section titled “GET /{archive}?view_file”Reads and returns a single file from inside a ZIP, TAR, or compressed TAR archive without extracting the entire archive. The response is the raw file content with an auto-detected MIME type, useful for inspecting individual files before deciding to extract the whole archive.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
archive | path | string | Yes | Path to archive file |
preview | query | string | Yes | Path of the file inside the archive to view (e.g. src/ or README.md) |
Request
curl "https://api.example.com/uploads/release-v2.1.zip?view_file&preview=README.md"await client.files.archives.viewFile({ archive: "/uploads/release-v2.1.zip", preview: "README.md"});Response
Returns the raw file content with an auto-detected MIME type (application/octet-stream or more specific).
{ "success": false, "error": "INVALID_SELECTIVE_PATH"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_ARCHIVE_FORMAT | Invalid archive format | File is not a valid ZIP, TAR, or compressed TAR archive | Verify file is a valid archive and format is supported (zip, tar, tar.gz, tar.bz2, tar.xz) |
INVALID_SELECTIVE_PATH | Invalid entry path | The entry path is invalid (empty, absolute, contains traversal, or null bytes) | Use a relative path without .. components (e.g. src/) |
{ "success": false, "error": "Archive entry is password-protected"}{ "success": false, "error": "Archive file or entry not found"}{ "success": false, "error": "File too large for preview"}Downloading directories as ZIP
Section titled “Downloading directories as ZIP”GET /{directory}?zip
Section titled “GET /{directory}?zip”Packages an existing directory into a ZIP archive and downloads it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
directory | path | string | Yes | Path of the directory to download as ZIP |
zip | query | string | Yes | Literal empty string flag (value must be "") that triggers ZIP download |
Request
curl "https://api.example.com/uploads/my-project?zip=" -o my-project.zipawait client.files.archives.downloadAsZip({ directory: "/uploads/my-project", zip: ""});Response
Returns the binary ZIP archive (application/zip).
{ "success": false, "error": "Archive download not allowed"}Directories
Section titled “Directories”Creating directories
Section titled “Creating directories”The create directory endpoint uses the WebDAV MKCOL method to create new directories on the server.
MKCOL /{path}
Section titled “MKCOL /{path}”Creates a new directory at the specified path.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Path of the new directory to create |
Request
curl -X MKCOL "https://api.example.com/uploads/new-folder"await client.files.directories.create({ path: "/uploads/new-folder" });Response
Directory created. No response body.
{ "success": false, "error": "UPLOAD_FORBIDDEN"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
UPLOAD_FORBIDDEN | Directory creation not allowed | Server is not configured to allow directory creation | Contact administrator to enable --allow-upload flag |
INSUFFICIENT_PERMISSIONS | Insufficient permissions | User account does not have write permissions for this path | Contact administrator for write permissions |
{ "success": false, "error": "DIRECTORY_EXISTS"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
DIRECTORY_EXISTS | Directory already exists | A directory with this name already exists at the specified path | Choose a different name or delete the existing directory first |