# Update a project

## `PUT /v1/projects/{projectId}`

Updates a project's metadata and configuration, including description, visibility, spicepod configuration, replicas, and resource limits.

### Path parameters

- `projectId` (integer, required): The ID of the project

### Header parameters

- `Authorization` (string, required): `Bearer <token>`. [Authentication](https://spice.ai/docs/cloud/api/management#authentication) lists the tokens it accepts.
- `X-Org-Name` (string, optional): The organization to act on, by handle. Omit it to act on the organization the credential is bound to; sending it blank is a 400, not the same as omitting it. A user credential may name any organization its owner belongs to; a machine credential is pinned to its own. A portal session token is bound to none, so it must send this header on every route but `GET /v1/orgs` (400 `org_assertion_required` otherwise). Pattern: `^[A-Za-z0-9._-]{1,255}$`.

### Request body

Required.

Content type: `application/json`

- `description` (string)
- `visibility` (string): Allowed values: `public`, `private`.
- `production_branch` (string)
- `tags` (map of string): Key-value tags for the project. The map replaces the stored tags. System tags the project already has stay on the project when the map omits them.
- `spicepod` (string | object): The project's Spicepod. A project connected to a GitHub repository takes its Spicepod from the repository's spicepod.yaml, so for such a project only the stored Spicepod, sent back unchanged, is accepted.
- `image_tag` (string | null): Runtime image tag for a managed project; rejected for standalone projects. A non-empty value pins the project. On stable, the pin must be a published stable runtime version. On preview, it must be a published preview or stable runtime version. On stable or preview, send null to clear a pin so deploys resolve from the channel catalog (stable - latest GA for the configured version range; preview - latest RC). null is rejected on nightly and internal channels.
- `update_channel` (string): Update channel for a managed runtime; rejected for standalone projects. Allowed values: `stable`, `preview`, `nightly`.
- `version` (string): Semver range for a managed runtime version (e.g. 1.x, 2.x); rejected for standalone projects.
- `replicas` (integer): Managed runtime replica count; rejected for standalone projects. Minimum: `0`.
- `resources` (object): Resource requests and limits for a managed project container; rejected for standalone projects.
  - `limits` (object)
    - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
    - `memory` (string): Memory limit in Gi (for example, 16Gi)
    - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
  - `requests` (object)
    - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
    - `memory` (string): Memory request. Minimum 192Mi.
- `executor` (object): Executor container configuration for a managed project; rejected for standalone projects.
  - `replicas` (integer): Number of executor replicas. Minimum: `0`.
  - `resources` (object): Resource requests and limits for the executor container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `storage_size_gb` (number)
- `region` (string): Managed project region; standalone placement is resolved during attachment.
- `cluster_name` (string): Reassign the project to a dedicated cluster, as listed by `GET /v1/clusters`. Provide at most one of `region` or `cluster_name`. When set, region/routing are derived from the cluster; if `region` is also provided it must match the cluster's region. Rejected for standalone projects, whose placement is resolved during attachment.
- `storage_size_gb` (number): Managed runtime storage size; rejected for standalone projects.
- `storage_claim_size_gb` (number, deprecated): Deprecated. Use storage\_size\_gb instead. Rejected for standalone projects.

### Example request

```bash
curl -X PUT "https://api.spice.ai/v1/projects/<projectId>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "string",
    "visibility": "public",
    "production_branch": "string",
    "tags": {},
    "spicepod": "string",
    "image_tag": "string",
    "update_channel": "stable",
    "version": "string",
    "replicas": 0,
    "resources": {},
    "executor": {},
    "region": "string",
    "cluster_name": "string",
    "storage_size_gb": 0,
    "storage_claim_size_gb": 0
  }'
```

```http
PUT /v1/projects/<projectId> HTTP/1.1
Host: api.spice.ai
Authorization: Bearer <token>
Content-Type: application/json
Content-Length: 362

{
  "description": "string",
  "visibility": "public",
  "production_branch": "string",
  "tags": {},
  "spicepod": "string",
  "image_tag": "string",
  "update_channel": "stable",
  "version": "string",
  "replicas": 0,
  "resources": {},
  "executor": {},
  "region": "string",
  "cluster_name": "string",
  "storage_size_gb": 0,
  "storage_claim_size_gb": 0
}
```

### Responses

**200 OK**

Project updated successfully

Content type: `application/json`

- `id` (integer): Unique identifier for the project
- `name` (string): Name of the project
- `kind` (string): Resolved project hosting model. Allowed values: `managed`, `standalone`, `byoc`.
- `description` (string | null): Description of the project
- `visibility` (string): Visibility setting for the project. Allowed values: `public`, `private`.
- `created_at` (string (date-time)): Timestamp when the project was created
- `cname` (string | null): Region identifier
- `cluster_name` (string | null): Resolved dedicated cluster name; null for projects not assigned to a dedicated cluster.
- `endpoint` (string | null): The data-plane endpoint the project connects to, or null before a standalone instance is attached.
- `production_branch` (string | null): Production branch for the project
- `api_key` (string, deprecated): Deprecated. Use the API Keys endpoints instead.
- `tags` (map of string | null): Key-value tags for the project
- `forked_from` (object | null): The project this project was forked from, while that project is live in the same organization. Null for a project that was not created as a fork.
  - `id` (integer, required): ID of the source project
  - `name` (string, required): Name of the source project
- `paused_at` (string (date-time) | null): Timestamp when the project was paused; null while running
- `warning` (string | null): Present when the project was created but initial configuration could not be applied
- `config` (object | null): Runtime configuration; null for an unattached standalone project.
  - `spicepod` (object | null): Spicepod configuration
  - `registry` (string | null): Container registry for the runtime image
  - `image_tag` (string | null): Runtime image tag
  - `update_channel` (string | null): Update channel for the runtime. Allowed values: `stable`, `preview`, `nightly`.
  - `replicas` (integer): Number of replicas
  - `resources` (object | null): Resource requests and limits for the project container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `executor` (object | null): Executor container configuration
    - `replicas` (integer): Number of executor replicas
    - `resources` (object): Resource requests and limits for the executor container
      - `limits` (object)
        - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
        - `memory` (string): Memory limit in Gi (for example, 16Gi)
        - `ephemeral-storage` (string)
      - `requests` (object)
        - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
        - `memory` (string): Memory request. Minimum 192Mi.
  - `region` (string | null): Cloud region code (e.g., us-east-1)
  - `node_group` (string | null): Node group for scheduling the project runtime
  - `storage_claim_size_gb` (number | null): Storage claim size in GB

**400 Bad Request**

Invalid request body or project ID, including placement or hosted runtime fields that do not apply to standalone projects. When `image_tag` is supplied on stable or preview, a tag that is not a published version for that channel returns `{ error: 'Invalid image_tag for stable channel', code: 'invalid_stable_image_tag' }` (or the preview analog). A `spicepod` that adds a component on a source the Spice runtime no longer loads returns code `retired_component_source`; components the project already stores on such a source may be kept, edited and renamed, and a project backed by a GitHub repository is not checked.

**401 Unauthorized**

Unauthorized

**403 Forbidden**

Insufficient scope, viewer role cannot mutate projects, requested replicas or resources exceed plan limits, dedicated-cluster assignment or special-org private-compute ceilings required, requested resources exceed dedicated-cluster capacity, `image_tag` was supplied outside the Enterprise plan (code: `image_tag_requires_enterprise`), or the requested runtime image is not available for the organization plan (code: `image_tag_not_allowed_for_plan`); omitting `image_tag` leaves the configured image unchanged

**404 Not Found**

Project not found

**409 Conflict**

The project's lifecycle state changed while the update was in flight — a pause, resume or restore landing concurrently — so the configuration was not saved (code: `project_state_changed`). Re-read the project before retrying: a configuration update clears `paused_at`, so repeating this request against a project that has since been paused also resumes it. Or a `spicepod` that differs from the stored one was sent for a project connected to a GitHub repository (code: `github_connected`); change spicepod.yaml in the repository instead, since nothing in that request is applied.

**500 Internal Server Error**

Internal server error

**502 Bad Gateway**

The configuration was stored but could not be published to the spicepod registry (code: `registry_publish_failed`), so the project still deploys its previously published configuration. Retry the request.

**503 Service Unavailable**

Runtime version catalog is unavailable

## `PUT /v1/orgs/{orgId}/projects/{projectId}`

The org is `orgId` in the path. Updates a project's metadata and configuration, including description, visibility, spicepod configuration, replicas, and resource limits.

### Path parameters

- `orgId` (integer, required): The org id from GET /v1/orgs. Minimum: `1`.
- `projectId` (integer, required): The ID of the project

### Header parameters

- `Authorization` (string, required): `Bearer <token>`. [Authentication](https://spice.ai/docs/cloud/api/management#authentication) lists the tokens it accepts.
- `X-Org-Name` (string, optional): When present, X-Org-Name must name the same org as orgId. Otherwise the request returns org\_path\_mismatch (400). Pattern: `^[A-Za-z0-9._-]{1,255}$`.

### Request body

Required.

Content type: `application/json`

- `description` (string)
- `visibility` (string): Allowed values: `public`, `private`.
- `production_branch` (string)
- `tags` (map of string): Key-value tags for the project. The map replaces the stored tags. System tags the project already has stay on the project when the map omits them.
- `spicepod` (string | object): The project's Spicepod. A project connected to a GitHub repository takes its Spicepod from the repository's spicepod.yaml, so for such a project only the stored Spicepod, sent back unchanged, is accepted.
- `image_tag` (string | null): Runtime image tag for a managed project; rejected for standalone projects. A non-empty value pins the project. On stable, the pin must be a published stable runtime version. On preview, it must be a published preview or stable runtime version. On stable or preview, send null to clear a pin so deploys resolve from the channel catalog (stable - latest GA for the configured version range; preview - latest RC). null is rejected on nightly and internal channels.
- `update_channel` (string): Update channel for a managed runtime; rejected for standalone projects. Allowed values: `stable`, `preview`, `nightly`.
- `version` (string): Semver range for a managed runtime version (e.g. 1.x, 2.x); rejected for standalone projects.
- `replicas` (integer): Managed runtime replica count; rejected for standalone projects. Minimum: `0`.
- `resources` (object): Resource requests and limits for a managed project container; rejected for standalone projects.
  - `limits` (object)
    - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
    - `memory` (string): Memory limit in Gi (for example, 16Gi)
    - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
  - `requests` (object)
    - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
    - `memory` (string): Memory request. Minimum 192Mi.
- `executor` (object): Executor container configuration for a managed project; rejected for standalone projects.
  - `replicas` (integer): Number of executor replicas. Minimum: `0`.
  - `resources` (object): Resource requests and limits for the executor container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `storage_size_gb` (number)
- `region` (string): Managed project region; standalone placement is resolved during attachment.
- `cluster_name` (string): Reassign the project to a dedicated cluster, as listed by `GET /v1/clusters`. Provide at most one of `region` or `cluster_name`. When set, region/routing are derived from the cluster; if `region` is also provided it must match the cluster's region. Rejected for standalone projects, whose placement is resolved during attachment.
- `storage_size_gb` (number): Managed runtime storage size; rejected for standalone projects.
- `storage_claim_size_gb` (number, deprecated): Deprecated. Use storage\_size\_gb instead. Rejected for standalone projects.

### Example request

```bash
curl -X PUT "https://api.spice.ai/v1/orgs/<orgId>/projects/<projectId>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "string",
    "visibility": "public",
    "production_branch": "string",
    "tags": {},
    "spicepod": "string",
    "image_tag": "string",
    "update_channel": "stable",
    "version": "string",
    "replicas": 0,
    "resources": {},
    "executor": {},
    "region": "string",
    "cluster_name": "string",
    "storage_size_gb": 0,
    "storage_claim_size_gb": 0
  }'
```

```http
PUT /v1/orgs/<orgId>/projects/<projectId> HTTP/1.1
Host: api.spice.ai
Authorization: Bearer <token>
Content-Type: application/json
Content-Length: 362

{
  "description": "string",
  "visibility": "public",
  "production_branch": "string",
  "tags": {},
  "spicepod": "string",
  "image_tag": "string",
  "update_channel": "stable",
  "version": "string",
  "replicas": 0,
  "resources": {},
  "executor": {},
  "region": "string",
  "cluster_name": "string",
  "storage_size_gb": 0,
  "storage_claim_size_gb": 0
}
```

### Responses

**200 OK**

Project updated successfully

Content type: `application/json`

- `id` (integer): Unique identifier for the project
- `name` (string): Name of the project
- `kind` (string): Resolved project hosting model. Allowed values: `managed`, `standalone`, `byoc`.
- `description` (string | null): Description of the project
- `visibility` (string): Visibility setting for the project. Allowed values: `public`, `private`.
- `created_at` (string (date-time)): Timestamp when the project was created
- `cname` (string | null): Region identifier
- `cluster_name` (string | null): Resolved dedicated cluster name; null for projects not assigned to a dedicated cluster.
- `endpoint` (string | null): The data-plane endpoint the project connects to, or null before a standalone instance is attached.
- `production_branch` (string | null): Production branch for the project
- `api_key` (string, deprecated): Deprecated. Use the API Keys endpoints instead.
- `tags` (map of string | null): Key-value tags for the project
- `forked_from` (object | null): The project this project was forked from, while that project is live in the same organization. Null for a project that was not created as a fork.
  - `id` (integer, required): ID of the source project
  - `name` (string, required): Name of the source project
- `paused_at` (string (date-time) | null): Timestamp when the project was paused; null while running
- `warning` (string | null): Present when the project was created but initial configuration could not be applied
- `config` (object | null): Runtime configuration; null for an unattached standalone project.
  - `spicepod` (object | null): Spicepod configuration
  - `registry` (string | null): Container registry for the runtime image
  - `image_tag` (string | null): Runtime image tag
  - `update_channel` (string | null): Update channel for the runtime. Allowed values: `stable`, `preview`, `nightly`.
  - `replicas` (integer): Number of replicas
  - `resources` (object | null): Resource requests and limits for the project container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `executor` (object | null): Executor container configuration
    - `replicas` (integer): Number of executor replicas
    - `resources` (object): Resource requests and limits for the executor container
      - `limits` (object)
        - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
        - `memory` (string): Memory limit in Gi (for example, 16Gi)
        - `ephemeral-storage` (string)
      - `requests` (object)
        - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
        - `memory` (string): Memory request. Minimum 192Mi.
  - `region` (string | null): Cloud region code (e.g., us-east-1)
  - `node_group` (string | null): Node group for scheduling the project runtime
  - `storage_claim_size_gb` (number | null): Storage claim size in GB

**400 Bad Request**

Invalid request body or project ID, including placement or hosted runtime fields that do not apply to standalone projects. When `image_tag` is supplied on stable or preview, a tag that is not a published version for that channel returns `{ error: 'Invalid image_tag for stable channel', code: 'invalid_stable_image_tag' }` (or the preview analog). A `spicepod` that adds a component on a source the Spice runtime no longer loads returns code `retired_component_source`; components the project already stores on such a source may be kept, edited and renamed, and a project backed by a GitHub repository is not checked. orgId is not a valid org id (`invalid_org_id`), or X-Org-Name does not name that org (`org_path_mismatch`).

**401 Unauthorized**

Unauthorized

**403 Forbidden**

Insufficient scope, viewer role cannot mutate projects, requested replicas or resources exceed plan limits, dedicated-cluster assignment or special-org private-compute ceilings required, requested resources exceed dedicated-cluster capacity, `image_tag` was supplied outside the Enterprise plan (code: `image_tag_requires_enterprise`), or the requested runtime image is not available for the organization plan (code: `image_tag_not_allowed_for_plan`); omitting `image_tag` leaves the configured image unchanged. The caller is not a member of the org (`org_forbidden`). A machine credential named a different org (`org_assertion_mismatch`). The org is deleted (`org_deleted`).

**404 Not Found**

Project not found

**409 Conflict**

The project's lifecycle state changed while the update was in flight — a pause, resume or restore landing concurrently — so the configuration was not saved (code: `project_state_changed`). Re-read the project before retrying: a configuration update clears `paused_at`, so repeating this request against a project that has since been paused also resumes it. Or a `spicepod` that differs from the stored one was sent for a project connected to a GitHub repository (code: `github_connected`); change spicepod.yaml in the repository instead, since nothing in that request is applied.

**500 Internal Server Error**

Internal server error

**502 Bad Gateway**

The configuration was stored but could not be published to the spicepod registry (code: `registry_publish_failed`), so the project still deploys its previously published configuration. Retry the request.

**503 Service Unavailable**

Runtime version catalog is unavailable

## `PUT /v1/apps/{appId}` (deprecated)

Legacy alias of `/v1/projects/{projectId}` — projects were previously called apps. Updates a project's metadata and configuration, including description, visibility, spicepod configuration, replicas, and resource limits.

### Path parameters

- `appId` (integer, required): The ID of the project

### Header parameters

- `Authorization` (string, required): `Bearer <token>`. [Authentication](https://spice.ai/docs/cloud/api/management#authentication) lists the tokens it accepts.
- `X-Org-Name` (string, optional): The organization to act on, by handle. Omit it to act on the organization the credential is bound to; sending it blank is a 400, not the same as omitting it. A user credential may name any organization its owner belongs to; a machine credential is pinned to its own. A portal session token is bound to none, so it must send this header on every route but `GET /v1/orgs` (400 `org_assertion_required` otherwise). Pattern: `^[A-Za-z0-9._-]{1,255}$`.

### Request body

Required.

Content type: `application/json`

- `description` (string)
- `visibility` (string): Allowed values: `public`, `private`.
- `production_branch` (string)
- `tags` (map of string): Key-value tags for the project. The map replaces the stored tags. System tags the project already has stay on the project when the map omits them.
- `spicepod` (string | object): The project's Spicepod. A project connected to a GitHub repository takes its Spicepod from the repository's spicepod.yaml, so for such a project only the stored Spicepod, sent back unchanged, is accepted.
- `image_tag` (string | null): Runtime image tag for a managed project; rejected for standalone projects. A non-empty value pins the project. On stable, the pin must be a published stable runtime version. On preview, it must be a published preview or stable runtime version. On stable or preview, send null to clear a pin so deploys resolve from the channel catalog (stable - latest GA for the configured version range; preview - latest RC). null is rejected on nightly and internal channels.
- `update_channel` (string): Update channel for a managed runtime; rejected for standalone projects. Allowed values: `stable`, `preview`, `nightly`.
- `version` (string): Semver range for a managed runtime version (e.g. 1.x, 2.x); rejected for standalone projects.
- `replicas` (integer): Managed runtime replica count; rejected for standalone projects. Minimum: `0`.
- `resources` (object): Resource requests and limits for a managed project container; rejected for standalone projects.
  - `limits` (object)
    - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
    - `memory` (string): Memory limit in Gi (for example, 16Gi)
    - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
  - `requests` (object)
    - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
    - `memory` (string): Memory request. Minimum 192Mi.
- `executor` (object): Executor container configuration for a managed project; rejected for standalone projects.
  - `replicas` (integer): Number of executor replicas. Minimum: `0`.
  - `resources` (object): Resource requests and limits for the executor container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string): Ephemeral storage limit in Gi (for example, 8Gi)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `storage_size_gb` (number)
- `region` (string): Managed project region; standalone placement is resolved during attachment.
- `cluster_name` (string): Reassign the project to a dedicated cluster, as listed by `GET /v1/clusters`. Provide at most one of `region` or `cluster_name`. When set, region/routing are derived from the cluster; if `region` is also provided it must match the cluster's region. Rejected for standalone projects, whose placement is resolved during attachment.
- `storage_size_gb` (number): Managed runtime storage size; rejected for standalone projects.
- `storage_claim_size_gb` (number, deprecated): Deprecated. Use storage\_size\_gb instead. Rejected for standalone projects.

### Example request

```bash
curl -X PUT "https://api.spice.ai/v1/apps/<appId>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "string",
    "visibility": "public",
    "production_branch": "string",
    "tags": {},
    "spicepod": "string",
    "image_tag": "string",
    "update_channel": "stable",
    "version": "string",
    "replicas": 0,
    "resources": {},
    "executor": {},
    "region": "string",
    "cluster_name": "string",
    "storage_size_gb": 0,
    "storage_claim_size_gb": 0
  }'
```

```http
PUT /v1/apps/<appId> HTTP/1.1
Host: api.spice.ai
Authorization: Bearer <token>
Content-Type: application/json
Content-Length: 362

{
  "description": "string",
  "visibility": "public",
  "production_branch": "string",
  "tags": {},
  "spicepod": "string",
  "image_tag": "string",
  "update_channel": "stable",
  "version": "string",
  "replicas": 0,
  "resources": {},
  "executor": {},
  "region": "string",
  "cluster_name": "string",
  "storage_size_gb": 0,
  "storage_claim_size_gb": 0
}
```

### Responses

**200 OK**

Project updated successfully

Content type: `application/json`

- `id` (integer): Unique identifier for the project
- `name` (string): Name of the project
- `kind` (string): Resolved project hosting model. Allowed values: `managed`, `standalone`, `byoc`.
- `description` (string | null): Description of the project
- `visibility` (string): Visibility setting for the project. Allowed values: `public`, `private`.
- `created_at` (string (date-time)): Timestamp when the project was created
- `cname` (string | null): Region identifier
- `cluster_name` (string | null): Resolved dedicated cluster name; null for projects not assigned to a dedicated cluster.
- `endpoint` (string | null): The data-plane endpoint the project connects to, or null before a standalone instance is attached.
- `production_branch` (string | null): Production branch for the project
- `api_key` (string, deprecated): Deprecated. Use the API Keys endpoints instead.
- `tags` (map of string | null): Key-value tags for the project
- `forked_from` (object | null): The project this project was forked from, while that project is live in the same organization. Null for a project that was not created as a fork.
  - `id` (integer, required): ID of the source project
  - `name` (string, required): Name of the source project
- `paused_at` (string (date-time) | null): Timestamp when the project was paused; null while running
- `warning` (string | null): Present when the project was created but initial configuration could not be applied
- `config` (object | null): Runtime configuration; null for an unattached standalone project.
  - `spicepod` (object | null): Spicepod configuration
  - `registry` (string | null): Container registry for the runtime image
  - `image_tag` (string | null): Runtime image tag
  - `update_channel` (string | null): Update channel for the runtime. Allowed values: `stable`, `preview`, `nightly`.
  - `replicas` (integer): Number of replicas
  - `resources` (object | null): Resource requests and limits for the project container
    - `limits` (object)
      - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
      - `memory` (string): Memory limit in Gi (for example, 16Gi)
      - `ephemeral-storage` (string)
    - `requests` (object)
      - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
      - `memory` (string): Memory request. Minimum 192Mi.
  - `executor` (object | null): Executor container configuration
    - `replicas` (integer): Number of executor replicas
    - `resources` (object): Resource requests and limits for the executor container
      - `limits` (object)
        - `cpu` (string): Whole-number vCPU limit, or '-' for no CPU limit
        - `memory` (string): Memory limit in Gi (for example, 16Gi)
        - `ephemeral-storage` (string)
      - `requests` (object)
        - `cpu` (string): CPU request. Minimum 100 millicores (for example, 100m or 0.1).
        - `memory` (string): Memory request. Minimum 192Mi.
  - `region` (string | null): Cloud region code (e.g., us-east-1)
  - `node_group` (string | null): Node group for scheduling the project runtime
  - `storage_claim_size_gb` (number | null): Storage claim size in GB

**400 Bad Request**

Invalid request body or project ID, including placement or hosted runtime fields that do not apply to standalone projects. When `image_tag` is supplied on stable or preview, a tag that is not a published version for that channel returns `{ error: 'Invalid image_tag for stable channel', code: 'invalid_stable_image_tag' }` (or the preview analog). A `spicepod` that adds a component on a source the Spice runtime no longer loads returns code `retired_component_source`; components the project already stores on such a source may be kept, edited and renamed, and a project backed by a GitHub repository is not checked.

**401 Unauthorized**

Unauthorized

**403 Forbidden**

Insufficient scope, viewer role cannot mutate projects, requested replicas or resources exceed plan limits, dedicated-cluster assignment or special-org private-compute ceilings required, requested resources exceed dedicated-cluster capacity, `image_tag` was supplied outside the Enterprise plan (code: `image_tag_requires_enterprise`), or the requested runtime image is not available for the organization plan (code: `image_tag_not_allowed_for_plan`); omitting `image_tag` leaves the configured image unchanged

**404 Not Found**

Project not found

**409 Conflict**

The project's lifecycle state changed while the update was in flight — a pause, resume or restore landing concurrently — so the configuration was not saved (code: `project_state_changed`). Re-read the project before retrying: a configuration update clears `paused_at`, so repeating this request against a project that has since been paused also resumes it. Or a `spicepod` that differs from the stored one was sent for a project connected to a GitHub repository (code: `github_connected`); change spicepod.yaml in the repository instead, since nothing in that request is applied.

**500 Internal Server Error**

Internal server error

**502 Bad Gateway**

The configuration was stored but could not be published to the spicepod registry (code: `registry_publish_failed`), so the project still deploys its previously published configuration. Retry the request.

**503 Service Unavailable**

Runtime version catalog is unavailable

OpenAPI: [api.spice.ai/openapi.json](https://api.spice.ai/openapi.json)
