Skip to content
Hoody.com

The Containers API provides full lifecycle control of Hoody containers: list, retrieve, monitor, authorize, create, update, and delete containers, both globally across all projects and scoped to a single project. Use these endpoints to manage container settings (KVM, ramdisk scope, autostart, environment variables, SSH keys, realm membership), inspect live resource statistics and per-month proxied-request usage, and issue short-lived ED25519-signed container claims that programs inside the container can verify offline.

Get all containers across all projects for the current user with pagination, filtering, and sorting. This endpoint provides a global view of all containers without being scoped to a specific project. environment_vars is always {} in this response: read the variables with GET /api/v1/containers/{id}/env.

NameInTypeRequiredDescription
pagequerynumberNoPage number for pagination, starts from 1. Default: 1.
limitquerynumberNoNumber of containers to return per page, maximum 100 items. Default: 50.
sort_byquerystringNoField to sort containers by. Allowed values: id, name, status, created_at, updated_at. Default: created_at.
sort_orderquerystringNoSort direction. Allowed values: asc, desc. Default: desc.
realm_idquerystringNoFilter by realm ID. Only returns containers that belong to this realm. Alternative to using a realm subdomain in the URL.
runtimequerystringNoInclude live runtime information. Accepts true, false, or a URL-encoded JSON string like {"displays":true}. An empty JSON object {} fetches all info. Runtime information may be up to 2 seconds old.
include_proxy_domainsquerybooleanNoInclude proxy domains (aliases) for each container. When true, adds a proxy_domains array to each container object.
include_proxy_permissionsquerybooleanNoInclude the full proxy-permissions documents (container-level proxy_permissions and parent-project-level project_proxy_permissions) for each container. Returns proxy authentication group configuration including credentials, request only when explicitly needed. Auth tokens additionally require the resources.proxy_aliases permission.
include_expiredquerybooleanNoInclude containers that have expired due to server termination. By default, expired containers are excluded.
include_deletingquerybooleanNoInclude containers currently being deleted. By default, deleting containers are excluded.
Terminal window
curl -X GET 'https://api.hoody.com/api/v1/containers/?page=1&limit=50' \
-H 'Authorization: Bearer <token>'

Get all containers for a single project with pagination, filtering, and sorting. environment_vars is always {} in this response: read the variables with GET /api/v1/containers/{id}/env.

NameInTypeRequiredDescription
pagequerynumberNoPage number for pagination, starts from 1.
limitquerynumberNoNumber of containers to return per page. Default: 50.
sort_byquerystringNoField to sort containers by. Allowed values: id, name, status, created_at, updated_at.
sort_orderquerystringNoSort direction. Allowed values: asc, desc.
runtimequerystringNoInclude live runtime information. Accepts true, false, or a URL-encoded JSON string like {"displays":true}. An empty JSON object {} fetches all info. Runtime information may be up to 2 seconds old.
include_proxy_domainsquerybooleanNoInclude proxy domains (aliases) for each container.
include_proxy_permissionsquerybooleanNoInclude the full proxy-permissions documents for each container. Auth tokens additionally require the resources.proxy_aliases permission.
include_expiredquerybooleanNoInclude containers that have expired due to server termination.
include_deletingquerybooleanNoInclude containers currently being deleted.
idpathstringYesUnique identifier of the project.
Terminal window
curl -X GET 'https://api.hoody.com/api/v1/projects/67e89abc123def456789abcd/containers?page=1&limit=20' \
-H 'Authorization: Bearer <token>'

Retrieve a single container by ID, with optional live runtime information, proxy domains, and full proxy-permissions documents.

NameInTypeRequiredDescription
idpathstringYesUnique identifier of the container to retrieve.
runtimequerystringNoInclude live runtime information. Accepts true, false, or a URL-encoded JSON string like {"displays":true}. An empty JSON object {} fetches all info. Runtime information may be up to 2 seconds old.
include_proxy_domainsquerybooleanNoInclude proxy domains (aliases) for this container.
include_proxy_permissionsquerybooleanNoInclude the full proxy-permissions documents. Auth tokens additionally require the resources.proxy_aliases permission.
Terminal window
curl -X GET 'https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef' \
-H 'Authorization: Bearer <token>'

Per-month proxied request counts and response bytes for one container.

Counts completed, routed, non-excluded HTTP responses only. They do not include forward-proxy/CONNECT egress, direct SSH, raw container egress, or WebSocket sessions until they close. Live containers only are reported; deleted containers are excluded. The totals field sums the documents actually returned. It is NOT comprehensive whenever coverage_complete is false (some usage could not be read, or a month is no longer available), and totals always excludes deleted containers. totals.exact is false if a sum exceeded the exact integer range. Older months are kept only if they were read before they expired, so a month never queried in time may be gone permanently. A month withdrawn by an ownership change stops being served.

NameInTypeRequiredDescription
fromquerystringYesFirst month, inclusive (YYYY-MM).
toquerystringYesLast month, inclusive (YYYY-MM). Maximum 12 months.
idpathstringYesContainer ID.
Terminal window
curl -X GET 'https://api.hoody.com/api/v1/containers/67e89abc123def456789abcd/proxy-usage?from=2025-01&to=2025-03' \
-H 'Authorization: Bearer <token>'

Get real-time resource usage statistics for a container, including CPU, memory, disk, network, and ramdisk metrics.

data.started_at is when the container was started, or null when that is not known.

NameInTypeRequiredDescription
idpathstringYesUnique identifier of the container.
Terminal window
curl -X GET 'https://api.hoody.com/api/v1/containers/67e89abc123def456789abcd/stats' \
-H 'Authorization: Bearer <token>'

Issue a signed, portable container authorization claim. The returned container_claim is an ED25519-signed credential that proves who the user is (sub, type), which container they are authorized for (containerId, projectId), and when Hoody issued the authorization (iat, exp).

Container programs can verify this claim offline using Hoody’s public key at GET /api/v1/meta/public-key; no API round-trip is needed during verification.

Claims expire after a few hours (6h by default). expires_in gives the exact lifetime in seconds. Clients should re-call this endpoint to refresh before expiry.

NameInTypeRequiredDescription
idpathstringYesContainer ID (24-character hexadecimal string).
Terminal window
curl -X POST 'https://api.hoody.com/api/v1/containers/67e89abc123def456789abcd/authorize' \
-H 'Authorization: Bearer <token>'

Create a new container inside a project. The container starts in the creating state and progresses to running once provisioning finishes on the chosen server. environment_vars is always {} in this response: read the variables with GET /api/v1/containers/{id}/env.

NameInTypeRequiredDescription
idpathstringYesUnique identifier of the project that will own the new container.
NameTypeRequiredDescription
server_idstringYesUnique identifier of the server that will run the container.
namestringNoHuman-readable name, 3 to 100 characters, alphanumeric with hyphens and underscores. Omit or use "rand" to generate a random name.
colorstringNoHex color for the container (e.g., #FF0000 or FF0000). A # prefix is added automatically if missing, and the color is converted to uppercase.
container_imagestringNoContainer image to use. Bare distribution names and hyphenated versions (debian, debian-13) are resolved to the canonical base image (debian/13), as are debian:13 and debian 13. If null or omitted, the default configured image is used.
aibooleanNoWhether AI features are enabled. Defaults to true for JWT callers; for auth-token callers, defaults to whether the token has containers.features.ai permission.
environment_varsobjectNoObject of environment variables to set in the container. Keys must match ^[a-zA-Z_][a-zA-Z0-9_]*$ and be at most 128 characters long. Maximum 256 keys; each value 1 to 4096 characters.
ssh_public_keystringNoSSH public key for container access. SSH public keys must be unique per container (one container per key). If omitted, the key is inherited from project defaults.
commentstringNoOptional comment for the container, max 16000 characters.
hoody_kitbooleanNoEnable all Hoody Kit features: extra package sources, a package download cache, basic and developer packages, extra shells, the Hoody daemon, sudo setup, snapd removal, web view, desktop, a default user, a web terminal, and VM tooling (about 185 MiB; running VMs additionally needs the separate kvm grant). Defaults to true for JWT callers; for auth-token callers, defaults to whether the token has containers.features.hoody_kit permission.
dev_kitbooleanNoEnable dev_kit development tools in the container. Defaults to true when hoody_kit is true, false otherwise. Cannot be updated after creation.
kvmbooleanNoEnable /dev/kvm passthrough (run full VMs inside the container) at creation. Available on rented or dedicated (bare-metal) servers only, never free tier; rejected with 403 on a free server. Default: false. Can also be toggled later via PUT /api/v1/containers/{id}/kvm on a stopped container.
dev_kvmbooleanNoAccepted alias of kvm on input. If both are sent, kvm wins and the two must agree.
autostartbooleanNoWhether the container starts automatically on host boot. Default: true.
ramdiskbooleanNoWhether to mount a ramdisk at /ramdisk. Keeps data on container stop/start/reboot but LOSES data on a host reboot. Up to 50% of total host memory. Default: true.
cachebooleanNoEnable use of cached images during container creation. When false, the container is built without the image cache. Default: true.
cache_imagebooleanNoForce creation of a new cached image from the container image. Only available to the image owner. Default: false.
realm_idsarrayNoRealm IDs to assign this container to. If creating from a realm subdomain (e.g., https://realm-abc.api.hoody.com), the subdomain realm is automatically included and merged with any explicitly provided realm_ids. Containers can have different realm membership than their parent project.
Terminal window
curl -X POST 'https://api.hoody.com/api/v1/projects/67e89abc123def456789abcd/containers' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"server_id": "111abcdef12345678901aaaa",
"name": "backend-api",
"container_image": "debian/13",
"ai": true,
"environment_vars": {
"DATABASE_URL": "postgresql://user:pass@db:5432/app",
"REDIS_URL": "redis://cache:6379"
},
"ssh_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl user@host",
"comment": "Backend API server with PostgreSQL connection",
"autostart": true,
"ramdisk": true
}'

Also accepted: PATCH (same endpoint, identical behaviour).

Update an existing container’s editable settings, including environment variables, autostart, ramdisk configuration, SSH key, comment, and realm membership. Omitted fields are preserved.

NameInTypeRequiredDescription
idpathstringYesUnique identifier of the container to update.
NameTypeRequiredDescription
namestringNoHuman-readable name for the container, at most 100 characters. Must be unique within the project; a name the server refuses answers INVALID_CONTAINER_NAME.
colorstringNoHex color for the container (e.g., #FF0000 or FF0000). A # prefix is added automatically if missing, and the color is converted to uppercase.
aibooleanNoWhether AI features are enabled. If omitted, the current value is preserved.
autostartbooleanNoWhether the container starts automatically on host boot. If omitted, the current value is preserved.
ramdisk_scopestringNoSharing scope for /ramdisk. Allowed values: container, project. container (default) mounts only private storage. project additionally mounts /ramdisk/project, shared with other containers in this project on the same server (a RAM disk cannot span servers). Refused when the project has other members.
ramdiskbooleanNoWhether to mount a ramdisk at /ramdisk. If omitted, the current value is preserved. Counts against memory rather than disk. Data survives container restarts but is lost on a host reboot.
environment_varsobjectNoEnvironment variables to set in the container as key-value pairs. Keys must match ^[a-zA-Z_][a-zA-Z0-9_]*$ and be at most 128 characters long. Maximum 256 keys; each value 1 to 4096 characters.
ssh_public_keystringNoSSH public key for direct SSH access. Keys are globally unique (one container per key). Re-sending the same key for the same container is a no-op and completes an earlier change that did not finish. Set to null to remove the key: direct SSH stops accepting it within about a minute, an already-open session is closed shortly after, and the key becomes installable again afterwards. An empty or whitespace-only string is rejected with 400 (send null to remove). Requires a token with the ssh-keys resource permission to set or replace; removal needs only container update permission.
commentstringNoOptional comment for the container, max 16000 characters. Set to null to clear an existing comment.
realm_idsarrayNoUpdate realm membership for this container. Containers can have different realm membership than their parent project. A signed-in session (JWT) or an unrestricted auth token can modify realm_ids; realm-restricted tokens cannot change realm membership.
Terminal window
curl -X PUT 'https://api.hoody.com/api/v1/containers/890abcdef12345678901cdef' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "web-app-1-renamed",
"color": "#FF0000",
"autostart": true,
"ramdisk_scope": "container",
"ramdisk": true,
"environment_vars": {
"NODE_ENV": "production",
"LOG_LEVEL": "info"
},
"comment": "Renamed after refactor"
}'

Also accepted: PATCH (same endpoint, identical behaviour).

Enable or disable hardware virtualization passthrough (/dev/kvm) so the container can run full virtual machines. Available on rented or dedicated (bare-metal) servers only, never on free-tier servers. The container must be stopped. Send kvm: true to enable or kvm: false to disable. dev_kvm is accepted as an alias of kvm.

The SDK reaches this same operation through two named methods:

  • client.api.containers.enableKvm(id) sends kvm: true and refuses dev_kvm.
  • client.api.containers.disableKvm(id) sends kvm: false and refuses dev_kvm.
NameInTypeRequiredDescription
idpathstringYesUnique identifier of the container.
NameTypeRequiredDescription
kvmbooleanNoEnable (true) or disable (false) /dev/kvm passthrough (run VMs in the container). Rented or dedicated servers only; the container must be stopped.
dev_kvmbooleanNoAccepted alias of kvm on input. If both are sent, kvm wins and the two must agree.
Terminal window
curl -X PUT 'https://api.hoody.com/api/v1/containers/67e89abc123def456789abcd/kvm' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{ "kvm": true }'

Delete a container and release its name, SSH key, and project/server quotas.

NameInTypeRequiredDescription
idpathstringYesUnique identifier of the container to delete.
Terminal window
curl -X DELETE 'https://api.hoody.com/api/v1/containers/67e89abc123def456789abcd' \
-H 'Authorization: Bearer <token>'