# Create a server

Creates a cloud server for Forge in the chosen offering, location and size, at the price the person confirmed (`quote`, from [Get offering options](/docs/api-reference/forge-compute/get-offering-options)). The server is created in the background: the answer is `202 Accepted` with the server in `creating`. Poll [Get a server](/docs/api-reference/forge-compute/get-host) about every two seconds until it reaches `awaiting_client` (or ends in `failed_clean` or `failed_billing`); the server moves `creating` → `booting` → `awaiting_client`, and then the client takes it through setup (see the [lifecycle](/docs/api-reference/forge-compute/introduction#creating-and-setting-up-a-server)).

The id is chosen by the client, which makes the call safe to retry: sending the same `id` again returns the server that id already names (whatever the rest of the body says) and never creates a second one. The server's login user (`ssh_user`, always `forge`), `ssh_port` and — once the backend has generated it — `bootstrap_host_key_pub`, the bootstrap host key (K0) to pin on the first connection, are on the server record. Only public keys are stored or returned; the server accepts logins only with `client_public_key`.

**Billing.** The server is billed to the organization named in `organization_id`, and only to it: every hour, a resume and a parked copy are charged there for the server's whole life. Offer the choice with [List billing organizations](/docs/api-reference/forge-compute/list-billing-organizations) and preselect its `default_organization_id`; the backend never infers it. An Aitronos server (`aitronos`) is charged to that organization per started hour at exactly the quoted `hourly` price in CHF, never more than the size's `monthly_cap` in a calendar month, from the moment the server exists until it is gone. A server in your own account is billed to that organization by the provider; Aitronos meters nothing for it.

**Project groups.** When the server is rented inside a Forge project group, send the group's Forge id as `project_group_id` (registered with [Register or update a project group](/docs/api-reference/forge-compute/put-project-group)). When that group bills to an organization (its own or its nearest registered ancestor's, as [List project groups](/docs/api-reference/forge-compute/list-project-groups) shows in `organization`), `organization_id` must be that organization: another one is refused with `422 FORGE_PROJECT_GROUP_ORGANIZATION_MISMATCH`, and a group whose organization you can no longer use Forge in is refused with `403 FORGE_PROJECT_GROUP_ORGANIZATION_UNAVAILABLE`, never billed somewhere else. The server then names the group in `project_group`, and its usage is shown under the group on the organization's [usage report](/assets/get-usage-detail-report.45870ea5b94806d0570403fa53ae031e4b48417dddf0f27bd3aa2fc29b7ba55c.49b960d1.md). A server stays billed to the organization it was rented in: changing or deleting the group later never moves it. A group that is not registered is ignored, and the server is created as if no group had been sent.

It acts for a person: it requires a bearer token whose user is an active member of `organization_id`, holds the `use_forge` capability there, and Forge cloud compute switched on for that organization.

#### Headers

**`X-Organization-Id`** string optional

Not needed: the body names the organization. If sent (or sent as the `organization_id` query parameter), it must name the same organization as the body, or the request is refused with `INVALID_FIELD_VALUE` (`details.reason` `organization_mismatch`).

#### Body Parameters

**`id`** string required

The server's id, chosen by the client: a UUID (any case, with or without hyphens) or `fchost_` followed by 32 hex characters. It is returned, and accepted in paths, as `fchost_<32 hex>`. Sending an id that already names a server of yours returns that server; an id already used by a different server is refused with `FORGE_COMPUTE_HOST_ID_CONFLICT`.

**`organization_id`** string required

The organization the server is billed to: an organization marked `selectable` in [List billing organizations](/docs/api-reference/forge-compute/list-billing-organizations). It becomes the server's `organization`, and every later charge for the server goes there.

**`offering_id`** string required

The offering to run the server on, from the catalog, e.g. `aitronos`. A bring-your-own offering needs a connected account.

**`location_id`** string required

A location id from the offering's options, e.g. `eu-central`.

The size is given in exactly one of three ways — `size_id`, `machine_type_id`, or `vcpu` with `memory_gb` — otherwise the request is refused with `VALIDATION_ERROR` (`details.reason` `size_choice`).

**`size_id`** string optional

A size id from the offering's options `sizes`, e.g. `std-16`.

**`machine_type_id`** string optional

Aitronos servers only: a machine type id from the options `machine_types` (or a `resolutions` entry), e.g. `ded-x86-48c-192g`. Priced and created exactly like a size id.

**`vcpu`** integer optional

Aitronos servers only, with `memory_gb`: the vCPUs wanted, 1 to 4096. The server is the cheapest one in the location with at least this many vCPUs and at least `memory_gb` — the same answer as [Resolve a free size](/docs/api-reference/forge-compute/resolve-offering-size), so confirm the `quote` of that answer. When no server there has both, the request is refused with `FORGE_COMPUTE_CAPACITY_UNAVAILABLE` naming the largest server there.

**`memory_gb`** integer optional

Aitronos servers only, with `vcpu`: the memory wanted in GB, 1 to 65536.

**`name`** string required

A name for the server, 1 to 63 characters after surrounding spaces are removed, without control characters.

**`client_public_key`** string required

The OpenSSH public key the client will log in with, as exactly one line: `ssh-ed25519`, `ecdsa-sha2-nistp256/384/521`, `sk-ssh-ed25519@openssh.com`, or `ssh-rsa` of 3072 to 16384 bits. No options prefix and no certificates; the comment is kept, reduced to letters, digits and `@._-`, at most 64 characters. A private key is refused.

**`quote`** object required

The price the person confirmed, exactly as the options quoted it. It must match the live price, or the request is refused with `FORGE_COMPUTE_PRICE_CHANGED` and the live quote in `details.quote`: show it and ask again.

- **`hourly`** string, required — the hourly price as quoted, e.g. `"0.83"`. Compared as a decimal, so `"0.830"` equals `"0.83"`.
- **`currency`** string, required — the currency of `hourly`, e.g. `CHF`.
- **`catalog_version`** string, required — the `catalog_version` the quote came with.


**`project_group_id`** string optional

Forge's own id for the project group the server is rented in (its `client_id` in [List project groups](/docs/api-reference/forge-compute/list-project-groups)), at most 128 characters; an empty or blank value is the same as leaving it out. When the group bills to an organization (its own or an ancestor's), `organization_id` must be that organization, else `FORGE_PROJECT_GROUP_ORGANIZATION_MISMATCH` (422); when you can no longer use Forge there, `FORGE_PROJECT_GROUP_ORGANIZATION_UNAVAILABLE` (403). A group billed to no organization is accepted with any `organization_id`. The server's usage is shown under the group on the organization's usage report. A group that is not registered (or was deleted) is ignored: `project_group` is then `null`.

Unknown fields are refused.

## Returns

`202 Accepted` with the [server object](/docs/api-reference/forge-compute/get-host#returns) in `creating`. A repeat of the same `id` also answers `202` with the server in whatever state it has reached.


```json
{
  "id": "fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90",
  "offering_id": "aitronos",
  "kind": "managed",
  "name": "build-box",
  "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
  "user_id": "usr_7f3a9c2e1b8d4e6fa0c5b3d9e2f1a4c7",
  "project_group": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
  "location_id": "eu-central",
  "location_label": "Germany",
  "size_id": "std-16",
  "size_label": "16 vCPU · 64 GB",
  "state": "creating",
  "state_label": "Creating the server",
  "transient": true,
  "step": null,
  "step_started_at": null,
  "state_changed_at": "2026-09-28T09:00:00.184066Z",
  "failure": null,
  "ipv4": null,
  "ipv6": null,
  "ssh_port": 22,
  "ssh_user": "forge",
  "bootstrap_host_key_pub": null,
  "host_key_pub": null,
  "price": {
    "hourly": "0.83",
    "monthly_cap": "520.30",
    "currency": "CHF",
    "source": "aitronos",
    "includes_vat": false,
    "catalog_version": "fc-3b8e1f0a9c42",
    "quoted_at": "2026-09-28T09:00:00.184066Z",
    "parked_per_gb_month": "0.0269",
    "price_verified": true
  },
  "month_to_date": "0.00",
  "notice": null,
  "idle_reminder": null,
  "reconcile_flags": null,
  "actions": ["delete", "revoke"],
  "created_at": "2026-09-28T09:00:00.184066Z",
  "ready_at": null,
  "parked_at": null,
  "parked_expires_at": null,
  "deleted_at": null,
  "revoked_at": null,
  "revoke_reason": null,
  "last_activity_at": null
}
```

A server that cannot be created after the `202` (for example the provider has no capacity for the size in that location) ends in `failed_clean` with `failure.code` set to the same code this endpoint would have returned, e.g. `FORGE_COMPUTE_CAPACITY_UNAVAILABLE` with `failure.details.alternatives`. Nothing is running and nothing is charged; delete it and create again.

## Errors

| Status | Code | When |
|  --- | --- | --- |
| 401 | `AUTHENTICATION_REQUIRED` | No credential, or a credential with no user (an organization API key). |
| 402 | `FORGE_COMPUTE_SPEND_LIMIT_REACHED` | Aitronos servers only: a spending limit of the organization is reached, or cannot absorb one more hour at the quoted price. `details.reason` is `spend_limit_reached`, `headroom_below_one_hour` or `compute_share_below_one_hour` (ask an admin to raise the limit); `org_compute_limit_reached` when one more hour would pass the organization's [monthly limit for Aitronos servers](/docs/api-reference/forge-compute/update-organization-limits) ("Your organization's monthly limit for Aitronos servers does not allow another server hour. Someone who manages billing can raise it on the Machines page."); or `member_limit_reached` when it would pass your own [per-person limit](/docs/api-reference/forge-compute/get-limits) ("Your monthly limit for Aitronos servers (CHF 12.50) does not allow another server hour." followed by "You can raise or clear your own limit on the Machines page." when your [own limit](/docs/api-reference/forge-compute/update-my-limit) applies, else "Someone who manages billing can raise it on the Machines page."). Show `message` as is. |
| 403 | `ORGANIZATION_ACCESS_DENIED` | `organization_id` names an organization you are not an active member of. |
| 403 | `INSUFFICIENT_PERMISSIONS` | The user does not hold `use_forge` in `organization_id`. |
| 403 | `FORGE_COMPUTE_DISABLED` | Forge cloud compute is not switched on for `organization_id`. |
| 403 | `FORGE_COMPUTE_OFFERING_BLOCKED` | The offering cannot be used in this environment. |
| 403 | `FORGE_COMPUTE_OFFERING_NOT_OFFERED` | The offering is not offered to you right now: switched off, switched off for your organization, or offered to Aitronos staff only. `message` names the offering (for example "DigitalOcean is not offered right now.") and `details.offering_id` is its id. Nothing was created. |
| 403 | `FORGE_PROJECT_GROUP_ORGANIZATION_UNAVAILABLE` | `project_group_id` names a group that bills to an organization where you can no longer use Forge (you left it, lost `use_forge` there, or the credential is not granted it). `message` names it ("This project group is billed to Client Workspace, where you can no longer use Forge. Choose another organization for the group."); `details` carries `client_id` and `organization_id`. Nothing was created and nothing is billed elsewhere. |
| 404 | `FORGE_COMPUTE_OFFERING_NOT_FOUND` | No offering has this id. |
| 409 | `FORGE_COMPUTE_PRICE_CHANGED` | The quote no longer matches the live price (hourly, currency or catalog version). `details.quote` is the live quote to confirm. A create by `vcpu` and `memory_gb` also gets `details.machine_type_id`, the machine type that price is for. |
| 409 | `FORGE_COMPUTE_CAPACITY_UNAVAILABLE` | The size cannot be ordered in that location now. `details.alternatives` lists up to three placements that can, each `{location_id, size_id, hourly, currency}`. |
| 409 | `FORGE_COMPUTE_CAPACITY_UNAVAILABLE` | A create by `vcpu` and `memory_gb` that no server in the location meets: `details.reason` is `no_size_large_enough`, `message` names the largest server there (for example "The largest server in Germany has 48 vCPU and 192 GB."), and `details.alternatives` lists the other locations where the choice can be met. |
| 409 | `FORGE_COMPUTE_HOST_ID_CONFLICT` | The `id` already names a different server. Generate a new id. |
| 422 | `FORGE_COMPUTE_CREDENTIAL_MISSING` | A bring-your-own offering whose account is not connected. |
| 422 | `FORGE_COMPUTE_CREDENTIAL_REJECTED` | The provider no longer accepts the connected account. |
| 422 | `FORGE_COMPUTE_INVALID_PUBLIC_KEY` | `client_public_key` is not one accepted OpenSSH public key. `details.reason` says why. |
| 422 | `FORGE_PROJECT_GROUP_ORGANIZATION_MISMATCH` | `project_group_id` names a group that bills to another organization than `organization_id`. `message` names it ("This project is billed to Acme Engineering through its project group. Rent the server in Acme Engineering, or change the group's organization first."); `details` is `{"field": "organization_id", "reason": "project_group_organization_mismatch", "client_id", "organization_id"}`, where `organization_id` is the organization the group bills to. Nothing was created. |
| 422 | `INVALID_FIELD_VALUE` | The `organization_id` query parameter or `X-Organization-Id` header names a different organization than the body: `details` is `{"field": "organization_id", "reason": "organization_mismatch"}`. Nothing was created. |
| 422 | `INVALID_ID_FORMAT` | `id` is neither a UUID nor `fchost_<32 hex>`. |
| 422 | `VALIDATION_ERROR` | A body of the wrong shape (including a missing `organization_id`), an unknown field, a `name` that is empty, longer than 63 characters or holds control characters, or a `project_group_id` longer than 128 characters. Also: the size given in none or more than one way (`details.reason` `size_choice`), or `machine_type_id`, `vcpu` or `memory_gb` for a bring-your-own offering (`details.reason` `free_sizing_unsupported`). |
| 502 | `FORGE_COMPUTE_PROVIDER_UNREACHABLE` | The provider could not be reached to confirm the price. |
| 503 | `FORGE_COMPUTE_PRICE_UNAVAILABLE` | No verified price, or no spending reading, could be taken right now, so nothing was created. Retry after `details.retry_after` seconds. |
| 503 | `FORGE_COMPUTE_PLATFORM_CAPACITY_REACHED` | Aitronos servers only: Aitronos servers are at capacity for now, so nothing was created. Nothing your organization changes lifts it; try again later (after `details.retry_after` seconds). |



```bash cURL
curl -X POST "https://api.aitronos.com/v1/forge/compute/hosts" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "5d0c2b9e-7a41-4f3c-9e8b-1a6d2f4c7e90",
    "organization_id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",
    "offering_id": "aitronos",
    "location_id": "eu-central",
    "size_id": "std-16",
    "name": "build-box",
    "client_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleClientKeyForDocumentationOnly000000 dev@laptop",
    "quote": {"hourly": "0.83", "currency": "CHF", "catalog_version": "fc-3b8e1f0a9c42"},
    "project_group_id": "grp-clients"
  }'
```


```python Python SDK
# pip install aitronos-sdk
#
# The Python SDK does not expose a typed `forge_compute` namespace yet, so call
# the endpoint directly with the same bearer token you would pass to `Aitronos(...)`.
import uuid
import httpx

ACCESS_TOKEN = "your-access-token"
headers = {"Authorization": f"Bearer {ACCESS_TOKEN}"}

body = {
    "id": str(uuid.uuid4()),  # keep it: resending it never creates a second server
    "organization_id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",  # from the billing organizations
    "offering_id": "aitronos",
    "location_id": "eu-central",
    "size_id": "std-16",
    "name": "build-box",
    "client_public_key": open("/Users/dev/.ssh/id_ed25519.pub").read().strip(),
    "quote": {"hourly": "0.83", "currency": "CHF", "catalog_version": "fc-3b8e1f0a9c42"},
    "project_group_id": "grp-clients",  # optional: Forge's id for the project group
}
response = httpx.post(
    "https://api.aitronos.com/v1/forge/compute/hosts", headers=headers, json=body
)
error = response.json().get("error") if response.is_error else None
if error and error["code"] == "FORGE_COMPUTE_PRICE_CHANGED":
    print("Ask again at", error["details"]["quote"])
elif error and error["code"] == "FORGE_PROJECT_GROUP_ORGANIZATION_MISMATCH":
    print("Rent it in", error["details"]["organization_id"], "-", error["message"])
elif error:
    print(error["message"])
else:
    host = response.json()
    print(host["id"], host["state"])
```


```python Python
import os
import time
import uuid
import requests

token = os.environ["AITRONOS_TOKEN"]
headers = {"Authorization": f"Bearer {token}"}
base = "https://api.aitronos.com/v1/forge/compute"

host = requests.post(
    f"{base}/hosts",
    headers=headers,
    json={
        "id": str(uuid.uuid4()),
        "organization_id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",
        "offering_id": "aitronos",
        "location_id": "eu-central",
        "size_id": "std-16",
        "name": "build-box",
        "client_public_key": os.environ["FORGE_CLIENT_PUBLIC_KEY"],
        "quote": {"hourly": "0.83", "currency": "CHF", "catalog_version": "fc-3b8e1f0a9c42"},
        "project_group_id": "grp-clients",
    },
).json()

while host["state"] in ("creating", "booting"):
    time.sleep(2)
    host = requests.get(f"{base}/hosts/{host['id']}", headers=headers).json()
print(host["state"], host["ipv4"], host["bootstrap_host_key_pub"])
```


```javascript JavaScript
const response = await fetch("https://api.aitronos.com/v1/forge/compute/hosts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.AITRONOS_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    id: crypto.randomUUID(),
    organization_id: "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",
    offering_id: "aitronos",
    location_id: "eu-central",
    size_id: "std-16",
    name: "build-box",
    client_public_key: process.env.FORGE_CLIENT_PUBLIC_KEY,
    quote: { hourly: "0.83", currency: "CHF", catalog_version: "fc-3b8e1f0a9c42" },
    project_group_id: "grp-clients",
  }),
});
const host = await response.json();
console.log(response.status, host.id, host.state); // 202 fchost_... creating
```

**Response:**

202 Accepted

```json
{
  "id": "fchost_5d0c2b9e7a414f3c9e8b1a6d2f4c7e90",
  "offering_id": "aitronos",
  "kind": "managed",
  "name": "build-box",
  "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
  "user_id": "usr_7f3a9c2e1b8d4e6fa0c5b3d9e2f1a4c7",
  "project_group": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
  "location_id": "eu-central",
  "location_label": "Germany",
  "size_id": "std-16",
  "size_label": "16 vCPU · 64 GB",
  "state": "creating",
  "state_label": "Creating the server",
  "transient": true,
  "step": null,
  "step_started_at": null,
  "state_changed_at": "2026-09-28T09:00:00.184066Z",
  "failure": null,
  "ipv4": null,
  "ipv6": null,
  "ssh_port": 22,
  "ssh_user": "forge",
  "bootstrap_host_key_pub": null,
  "host_key_pub": null,
  "price": {"hourly": "0.83", "monthly_cap": "520.30", "currency": "CHF", "source": "aitronos", "includes_vat": false, "catalog_version": "fc-3b8e1f0a9c42", "quoted_at": "2026-09-28T09:00:00.184066Z", "parked_per_gb_month": "0.0269", "price_verified": true},
  "month_to_date": "0.00",
  "notice": null,
  "idle_reminder": null,
  "reconcile_flags": null,
  "actions": ["delete", "revoke"],
  "created_at": "2026-09-28T09:00:00.184066Z",
  "ready_at": null,
  "parked_at": null,
  "parked_expires_at": null,
  "deleted_at": null,
  "revoked_at": null,
  "revoke_reason": null,
  "last_activity_at": null
}
```

409 Price changed

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_PRICE_CHANGED",
    "message": "The price has changed since you confirmed it. Review the new price and confirm again.",
    "system_message": "The confirmed Forge compute quote no longer matches the live price",
    "type": "client_error",
    "status": 409,
    "details": {"quote": {"hourly": "0.83", "currency": "CHF", "catalog_version": "fc-3b8e1f0a9c42"}},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

409 Capacity

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_CAPACITY_UNAVAILABLE",
    "message": "This server size is not available in that location right now. Choose another size or location.",
    "system_message": "No capacity for the requested size in the requested location",
    "type": "client_error",
    "status": 409,
    "details": {
      "alternatives": [
        {"location_id": "eu-north", "size_id": "std-16", "hourly": "0.83", "currency": "CHF"},
        {"location_id": "eu-central", "size_id": "std-8", "hourly": "0.42", "currency": "CHF"},
        {"location_id": "eu-central", "size_id": "std-32", "hourly": "1.61", "currency": "CHF"}
      ]
    },
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

402 Payment Required

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_SPEND_LIMIT_REACHED",
    "message": "Your organization's spending limit does not allow another cloud server hour. Ask an admin to raise the limit.",
    "system_message": "Forge compute spend limit reached: headroom_below_one_hour",
    "type": "client_error",
    "status": 402,
    "details": {"reason": "headroom_below_one_hour"},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

402 Your limit

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_SPEND_LIMIT_REACHED",
    "message": "Your monthly limit for Aitronos servers (CHF 12.50) does not allow another server hour. Someone who manages billing can raise it on the Machines page.",
    "system_message": "Forge compute spend limit reached: member_limit_reached",
    "type": "client_error",
    "status": 402,
    "details": {"reason": "member_limit_reached"},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-10-01T09:00:00Z"
  }
}
```

422 Unprocessable Entity

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_INVALID_PUBLIC_KEY",
    "message": "The SSH public key was not accepted. Use a single ed25519, ECDSA or RSA key of at least 3072 bits.",
    "system_message": "Invalid client public key: The RSA public key has 2048 bits; at least 3072 are required.",
    "type": "validation_error",
    "status": 422,
    "details": {"field": "client_public_key", "reason": "The RSA public key has 2048 bits; at least 3072 are required."},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

403 Forbidden

```json
{
  "success": false,
  "error": {
    "code": "FORGE_COMPUTE_DISABLED",
    "message": "Cloud servers are not enabled for this organization.",
    "system_message": "Forge cloud compute is disabled for this organization",
    "type": "authorization_error",
    "status": 403,
    "details": {"feature": "forge_compute_enabled"},
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-09-28T09:00:00Z"
  }
}
```

422 Group organization

```json
{
  "success": false,
  "error": {
    "code": "FORGE_PROJECT_GROUP_ORGANIZATION_MISMATCH",
    "message": "This project is billed to Acme Engineering through its project group. Rent the server in Acme Engineering, or change the group's organization first.",
    "system_message": "Forge compute create names an organization its project group does not bill",
    "type": "validation_error",
    "status": 422,
    "details": {
      "field": "organization_id",
      "reason": "project_group_organization_mismatch",
      "client_id": "grp-clients",
      "organization_id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c"
    },
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-10-09T09:00:00Z"
  }
}
```

403 Group unavailable

```json
{
  "success": false,
  "error": {
    "code": "FORGE_PROJECT_GROUP_ORGANIZATION_UNAVAILABLE",
    "message": "This project group is billed to Client Workspace, where you can no longer use Forge. Choose another organization for the group.",
    "system_message": "Forge project group bills to an organization the caller cannot use: 'org_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d'",
    "type": "authorization_error",
    "status": 403,
    "details": {
      "client_id": "grp-old-client",
      "organization_id": "org_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d"
    },
    "trace_id": "3f1c9a52-7d4e-4b8a-9c21-6e0d5f7a8b34",
    "timestamp": "2026-10-09T09:00:00Z"
  }
}
```

## Related Resources

- [Forge cloud compute overview](/docs/api-reference/forge-compute/introduction)
- [List billing organizations](/docs/api-reference/forge-compute/list-billing-organizations)
- [Choose the default billing organization](/docs/api-reference/forge-compute/choose-billing-organization)
- [List project groups](/docs/api-reference/forge-compute/list-project-groups)
- [Register or update a project group](/docs/api-reference/forge-compute/put-project-group)
- [Delete a project group](/docs/api-reference/forge-compute/delete-project-group)
- [List compute offerings](/docs/api-reference/forge-compute/list-offerings)
- [Get offering options](/docs/api-reference/forge-compute/get-offering-options)
- [Resolve a free size](/docs/api-reference/forge-compute/resolve-offering-size)
- [List connected accounts](/docs/api-reference/forge-compute/list-credentials)
- [Connect a cloud account](/docs/api-reference/forge-compute/put-credential)
- [Disconnect a cloud account](/docs/api-reference/forge-compute/delete-credential)
- [Create a server](/docs/api-reference/forge-compute/create-host)
- [List servers](/docs/api-reference/forge-compute/list-hosts)
- [List your servers in every organization](/docs/api-reference/forge-compute/list-my-hosts)
- [Get a server](/docs/api-reference/forge-compute/get-host)
- [Get a server's daily cost and uptime](/docs/api-reference/forge-compute/get-host-usage)
- [List a server's running intervals](/docs/api-reference/forge-compute/list-host-intervals)
- [List a server's event history](/docs/api-reference/forge-compute/list-host-events)
- [Report a setup step](/docs/api-reference/forge-compute/report-progress)
- [Report the server's host key](/docs/api-reference/forge-compute/report-host-key)
- [Mark a server ready](/docs/api-reference/forge-compute/report-ready)
- [Report activity](/docs/api-reference/forge-compute/report-activity)
- [Park a server](/docs/api-reference/forge-compute/park-host)
- [Resume a server](/docs/api-reference/forge-compute/resume-host)
- [Delete a server](/docs/api-reference/forge-compute/delete-host)
- [Revoke a server](/docs/api-reference/forge-compute/revoke-host)
- [Get compute settings](/docs/api-reference/forge-compute/get-settings)
- [Update compute settings](/docs/api-reference/forge-compute/update-settings)
- [Get spend limits](/docs/api-reference/forge-compute/get-limits)
- [Change the organization's limits](/docs/api-reference/forge-compute/update-organization-limits)
- [Set your own limit](/docs/api-reference/forge-compute/update-my-limit)
- [List member limits](/docs/api-reference/forge-compute/list-member-limits)
- [Set a member's limit](/docs/api-reference/forge-compute/update-member-limit)
- [Delete a leftover resource](/docs/api-reference/forge-compute/delete-orphan)