Container Operations & Lifecycle
Section titled “Container Operations & Lifecycle”The Container Operations and Lifecycle endpoints control the runtime state of a container and expose the history of its state transitions. Use these endpoints to start, stop, restart, pause, or resume a container, and to retrieve a paginated audit log of every status change for debugging, compliance, or operational reporting.
Get container status logs
Section titled “Get container status logs”GET /api/v1/containers/{id}/status-logs
Section titled “GET /api/v1/containers/{id}/status-logs”Returns a paginated list of status transition logs for a specific container. Each entry records the previous and new status, the actor that triggered the transition, the elapsed time in the prior status, and any metadata captured at the moment of the transition.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
page | query | number | No | Page number. Default: 1 |
limit | query | number | No | Items per page. Default: 10 |
sort_by | query | string | No | Field to sort by. Default: "transition_time". One of: "transition_time", "created_at", "to_status", "from_status" |
sort_order | query | string | No | Sort direction. Default: "desc". One of: "asc", "desc" |
This endpoint takes no request body.
Example request
Section titled “Example request”curl -X GET 'https://api.hoody.com/api/v1/containers/{id}/status-logs?page=1&limit=10&sort_by=transition_time&sort_order=desc' \ -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.listStatusHistory('{id}', { page: 1, limit: 10, sort_by: 'transition_time', sort_order: 'desc' });Response
Section titled “Response”{ "statusCode": 200, "message": "Status logs retrieved successfully", "data": { "logs": [ { "id": "507f1f77bcf86cd799439077", "container_id": "507f1f77bcf86cd799439011", "from_status": "stopped", "to_status": "running", "transition_time": "2025-01-15T10:30:00.000Z", "duration_ms": 3500, "triggered_by": "manual_operation", "metadata": { "command": "start" } }, { "id": "507f1f77bcf86cd799439078", "container_id": "507f1f77bcf86cd799439011", "from_status": null, "to_status": "stopped", "transition_time": "2025-01-15T09:15:00.000Z", "duration_ms": null, "triggered_by": "container_creation", "metadata": null } ], "pagination": { "total": 15, "page": 1, "limit": 10, "totalPages": 2 } }}{ "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) |
{ "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 |
AUTH_TOKEN_LINEAGE_REVOKED | Parent auth token no longer valid | The auth token was created by another auth token, and that token (or one above it) has been revoked, disabled or has expired, so this one no longer authenticates | Create a new auth token from a valid one, or sign in again |
EMAIL_NOT_VERIFIED | Email not verified | Returned by the login endpoint when the password is correct but the account’s email address has not been verified yet. It is only returned after the password has been checked. The response carries data.email so the client can offer a ‘resend verification email’ action without asking again. | Complete email verification by clicking the link sent to your inbox, or call /auth/resend-verification to receive a new link, or complete a password reset which also implicitly verifies the email. |
INVALID_OTP_CODE | Invalid OTP code | The provided 2FA code is incorrect or has expired | Generate a new code from your authenticator app and try again |
{ "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 |
Validation Error: the request does not match the operation schema, or its JSON body cannot be parsed. message names each failing check, and data, when present, lists them one entry per failing field.
{ "statusCode": 422, "error": "Validation Error", "message": "Validation failed: /name must NOT have fewer than 3 characters"}Manage container
Section titled “Manage container”POST /api/v1/containers/{id}/{operation}
Section titled “POST /api/v1/containers/{id}/{operation}”Performs a lifecycle operation on a container. The operation path segment selects the action: start, stop, force-stop, restart, pause, or resume. Each successful operation returns the container’s new status and a human-readable message describing the outcome.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Container ID |
operation | path | string | Yes | Lifecycle operation to perform. One of: start, stop, force-stop, restart, pause, resume |
Request body
Section titled “Request body”The body is optional. When present, it may carry the following field:
| Name | Type | Required | Description |
|---|---|---|---|
timeout | integer | No | Upper bound, in seconds, on how long the operation may run on the host before it is cut off. For stop and restart it is also the time the container is given to shut down cleanly. At most 600. Omit it for the server default. |
{ "timeout": 120}Example request
Section titled “Example request”curl -X POST 'https://api.hoody.com/api/v1/containers/{id}/start' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{"timeout": 120}'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });
await client.api.containers.start('{id}', { timeout: 120 });Response
Section titled “Response”{ "statusCode": 200, "message": "Container operation completed successfully", "data": { "error": false, "operation": "start", "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "message": "Container started successfully", "status": "running" }}{ "statusCode": 400, "error": "Bad Request", "message": "Container is already running", "data": { "error": true, "operation": "start", "container_id": "507f1f77bcf86cd799439011", "project_id": "507f1f77bcf86cd799439033", "message": "Container is already running", "status": "running" }}| 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) |
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 |
{ "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 |
AUTH_TOKEN_LINEAGE_REVOKED | Parent auth token no longer valid | The auth token was created by another auth token, and that token (or one above it) has been revoked, disabled or has expired, so this one no longer authenticates | Create a new auth token from a valid one, or sign in again |
EMAIL_NOT_VERIFIED | Email not verified | Returned by the login endpoint when the password is correct but the account’s email address has not been verified yet. It is only returned after the password has been checked. The response carries data.email so the client can offer a ‘resend verification email’ action without asking again. | Complete email verification by clicking the link sent to your inbox, or call /auth/resend-verification to receive a new link, or complete a password reset which also implicitly verifies the email. |
INVALID_OTP_CODE | Invalid OTP code | The provided 2FA code is incorrect or has expired | Generate a new code from your authenticator app and try again |
{ "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 |
OPERATION_NOT_PERMITTED_ON_EXPIRED | Operation Not Permitted on Expired Container | This operation cannot be performed because the container has expired due to server termination | The container is in a read-only state. No further operations are allowed. Please create a new container |
CONTAINER_ACCESS_SUSPENDED | Container access is suspended | The container is under an access suspension and must stay stopped. start, resume and restart are refused. | Contact support. The container can be started once the suspension is lifted. |
{ "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": "CONTAINER_OPERATION_IN_PROGRESS", "message": "Cannot perform start operation. Container is currently being operated on."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_OPERATION_IN_PROGRESS | Another operation is running on this container | Another start, stop, setup or maintenance operation is already in progress on this container. Nothing was done. | Retry in a few seconds. |
container_finalizing | Container is still being set up | The container is still being set up and refuses changes until that completes. | Retry in a few seconds. |
SUBSERVER_DORMANT | Subserver is not active | The container is on a paid subserver whose subscription is not active (on hold, being delivered, or being deleted) or has a change in progress, so containers on it cannot be created, started, stopped, changed, copied, shared or deleted. data.reason is not_active, operation_in_flight or no_subscription. Nothing was changed. | Retry once the subserver is active again (renew a held subscription, or wait for the change to finish). |
Validation Error: the request does not match the operation schema, or its JSON body cannot be parsed. message names each failing check, and data, when present, lists them one entry per failing field.
{ "statusCode": 422, "error": "Validation Error", "message": "Validation failed: /name must NOT have fewer than 3 characters"}{ "statusCode": 500, "error": "Internal Server Error", "message": "An unexpected error occurred"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
INTERNAL_SERVER_ERROR | Internal server error | An unexpected error occurred on the server | Try again later, or contact support if the problem persists |
EXTERNAL_SERVICE_ERROR | External service error | A required external service is unavailable or returned an error | Try again later when the external service is available |
{ "statusCode": 502, "error": "CONTAINER_HOST_COMMAND_FAILED", "message": "Container operation failed: server is temporarily unreachable. Please try again shortly."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_HOST_COMMAND_FAILED | The container server could not complete the operation | The container’s server was unreachable, or ran the operation and reported a failure. | Check the container status, then retry. If it keeps failing, contact support. |
{ "statusCode": 504, "error": "CONTAINER_HOST_TIMEOUT", "message": "Container operation timed out waiting for the server. Its outcome is unknown; check the container status before retrying."}| Error Code | Title | Description | Resolution |
|---|---|---|---|
CONTAINER_HOST_TIMEOUT | The container server did not answer in time | The operation was sent but the server did not answer before the deadline. It may still have completed. | Check the container status before retrying. |