# Projects

**Page:** api/projects

[Download Raw Markdown](./api/projects.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



Projects let you organize containers, networks, and other resources into logical groups with optional quotas, shared configurations, and multi-user access control. This page covers project CRUD, per-user permission management, and aggregated container statistics.


A default project is auto-provisioned for every user at signup. Project aliases must be unique within an account, and projects can belong to multiple realms for multi-tenant isolation.


## Project lifecycle

### `GET /api/v1/projects/`

List all projects you own or have been granted access to, with pagination and sorting.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `page` | query | number | No | Page number (1-based). Default: `1` |
| `limit` | query | number | No | Items per page (max 100). Default: `10` |
| `sort_by` | query | string | No | Field to sort by. Allowed: `id`, `alias`, `created_at`, `updated_at`. Default: `"created_at"` |
| `sort_order` | query | string | No | Sort direction. Allowed: `asc`, `desc`. Default: `"desc"` |
| `realm_id` | query | string | No | Filter by realm ID. Only returns projects that belong to this realm. Alternative to using a realm subdomain in the URL. |



```bash
curl -X GET "https://api.hoody.icu/api/v1/projects/?page=1&limit=10&sort_by=created_at&sort_order=desc" \
  -H "Authorization: Bearer <token>"
```


```ts
const page = await client.api.projects.listIterator({
  page: 1,
  limit: 10,
  sort_by: "created_at",
  sort_order: "desc",
});
```


```json
{
  "statusCode": 200,
  "message": "Projects retrieved successfully",
  "data": {
    "projects": [
      {
        "id": "507f1f77bcf86cd799439011",
        "user_id": "507f1f77bcf86cd799439022",
        "alias": "Production Environment",
        "color": "#3B82F6",
        "created_at": "2025-01-10T08:00:00.000Z",
        "updated_at": "2025-01-15T10:30:00.000Z",
        "max_containers": 50
      },
      {
        "id": "507f1f77bcf86cd799439033",
        "user_id": "507f1f77bcf86cd799439022",
        "alias": "Development",
        "color": "#10B981",
        "created_at": "2025-01-05T12:00:00.000Z",
        "updated_at": "2025-01-05T12:00:00.000Z",
        "max_containers": null
      }
    ],
    "pagination": {
      "total": 3,
      "page": 1,
      "limit": 10,
      "totalPages": 1
    }
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid parameter value"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INVALID_PARAMETER_VALUE` | Invalid parameter value | A parameter value is outside the allowed range or format | Ensure parameter values meet the documented constraints (min/max, format, regex) |


```json
{
  "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 &lt;token&gt;` |
| `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 |



### `POST /api/v1/projects/`

Create a new project to organize and manage your containers, networks, and resources.

This endpoint takes no parameters.

#### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `alias` | string | Yes | Human-readable project name (1–100 characters). Must be unique across your projects (e.g., `"Production"`, `"Development"`, `"Client-ABC"`). |
| `color` | string | No | HEX color code for visual organization. Accepts 3-digit (`#RGB`) or 6-digit (`#RRGGBB`) formats. The `#` prefix is auto-added if missing, and the value is auto-normalized to uppercase. If omitted, a random color is generated. |
| `max_containers` | number \| null | No | Maximum number of containers allowed in this project. Set to `null` for unlimited. Enforced during container creation. |
| `realm_ids` | string[] | No | Realm IDs to assign this project to. If invoked from a realm subdomain, the subdomain realm is automatically included and merged with any explicitly provided `realm_ids`. |



```bash
curl -X POST "https://api.hoody.icu/api/v1/projects/" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Production Environment",
    "color": "#EF4444",
    "max_containers": 100
  }'
```


```ts
const project = await client.api.projects.create({
  alias: "Production Environment",
  color: "#EF4444",
  max_containers: 100,
});
```


```json
{
  "statusCode": 201,
  "message": "Project created successfully",
  "data": {
    "id": "507f1f77bcf86cd799439011",
    "user_id": "507f1f77bcf86cd799439022",
    "alias": "Production Environment",
    "color": "#3B82F6",
    "created_at": "2025-01-10T08:00:00.000Z",
    "updated_at": "2025-01-10T08:00:00.000Z",
    "max_containers": 50,
    "realm_ids": []
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation failed"
}
```

| 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 |
| `MISSING_REQUIRED_FIELD` | Required field missing | One or more required fields are missing from the request | Include all required fields as specified in the API documentation |
| `INVALID_ALIAS_FORMAT` | Invalid alias format | Project alias must be between 1–100 characters | Provide a valid alias following the format requirements: 1–100 characters |
| `INVALID_COLOR_FORMAT` | Invalid color format | Color must be a valid HEX color code (3 or 6 digits) | Provide a valid HEX color like `#RGB` or `#RRGGBB` (e.g., `#F00` or `#FF0000`) |
| `INVALID_QUOTA_VALUE` | Invalid quota value | Quota values must be non-negative numbers or null | Provide a valid quota value (0 or higher) or `null` for unlimited |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Project alias already exists"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `DUPLICATE_ALIAS` | Project alias already exists | The provided project alias is already in use by another project in your account | Choose a different, unique project alias |



### `GET /api/v1/projects/{id}`

Retrieve detailed information about a specific project, including the project owner, quotas, and (optionally) all users who have been granted access.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID |
| `include_permissions` | query | boolean | No | Include project permissions with user details in response. Default: `false` |



```bash
curl -X GET "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011?include_permissions=true" \
  -H "Authorization: Bearer <token>"
```


```ts
const project = await client.api.projects.get({
  id: "507f1f77bcf86cd799439011",
  include_permissions: true,
});
```


```json
{
  "statusCode": 200,
  "message": "Project retrieved successfully",
  "data": {
    "id": "507f1f77bcf86cd799439011",
    "user_id": "507f1f77bcf86cd799439022",
    "alias": "Production Environment",
    "color": "#3B82F6",
    "created_at": "2025-01-10T08:00:00.000Z",
    "updated_at": "2025-01-15T10:30:00.000Z",
    "max_containers": 50,
    "permissions": [
      {
        "id": "507f1f77bcf86cd799439033",
        "project_id": "507f1f77bcf86cd799439011",
        "user_id": "507f1f77bcf86cd799439044",
        "permission_level": "read",
        "created_at": "2025-01-12T14:00:00.000Z",
        "updated_at": "2025-01-12T14:00:00.000Z",
        "user": {
          "id": "507f1f77bcf86cd799439044",
          "username": "jane_smith",
          "alias": "Jane Smith"
        }
      }
    ]
  }
}
```


```json
{
  "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) |
| `INVALID_PARAMETER_VALUE` | Invalid parameter value | A parameter value is outside the allowed range or format | Ensure parameter values meet the documented constraints (min/max, format, regex) |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_NOT_FOUND` | Project not found | The requested project does not exist or has been deleted | Verify the project ID is correct and that you have access to this project |



### `PATCH /api/v1/projects/{id}`

Update a project's alias, color, or realm membership. Only the fields you send are modified. You must be the project owner or have `edit` permission.


Only unrestricted tokens and admin users can modify `realm_ids`; realm-restricted tokens cannot change realm membership. When updating from a realm subdomain, the subdomain realm is automatically preserved and merged.


#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID to update |

#### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `alias` | string | Yes | New project name (1–100 characters). Must be unique across your projects. |
| `color` | string | No | New HEX color code. Auto-normalized to uppercase with `#` prefix. |
| `realm_ids` | string[] | No | Updated realm membership for this project. |



```bash
curl -X PATCH "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "Production v2",
    "color": "#10B981"
  }'
```


```ts
const updated = await client.api.projects.update({
  id: "507f1f77bcf86cd799439011",
  alias: "Production v2",
  color: "#10B981",
});
```


```json
{
  "statusCode": 200,
  "message": "Project updated successfully",
  "data": {
    "id": "507f1f77bcf86cd799439011",
    "user_id": "507f1f77bcf86cd799439022",
    "alias": "Production Environment Updated",
    "color": "#EF4444",
    "created_at": "2025-01-10T08:00:00.000Z",
    "updated_at": "2025-01-15T14:45:00.000Z",
    "max_containers": 50
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation failed"
}
```

| 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_ALIAS_FORMAT` | Invalid alias format | Project alias must be between 1–100 characters | Provide a valid alias following the format requirements: 1–100 characters |
| `INVALID_COLOR_FORMAT` | Invalid color format | Color must be a valid HEX color code (3 or 6 digits) | Provide a valid HEX color like `#RGB` or `#RRGGBB` (e.g., `#F00` or `#FF0000`) |
| `INVALID_QUOTA_VALUE` | Invalid quota value | Quota values must be non-negative numbers or null | Provide a valid quota value (0 or higher) or `null` for unlimited |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_NOT_FOUND` | Project not found | The requested project does not exist or has been deleted | Verify the project ID is correct and that you have access to this project |


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Project alias already exists"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `DUPLICATE_ALIAS` | Project alias already exists | The provided project alias is already in use by another project in your account | Choose a different, unique project alias |



### `DELETE /api/v1/projects/{id}`

Permanently delete a project and all associated resources. You must be the project owner or have `delete` permission.


This action cannot be undone. If the request cannot be fully completed, the project remains available so you can safely retry. If the project still contains active containers, the API returns `422 PROJECT_HAS_CONTAINERS` — delete the containers first, then retry.


#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID to delete |
| `include_deleted_items` | query | boolean | No | Include a lightweight list of deleted container IDs and names in the response for confirmation UX. Default: `false` |



```bash
curl -X DELETE "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011?include_deleted_items=true" \
  -H "Authorization: Bearer <token>"
```


```ts
const result = await client.api.projects.delete({
  id: "507f1f77bcf86cd799439011",
  include_deleted_items: true,
});
```


```json
{
  "statusCode": 200,
  "message": "Project deleted successfully",
  "data": {
    "deleted": {
      "containers": 2,
      "permissions": 1,
      "aliases": 3
    },
    "deleted_items": {
      "containers": [
        {
          "id": "507f1f77bcf86cd799439011",
          "name": "web-app"
        },
        {
          "id": "507f1f77bcf86cd799439012",
          "name": "worker"
        }
      ]
    }
  }
}
```


```json
{
  "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) |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_NOT_FOUND` | Project not found | The requested project does not exist or has been deleted | Verify the project ID is correct and that you have access to this project |


```json
{
  "statusCode": 409,
  "error": "Conflict",
  "message": "Resource already exists"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `RESOURCE_ALREADY_EXISTS` | Resource already exists | A resource with this identifier already exists | Use a different identifier or update the existing resource instead |


```json
{
  "statusCode": 422,
  "error": "Unprocessable Entity",
  "message": "Project contains active containers"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_HAS_CONTAINERS` | Project has active containers | Cannot delete project because it contains active containers | Delete all containers in this project first, then try again |



## Permissions

Each project supports three permission levels: `read` (view only), `edit` (modify resources), and `delete` (destroy the project). The project owner always has full access; additional users can be granted access through the endpoints below.

### `GET /api/v1/projects/{id}/permissions`

List all users who have been granted access to this project, with their permission levels.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID |
| `page` | query | number | No | Page number (1-based) |
| `limit` | query | number | No | Items per page (max 100) |
| `sort_by` | query | string | No | Field to sort by. Allowed: `id`, `user_id`, `permission_level`, `created_at`, `updated_at` |
| `sort_order` | query | string | No | Sort direction. Allowed: `asc`, `desc` |



```bash
curl -X GET "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011/permissions?page=1&limit=10" \
  -H "Authorization: Bearer <token>"
```


```ts
const page = await client.api.projects.listPermissionsIterator({
  id: "507f1f77bcf86cd799439011",
  page: 1,
  limit: 10,
});
```


```json
{
  "statusCode": 200,
  "message": "Project permissions retrieved successfully",
  "data": {
    "permissions": [
      {
        "id": "507f1f77bcf86cd799439033",
        "project_id": "507f1f77bcf86cd799439011",
        "user_id": "507f1f77bcf86cd799439044",
        "permission_level": "read",
        "created_at": "2025-01-12T14:00:00.000Z",
        "updated_at": "2025-01-12T14:00:00.000Z",
        "user": {
          "id": "507f1f77bcf86cd799439044",
          "username": "jane_smith",
          "alias": "Jane Smith"
        }
      },
      {
        "id": "507f1f77bcf86cd799439055",
        "project_id": "507f1f77bcf86cd799439011",
        "user_id": "507f1f77bcf86cd799439066",
        "permission_level": "edit",
        "created_at": "2025-01-13T09:30:00.000Z",
        "updated_at": "2025-01-14T16:20:00.000Z",
        "user": {
          "id": "507f1f77bcf86cd799439066",
          "username": "bob_jones",
          "alias": "Bob Jones"
        }
      }
    ],
    "pagination": {
      "total": 2,
      "page": 1,
      "limit": 10,
      "totalPages": 1
    }
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid ID format"
}
```


```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Authentication token required"
}
```


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Insufficient permissions"
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```



### `POST /api/v1/projects/{id}/permissions`

Grant another user access to your project. You must be the project owner or have `edit` permission.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID |

#### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `user_id` | string | Yes | User ID to grant access to |
| `permission_level` | string | Yes | Access level. One of: `read`, `edit`, `delete` |



```bash
curl -X POST "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011/permissions" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "507f1f77bcf86cd799439044",
    "permission_level": "edit"
  }'
```


```ts
const permission = await client.api.projects.addPermission({
  id: "507f1f77bcf86cd799439011",
  user_id: "507f1f77bcf86cd799439044",
  permission_level: "edit",
});
```


```json
{
  "statusCode": 201,
  "message": "Project permission added successfully",
  "data": {
    "id": "507f1f77bcf86cd799439033",
    "project_id": "507f1f77bcf86cd799439011",
    "user_id": "507f1f77bcf86cd799439044",
    "permission_level": "read",
    "created_at": "2025-01-12T14:00:00.000Z",
    "updated_at": "2025-01-12T14:00:00.000Z",
    "user": {
      "id": "507f1f77bcf86cd799439044",
      "username": "jane_smith",
      "alias": "Jane Smith"
    }
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation failed"
}
```

| 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) |
| `MISSING_REQUIRED_FIELD` | Required field missing | One or more required fields are missing from the request | Include all required fields as specified in the API documentation |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_NOT_FOUND` | Project not found | The requested project does not exist or has been deleted | Verify the project ID is correct and that you have access to this project |
| `RESOURCE_NOT_FOUND` | Resource not found | The requested resource does not exist or has been deleted | Verify the resource ID and ensure it exists |


```json
{
  "statusCode": 409,
  "error": "Conflict",
  "message": "User already has permission for this project"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PERMISSION_ALREADY_EXISTS` | Permission already exists | This user already has a permission for this project | Update the existing permission instead of creating a new one |
| `CANNOT_GRANT_SELF_PERMISSION` | Cannot grant permission to self | You cannot grant permissions to yourself | As the owner, you already have full access to this project |



### `PATCH /api/v1/projects/{id}/permissions/{permissionId}`

Change a user's permission level for a project — for example, upgrade from `read` to `edit` or downgrade from `edit` to `read`. You must be the project owner or have `edit` permission.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID |
| `permissionId` | path | string | Yes | Permission ID to update |

#### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `permission_level` | string | Yes | New permission level. One of: `read`, `edit`, `delete` |



```bash
curl -X PATCH "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011/permissions/507f1f77bcf86cd799439033" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "permission_level": "edit"
  }'
```


```ts
const updated = await client.api.projects.updatePermission({
  id: "507f1f77bcf86cd799439011",
  permissionId: "507f1f77bcf86cd799439033",
  permission_level: "edit",
});
```


```json
{
  "statusCode": 200,
  "message": "Project permission updated successfully",
  "data": {
    "id": "507f1f77bcf86cd799439033",
    "project_id": "507f1f77bcf86cd799439011",
    "user_id": "507f1f77bcf86cd799439044",
    "permission_level": "edit",
    "created_at": "2025-01-12T14:00:00.000Z",
    "updated_at": "2025-01-15T14:45:00.000Z",
    "user": {
      "id": "507f1f77bcf86cd799439044",
      "username": "jane_smith",
      "alias": "Jane Smith"
    }
  }
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Validation failed"
}
```

| 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) |
| `MISSING_REQUIRED_FIELD` | Required field missing | One or more required fields are missing from the request | Include all required fields as specified in the API documentation |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROJECT_NOT_FOUND` | Project not found | The requested project does not exist or has been deleted | Verify the project ID is correct and that you have access to this project |
| `PERMISSION_NOT_FOUND` | Permission not found | The requested permission does not exist or has been removed | Verify the permission ID is correct |



### `DELETE /api/v1/projects/{id}/permissions/{permissionId}`

Revoke a user's access to a project. The user will immediately lose all access. You must be the project owner or have `edit` permission.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Project ID |
| `permissionId` | path | string | Yes | Permission ID to remove |



```bash
curl -X DELETE "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439011/permissions/507f1f77bcf86cd799439033" \
  -H "Authorization: Bearer <token>"
```


```ts
await client.api.projects.removePermission({
  id: "507f1f77bcf86cd799439011",
  permissionId: "507f1f77bcf86cd799439033",
});
```


```json
{
  "statusCode": 200,
  "message": "Project permission removed successfully"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid ID format"
}
```


```json
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Authentication token required"
}
```


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Insufficient permissions"
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Project not found"
}
```



## Statistics

### `GET /api/v1/projects/{id}/stats`

Get aggregated resource usage statistics for all containers in a project. Returns per-container stats (CPU, memory, disk, network) plus a summary with the total container count and total processing time.

#### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `id` | path | string | Yes | Unique identifier of the project |



```bash
curl -X GET "https://api.hoody.icu/api/v1/projects/507f1f77bcf86cd799439033/stats" \
  -H "Authorization: Bearer <token>"
```


```ts
const stats = await client.api.projects.getStats({
  id: "507f1f77bcf86cd799439033",
});
```


```json
{
  "statusCode": 200,
  "message": "Project statistics retrieved successfully",
  "data": {
    "stats": [
      {
        "id": "507f1f77bcf86cd799439011",
        "project_id": "507f1f77bcf86cd799439033",
        "project_name": "Production Environment",
        "server_name": "node-sg-sin-1",
        "status": "Running",
        "status_code": 103,
        "processes": 143,
        "started_at": "2025-12-03T18:39:53Z",
        "cpu": {
          "usage": 17303605000
        },
        "memory": {
          "usage": 1474666496,
          "total": 131503332000
        },
        "disk": {
          "root": {
            "total": 0,
            "usage": 11081670656
          }
        },
        "network": [],
        "processing_time": "3ms"
      }
    ],
    "summary": {
      "project_id": "507f1f77bcf86cd799439033",
      "project_name": "Production Environment",
      "container_count": 29,
      "total_processing_time": "1506ms"
    }
  }
}
```


```json
{
  "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) |


```json
{
  "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 &lt;token&gt;` |
| `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 |


```json
{
  "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 |
| `RESOURCE_ACCESS_DENIED` | Resource access denied | You do not have permission to access this specific resource | Ensure you own this resource or have been granted access by the owner |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `RESOURCE_NOT_FOUND` | Resource not found | The requested resource does not exist or has been deleted | Verify the resource ID and ensure it exists |


```json
{
  "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 |