Container Snapshots
Section titled “Container Snapshots”Container snapshots capture the filesystem state of a container at a point in time. Use these endpoints to create new snapshots, restore a container to a previous state, update or remove the alias of an existing snapshot, and delete snapshots you no longer need. Snapshot limits depend on the server: free-tier servers cap at 10 snapshots per container, while paid servers and rentals support up to 1000. Each container’s current count and the applicable ceiling are returned in the snapshot_count and max_snapshots fields when listing snapshots.
List Snapshots
Section titled “List Snapshots”GET /api/v1/containers/{id}/snapshots
Section titled “GET /api/v1/containers/{id}/snapshots”Get all snapshots for a container.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container to retrieve snapshots for |
curl -X GET https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/snapshots \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.listSnapshotsIterator('507f1f77bcf86cd799439011');{ "statusCode": 200, "message": "Snapshots retrieved successfully", "data": { "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "snapshot_count": 2, "max_snapshots": 10, "snapshots": [ { "name": "snap-20250115-103000", "alias": "backup-2025-01-15", "created_at": "2025-01-15T10:30:00.000Z", "last_used_at": "2025-01-15T14:00:00.000Z", "expires_at": "2025-02-15T10:30:00.000Z", "stateful": false, "size": 2147483648 }, { "name": "snap-20250110-080000", "alias": "weekly-backup", "created_at": "2025-01-10T08:00:00.000Z", "last_used_at": null, "expires_at": null, "stateful": false, "size": 1073741824 } ] }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid container id"}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}{ "statusCode": 404, "error": "Not Found", "message": "Container not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}Create Snapshot
Section titled “Create Snapshot”POST /api/v1/containers/{id}/snapshots
Section titled “POST /api/v1/containers/{id}/snapshots”Create a new snapshot for a container.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container to create snapshot for |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
alias | string | No | Optional user-friendly alias for the snapshot. Maximum length 100 characters. |
expiry | integer | No | Expiry in days (1–3650). Values outside this range are rejected before the snapshot is created. |
curl -X POST https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/snapshots \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "alias": "pre-deployment-backup", "expiry": 30 }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.createSnapshot('507f1f77bcf86cd799439011', { alias: 'pre-deployment-backup', expiry: 30,});{ "statusCode": 200, "message": "Snapshot created successfully", "data": { "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "snapshot": { "name": "snap-20250115-145500", "alias": "pre-deployment-backup", "created_at": "2025-01-15T14:55:00.000Z", "last_used_at": null, "expires_at": "2025-02-14T14:55:00.000Z", "stateful": false, "size": 2147483648 } }}{ "statusCode": 400, "error": "CONTAINER_SNAPSHOT_LIMIT", "message": "This container has reached its snapshot limit.", "data": { "field": "container_snapshot_limit", "container_id": "507f1f77bcf86cd799439011", "server_id": "507f1f77bcf86cd799439022", "current_count": 10, "limit": 10 }}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_SNAPSHOT_LIMIT | Container snapshot limit reached | The container already holds the maximum number of snapshots allowed for its server. Containers on free-tier servers are capped lower than those on paid servers and rentals; the applicable limit is returned as max_snapshots when listing snapshots. | Delete an existing snapshot on this container before creating a new one. |
SNAPSHOT_PRESPAWN_FORBIDDEN | Snapshots not allowed on a prespawn container | A prespawn container is not yet bound to the server it will finally run on, so a snapshot taken now could not be counted against the limits that will apply to it. | Claim the container first, then create snapshots on the claimed container. |
VALIDATION_ERROR | Invalid input parameters | One or more request parameters failed validation. | Check the error message for specific field requirements and correct your input. |
{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}{ "statusCode": 404, "error": "Not Found", "message": "Container not found"}{ "statusCode": 409, "error": "SNAPSHOT_OPERATION_IN_PROGRESS", "message": "Another snapshot operation may be running for this container, or the service is temporarily unavailable. Nothing was created; retry shortly."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
SNAPSHOT_OPERATION_IN_PROGRESS | Snapshot creation already running | Another snapshot creation is already in flight for this container. Concurrent creations are rejected so the snapshot limit cannot be exceeded. | Retry after a few seconds (see the Retry-After header). |
container_finalizing | Container is being finalized | The container is still being claimed and refuses changes until that completes. | Retry in a few seconds. |
{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}{ "statusCode": 503, "error": "SNAPSHOT_INVENTORY_UNAVAILABLE", "message": "Unable to verify this container's snapshot inventory. No changes were made."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
SNAPSHOT_INVENTORY_UNAVAILABLE | Snapshot inventory could not be verified | The container’s live snapshot list could not be read, so the snapshot limit could not be checked. The request is refused rather than creating a snapshot that might exceed it. | Retry shortly. If it persists, contact support. |
Restore Snapshot
Section titled “Restore Snapshot”PUT /api/v1/containers/{id}/snapshots/{name}
Section titled “PUT /api/v1/containers/{id}/snapshots/{name}”Restore a container from a snapshot.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container to restore |
name | path | string | Yes |
curl -X PUT https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/snapshots/snap-20250115-103000 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.restoreSnapshot('507f1f77bcf86cd799439011', 'snap-20250115-103000');{ "statusCode": 200, "message": "Container restored from snapshot successfully", "data": { "success": true, "message": "Container restored from snapshot successfully", "snapshot": {} }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid request"}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}{ "statusCode": 404, "error": "Not Found", "message": "Snapshot not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}Update Snapshot Alias
Section titled “Update Snapshot Alias”PUT /api/v1/containers/{id}/snapshots/{name}/alias
Section titled “PUT /api/v1/containers/{id}/snapshots/{name}/alias”Update the alias of an existing snapshot. Set alias to null to remove the alias.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container |
name | path | string | Yes |
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
alias | string | null | Yes | New alias for the snapshot (set to null to remove alias). Maximum length 100 characters. |
curl -X PUT https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/snapshots/snap-20250115-103000/alias \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "alias": "production-baseline" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.updateSnapshotAlias('507f1f77bcf86cd799439011', 'snap-20250115-103000', { alias: 'production-baseline',});{ "statusCode": 200, "message": "Snapshot alias updated successfully", "data": { "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "snapshot": { "name": "snap-20250115-103000", "alias": "production-baseline", "created_at": "2025-01-15T10:30:00.000Z", "last_used_at": "2025-01-15T14:00:00.000Z", "expires_at": "2025-02-15T10:30:00.000Z", "stateful": false, "size": 2147483648 } }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid request"}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}{ "statusCode": 404, "error": "Not Found", "message": "Snapshot not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}{ "statusCode": 503, "error": "SNAPSHOT_INVENTORY_UNAVAILABLE", "message": "Unable to verify this container's snapshot inventory. No changes were made."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
SNAPSHOT_INVENTORY_UNAVAILABLE | Snapshot inventory could not be verified | The container’s live snapshot list could not be read, so the snapshot limit could not be checked. The request is refused rather than creating a snapshot that might exceed it. | Retry shortly. If it persists, contact support. |
Delete Snapshot
Section titled “Delete Snapshot”DELETE /api/v1/containers/{id}/snapshots/{name}
Section titled “DELETE /api/v1/containers/{id}/snapshots/{name}”Delete a snapshot.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Unique identifier of the container |
name | path | string | Yes |
curl -X DELETE https://api.hoody.com/api/v1/containers/507f1f77bcf86cd799439011/snapshots/snap-20250110-080000 \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.deleteSnapshot('507f1f77bcf86cd799439011', 'snap-20250110-080000');{ "statusCode": 200, "message": "Snapshot deleted successfully", "data": { "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "snapshot_name": "snap-20250110-080000" }}{ "statusCode": 400, "error": "Bad Request", "message": "Invalid request"}{ "statusCode": 401, "error": "Unauthorized", "message": "Authentication required"}{ "statusCode": 403, "error": "Forbidden", "message": "Insufficient permissions"}{ "statusCode": 404, "error": "Not Found", "message": "Snapshot not found"}{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}