Container Copy & Sync
Section titled “Container Copy & Sync”These endpoints duplicate an existing container into a different project or server, and synchronize a previously-copied container with its source. Both operations run asynchronously; the new or target container transitions to running once the background job finishes.
Use copy to provision a working duplicate of a base container, and sync to pull incremental updates from the original after the copy exists.
Copy a container
Section titled “Copy a container”POST /api/v1/containers/{id}/copy
Creates an asynchronous copy of an existing container. The new container starts automatically on success.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the source container to copy |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
target_project_id | string | Yes | ID of the project where the copy will be created |
target_server_id | string | No | ID of the server where the copy will be created (defaults to source server) |
name | string | No | Name for the copied container (auto-generated if not provided) |
ssh_public_key | string | No | SSH public key for the copied container (must be unique, not inherited from source) |
source_snapshot | string | No | Specific snapshot to copy from (copies latest state if not provided) |
copy_firewall_rules | boolean | No | Whether to copy firewall rules (ACL) from source container to target container. Default: false |
copy_network_rules | boolean | No | Whether to copy network rules/settings from source container to target container. Default: false |
curl -X POST "https://api.hoody.icu/api/v1/containers/507f1f77bcf86cd799439011/copy" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "target_project_id": "507f1f77bcf86cd799439033", "target_server_id": "507f1f77bcf86cd799439044", "name": "web-app-staging", "copy_firewall_rules": true, "copy_network_rules": true }'const result = await client.api.containers.copy({ id: "507f1f77bcf86cd799439011", data: { target_project_id: "507f1f77bcf86cd799439033", target_server_id: "507f1f77bcf86cd799439044", name: "web-app-staging", copy_firewall_rules: true, copy_network_rules: true }});{ "statusCode": 201, "message": "Container copy initiated successfully", "data": { "id": "507f1f77bcf86cd799439099", "name": "web-app-staging", "status": "copying", "source_container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "project_alias": "production", "server_id": "507f1f77bcf86cd799439044", "server_name": "node-sg-sin-1", "subserver_name": "web-app-staging", "server": { "name": "node-sg-sin-1", "country": "SG", "country_name": "Singapore", "city": "Singapore", "region": "Asia Pacific", "datacenter": "SIN-DC1", "is_free": true, "specs": { "cpu_cores": null, "ram_gb": null, "disk_gb": 20, "shared_compute": true } }, "ssh_hostname": "507f1f77bcf86cd799439033-507f1f77bcf86cd799439099-ssh.node-sg-sin-1.containers.hoody.icu", "color": "#3B82F6", "container_image": "ubuntu:22.04", "ai": false, "hoody_kit": true, "dev_kit": true, "autostart": true, "ramdisk": false, "prespawn": false, "is_default": false, "container_image_id": null, "environment_vars": {}, "volumes": {}, "ssh_public_key": null, "comment": null, "copy_firewall_rules": true, "copy_network_rules": true, "created_at": "2026-01-15T10:30:00.000Z", "updated_at": "2026-01-15T10:30:00.000Z", "realm_ids": [] }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid container name"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Invalid input parameters | One or more request parameters failed validation | Check the error message for specific field requirements and correct your input |
INVALID_ID_FORMAT | Invalid ID format | The provided ID must be a 24-character hexadecimal string | Ensure the ID is exactly 24 characters long and contains only hexadecimal characters (0-9, a-f) |
INVALID_CONTAINER_NAME | Invalid container name | Container name must be 3-100 characters, alphanumeric with hyphens and underscores. | Use a valid name between 3 and 100 characters containing only a-z, A-Z, 0-9, -, and _. |
SERVER_CONTAINER_LIMIT | Server container limit reached | The target server is at its maximum number of live containers (explicit max_containers, or the free-tier default). | Delete an existing container on this server, or create the container on a different server. |
{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication token required"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
MISSING_TOKEN | Authentication token missing | No authentication token was provided in the request | Include a valid JWT token in the Authorization header as Bearer <token> |
INVALID_TOKEN | Invalid authentication token | The provided authentication token is malformed or invalid | Obtain a new token by logging in again or using a valid auth token |
TOKEN_EXPIRED | Authentication token expired | The provided authentication token has expired | Obtain a new token by logging in again or refreshing your session |
{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INSUFFICIENT_PERMISSIONS | Insufficient permissions | You do not have the required permissions to perform this action | Contact the resource owner or administrator to request access |
ACCOUNT_BANNED | Account banned | Your account has been banned and cannot access this resource | Contact support for information about your account status |
{ "statusCode": 404, "error": "Not Found", "message": "Source container not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
SOURCE_CONTAINER_NOT_FOUND | Source container not found | The source container specified for a copy or sync operation does not exist. | Verify the source container ID is correct. |
RESOURCE_NOT_FOUND | Resource not found | The requested resource does not exist or has been deleted | Verify the resource ID and ensure it exists |
{ "statusCode": 409, "error": "Conflict", "message": "Container name already in use within the project"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_NAME_IN_USE | Container name already in use | A container with this name already exists in the project. | Choose a different name for your container. |
SSH_PUBLIC_KEY_IN_USE | SSH public key already in use | SSH public keys must be unique per container. A single public key cannot be assigned to multiple containers because it is used for routing SSH connections. | Generate a new SSH key pair for this container, or remove the key from the other container before reusing it. |
OPERATION_STATE_CONFLICT | Container State Conflict | The operation cannot be performed because the container is not in the correct state. | Check the container’s current status. For example, a container must be stopped to be started. |
Sync a container
Section titled “Sync a container”POST /api/v1/containers/{id}/sync
Performs an incremental sync from the source container to this container. Only works for containers that were created via the copy operation. The sync runs asynchronously.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container to sync (must have been created via copy) |
This endpoint takes no request body.
curl -X POST "https://api.hoody.icu/api/v1/containers/507f1f77bcf86cd799439099/sync" \ -H "Authorization: Bearer <token>"const result = await client.api.containers.sync({ id: "507f1f77bcf86cd799439099"});{ "statusCode": 200, "message": "Container sync initiated successfully", "data": { "container_id": "507f1f77bcf86cd799439099", "source_container_id": "507f1f77bcf86cd799439011", "status": "copying" }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid ID format"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INVALID_ID_FORMAT | Invalid ID format | The provided ID must be a 24-character hexadecimal string | Ensure the ID is exactly 24 characters long and contains only hexadecimal characters (0-9, a-f) |
SERVER_CONTAINER_LIMIT | Server container limit reached | The target server is at its maximum number of live containers (explicit max_containers, or the free-tier default). | Delete an existing container on this server, or create the container on a different server. |
{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication token required"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
MISSING_TOKEN | Authentication token missing | No authentication token was provided in the request | Include a valid JWT token in the Authorization header as Bearer <token> |
INVALID_TOKEN | Invalid authentication token | The provided authentication token is malformed or invalid | Obtain a new token by logging in again or using a valid auth token |
TOKEN_EXPIRED | Authentication token expired | The provided authentication token has expired | Obtain a new token by logging in again or refreshing your session |
{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INSUFFICIENT_PERMISSIONS | Insufficient permissions | You do not have the required permissions to perform this action | Contact the resource owner or administrator to request access |
ACCOUNT_BANNED | Account banned | Your account has been banned and cannot access this resource | Contact support for information about your account status |
{ "statusCode": 404, "error": "Not Found", "message": "Container not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_NOT_FOUND | Container not found | The requested container does not exist or you do not have permission to access it. | Verify the container ID is correct and that you have access to the project it belongs to. |
{ "statusCode": 409, "error": "Conflict", "message": "Container was not created from a copy, sync is not possible."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_NOT_COPIED | Container Not a Copy | The sync operation can only be performed on a container that was created by copying another. | This operation is only valid for containers with a source_container_id. |
OPERATION_STATE_CONFLICT | Container State Conflict | The operation cannot be performed because the container is not in the correct state. | Check the container’s current status. For example, a container must be stopped to be started. |