Remote Storage Connections
Section titled “Remote Storage Connections”The endpoints on this page let you read from and write to external backends through a container-scoped files service. Each backend (FTP, Git, S3, SSH/SFTP) is selected via the type query parameter and accepts its own connection and authentication fields. Use these endpoints when you need to fetch a file from a Git repository, list or download objects from S3-compatible storage, or read/write files on a remote server over FTP or SSH.
All requests are issued against the per-container files host:
https://{projectId}-{containerId}-files-1.{server}.containers.hoody.icu
The examples below use the placeholder host https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu — substitute your own projectId, containerId, and server values.
Remote Storage
Section titled “Remote Storage”GET /{path}?type=ftp
Section titled “GET /{path}?type=ftp”Connect to an FTP server and read a file or list a directory. The path is the remote path relative to the FTP root, and server is the FTP host (optionally with :port).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Remote file or directory path on the FTP server |
type | query | string | Yes | Backend type. Must be ftp |
server | query | string | Yes | FTP server hostname (optionally with :port) |
user | query | string | No | FTP username. Default: "anonymous" |
pass | query | string | No | FTP password |
ftp_secure | query | boolean | No | Use FTPS (FTP over TLS). Default: false |
ftp_passive | query | boolean | No | Use passive mode. Default: true |
curl -X GET "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/reports/2024/q1.csv?type=ftp&server=ftp.example.com&user=admin&pass=c2VjcmV0MTIz&ftp_secure=false&ftp_passive=true"await client.files.ftp.access("reports/2024/q1.csv", { type: "ftp", server: "ftp.example.com", user: "admin", pass: "c2VjcmV0MTIz", ftp_secure: false, ftp_passive: true});Response
Section titled “Response”{ "description": "File content or directory listing"}The response body is the raw file content (binary) for files, or a directory listing for paths ending in /.
GET /{path}?type=git
Section titled “GET /{path}?type=git”Fetch a file from a Git repository hosted on GitHub, GitLab, Bitbucket, or a custom Git server. The path is the file path inside the repository.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | File path inside the repository |
type | query | string | Yes | Backend type. Must be git |
url | query | string | Yes | Full GitHub/GitLab/Bitbucket URL or repository URL |
ref | query | string | No | Branch, tag, or commit (defaults to HEAD or extracted from URL) |
pass | query | string | No | Personal Access Token (base64 encoded) for private repos |
curl -X GET "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/src/index.ts?type=git&url=https://github.com/example/repo&ref=main&pass=Y2l0YWRiX0FBY2Nlc3NfVG9rZW5fMTIzNDU2Nzg5MA=="await client.files.git.fetch("src/index.ts", { type: "git", url: "https://github.com/example/repo", ref: "main", pass: "Y2l0YWRiX0FBY2Nlc3NfVG9rZW5fMTIzNDU2Nzg5MA=="});Response
Section titled “Response”{ "content": { "application/octet-stream": { "schema": { "format": "binary", "type": "string" } } }, "description": "File content"}The response body is the raw file bytes (application/octet-stream).
GET /{path}?type=s3
Section titled “GET /{path}?type=s3”Access an object in AWS S3 or an S3-compatible store (MinIO, DigitalOcean Spaces, etc.). The path is the object key within the bucket.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Object key inside the bucket |
type | query | string | Yes | Backend type. Must be s3 |
server | query | string | Yes | S3 server hostname (optionally with :port) |
s3_bucket | query | string | Yes | S3 bucket name |
s3_region | query | string | Yes | S3 region |
user | query | string | No | AWS Access Key ID |
pass | query | string | No | AWS Secret Key (base64 encoded) |
s3_endpoint | query | string | No | Custom S3 endpoint for MinIO, etc. |
curl -X GET "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/data/2024-01-15/events.jsonl?type=s3&server=s3.amazonaws.com&s3_bucket=my-bucket&s3_region=us-east-1&user=AKIAIOSFODNN7EXAMPLE&pass=d2VsbHN0b3JlZHNlY3JldGtleQ==&s3_endpoint=https://s3.us-east-1.amazonaws.com"await client.files.s3.access("data/2024-01-15/events.jsonl", { type: "s3", server: "s3.amazonaws.com", s3_bucket: "my-bucket", s3_region: "us-east-1", user: "AKIAIOSFODNN7EXAMPLE", pass: "d2VsbHN0b3JlZHNlY3JldGtleQ==", s3_endpoint: "https://s3.us-east-1.amazonaws.com"});Response
Section titled “Response”{ "description": "Object content or listing"}The response body is the raw object bytes for keys, or an object listing for prefixes.
GET /{path}?type=ssh
Section titled “GET /{path}?type=ssh”Connect to a remote SSH/SFTP server and read a file or list a directory. Supports both password and private-key authentication.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Remote file or directory path |
type | query | string | Yes | Backend type. Must be ssh |
server | query | string | Yes | Server hostname:port |
user | query | string | Yes | SSH username |
pass | query | string | No | Password (base64 encoded) |
key | query | string | No | Private key PEM (base64 encoded) |
passphrase | query | string | No | Key passphrase (base64 encoded) |
curl -X GET "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/var/log/app.log?type=ssh&server=10.0.0.5:22&user=deploy&pass=c3NoLXBhc3N3b3Jk"await client.files.ssh.access("var/log/app.log", { type: "ssh", server: "10.0.0.5:22", user: "deploy", pass: "c3NoLXBhc3N3b3Jk"});Response
Section titled “Response”{ "content": { "application/octet-stream": { "schema": { "format": "binary", "type": "string" } } }, "description": "File content or directory listing"}The response body is the raw file bytes for files, or an application/octet-stream directory listing for directories.
PUT /{path}?type=ssh
Section titled “PUT /{path}?type=ssh”Upload a file to a remote SSH/SFTP server. The body of the request is the raw file content as application/octet-stream.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Remote destination file path |
server | query | string | Yes | Server hostname:port |
user | query | string | Yes | SSH username |
pass | query | string | No | Password (base64 encoded) |
key | query | string | No | Private key PEM (base64 encoded) |
passphrase | query | string | No | Key passphrase (base64 encoded) |
Request Body
Section titled “Request Body”Send the file contents as the request body with content type application/octet-stream. There are no structured body fields.
curl -X PUT "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/var/www/app/releases/1.4.2/bundle.tar.gz?server=10.0.0.5:22&user=deploy&pass=c3NoLXBhc3N3b3Jk" \ -H "Content-Type: application/octet-stream" \ --data-binary "@./bundle.tar.gz"const fs = await import("node:fs");
await client.files.ssh.upload("var/www/app/releases/1.4.2/bundle.tar.gz", { server: "10.0.0.5:22", user: "deploy", pass: "c3NoLXBhc3N3b3Jk"}, { body: fs.readFileSync("./bundle.tar.gz")});Response
Section titled “Response”{ "description": "File uploaded"}{ "description": "Upload exceeds the configured max upload size"}Authentication
Section titled “Authentication”CHECKAUTH /{path}
Section titled “CHECKAUTH /{path}”Verify the current authentication status for the files service. The response body contains the authenticated username, or an empty string when not authenticated.
This endpoint uses the non-standard CHECKAUTH HTTP method.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Any path within the files service |
curl -X CHECKAUTH "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/"const username = await client.files.authentication.checkAuth("/");Response
Section titled “Response”{ "content": { "text/plain": { "description": "Authenticated username or empty string", "schema": { "type": "string" } } }, "description": "Authentication status"}The response body is a plain text string: the authenticated username, or empty when no credentials are present.
LOGOUT /{path}
Section titled “LOGOUT /{path}”Clear authentication for the files service. The response includes a WWW-Authenticate header that forces the client to discard stored credentials.
This endpoint uses the non-standard LOGOUT HTTP method.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | Yes | Any path within the files service |
curl -X LOGOUT "https://prj_d8f7e2-c_4a9b1c-files-1.us-east.containers.hoody.icu/"await client.files.authentication.logout("/");Response
Section titled “Response”{ "description": "Authentication cleared", "headers": { "WWW-Authenticate": { "description": "Authentication challenge to force credential clearing", "schema": { "type": "string" } } }}The WWW-Authenticate response header is set so browsers and HTTP clients discard any cached credentials.