Container Copy & Sync
Section titled “Container Copy & Sync”Use these endpoints to clone a container to another project or server, and to incrementally sync a previously copied container with its source. Both operations run asynchronously; the new or updated container starts automatically when processing completes.
POST /api/v1/containers/{id}/copy
Section titled “POST /api/v1/containers/{id}/copy”Creates a copy of an existing container. The copy operation runs asynchronously and the new container will start automatically upon successful completion.
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 | Default | Description |
|---|---|---|---|---|
target_project_id | string | Yes | — | ID of the project where the copy will be created (24-character hex) |
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 (3–100 chars, alphanumeric with - and _) |
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 | false | Whether to copy firewall rules (ACL) from source container to target container |
copy_network_rules | boolean | No | false | Whether to copy network rules/settings from source container to target container |
curl -X POST "https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/copy" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "target_project_id": "507f1f77bcf86cd799439044", "target_server_id": "507f1f77bcf86cd799439055", "name": "dev-copy-prod", "copy_firewall_rules": true, "copy_network_rules": false }'const result = await client.api.containers.copy({ id: "507f1f77bcf86cd799439011", data: { target_project_id: "507f1f77bcf86cd799439044", target_server_id: "507f1f77bcf86cd799439055", name: "dev-copy-prod", copy_firewall_rules: true, copy_network_rules: false, },});{ "statusCode": 201, "message": "Container copy initiated successfully", "data": { "id": "507f1f77bcf86cd799439099", "name": "dev-copy-prod", "status": "copying", "source_container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439044", "project_alias": "staging-project", "server_id": "507f1f77bcf86cd799439055", "server_name": "node-sg-sin-1", "subserver_name": "prod-replica", "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": "507f1f77bcf86cd799439044-507f1f77bcf86cd799439099-ssh.node-sg-sin-1.containers.hoody.com", "color": "#3478F6", "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": "507f1f77bcf86cd799439077", "environment_vars": { "NODE_ENV": "development" }, "volumes": { "data": "/mnt/data" }, "ssh_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyCopy123", "comment": "Cloned from production container", "copy_firewall_rules": true, "copy_network_rules": false, "created_at": "2026-03-14T09:32:11.000Z", "updated_at": "2026-03-14T09:32:11.000Z", "realm_ids": [] }}{ "statusCode": 400, "error": "Bad Request", "message": "This server has reached its container limit."}| 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. |
POST /api/v1/containers/{id}/sync
Section titled “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.com/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. |