# List project groups

Lists every Forge project group you registered, each with the organization its Forge spend is billed to, and the organizations a group may be billed to. A project group is a folder of projects in the Forge sidebar. Forge keeps its groups on the person's machine and registers each one with [Register or update a project group](/docs/api-reference/forge-compute/put-project-group), keyed by its own id (`client_id`), so the group can carry an organization that pays for the Forge spend made inside its projects: [rented servers](/docs/api-reference/forge-compute/create-host) and the [git impact assessment](/assets/assess-git-impact.a7bae1761a3dd82a227de8c76df41608e7e238562f3d2f420b7b3eccb4ee1234.23c4b6e8.md). That spend is shown under the group on the organization's [usage report](/assets/get-usage-detail-report.45870ea5b94806d0570403fa53ae031e4b48417dddf0f27bd3aa2fc29b7ba55c.49b960d1.md) (`by_forge_project_group`). Every label and sentence in the answer is written by the backend; show them as they are.

**Which organization a group bills to.** It is resolved on every read, never stored, so changing one group's organization changes every group that follows it at once.

- A group with an organization of its own (`own_organization`) bills there.
- A group without one follows its parent: it bills to its nearest registered ancestor's organization. `inherited` is then `true` and `inherited_from` names that ancestor.
- When no group on the chain has an organization, `organization` is `null` and the group is "Not billed to an organization": Forge spend inside it is billed where it would have been without a group, and is still shown under the group.
- The chain is followed through registered groups only: a parent that is not registered (or was deleted) ends it. **Register every group, also those without an organization of their own**, so the groups inside them can inherit through them.


**When the organization can no longer be billed.** `reason` is set when Forge spend can no longer be billed to the group's organization: you left it, lost `use_forge` there, or the credential is not granted it. While it is set, billable work inside the group (renting a server, the git impact assessment) is refused with `403 FORGE_PROJECT_GROUP_ORGANIZATION_UNAVAILABLE`, never billed somewhere else. Choose another organization for the group, or for the ancestor it inherits from.

**The Bill to choice.** `organizations` lists every organization you are an active member of. One is `selectable` when you hold the `use_forge` capability there. This is deliberately looser than the [server billing choice](/docs/api-reference/forge-compute/list-billing-organizations): a group also carries spend that is not a server (Forge's AI features). Renting a server inside the group still needs cloud servers available in that organization; that is checked, and explained, when you rent.

Groups are personal: nobody else can read, rename, delete or bill yours. It names no organization (it is about you, across all of yours) and requires a credential that acts for a person (a bearer token, or a key belonging to a person). A credential confined to some organizations is shown those alone.

## Returns

**`title`** string — the label of the group's **Bill to** choice: `Bill to`.

**`help`** string — the sentence explaining it: `Forge spend inside this group's projects is billed to this organization: rented servers and Forge's AI features. Groups inside it follow it unless they choose their own.`

**`unassigned_label`** string — the sentence for a group billed to no organization: `Not billed to an organization`.

**`organizations`** array — every organization you are an active member of, for the group's **Bill to** choice, in `order`. Each entry:

- **`id`** string — the organization's id. Send it as `organization_id` when registering a group.
- **`name`** string — the organization's name.
- **`logo_url`** string or `null` — the organization's logo, as a public URL.
- **`selectable`** boolean — whether a group may be billed to it: you hold `use_forge` there.
- **`reason`** string or `null` — why it cannot be chosen, as a sentence to show (`You don't have permission to use Forge in this organization.`); `null` when `selectable`.
- **`order`** integer — display position from 0: selectable organizations first, then by name.


**`groups`** array — every registered group, oldest first. Deleted groups are left out. Each group:

- **`id`** string — the group's id (`fpgrp_` followed by 32 hex characters).
- **`client_id`** string — Forge's own id for the group, as registered.
- **`name`** string — the group's name.
- **`parent_id`** string or `null` — the parent group's `id`; `null` at the top, and while the parent is not registered.
- **`parent_client_id`** string or `null` — the parent group's Forge id, as last sent (also when that parent is not registered).
- **`organization`** object or `null` — the organization Forge spend inside the group is billed to now: its own, else its nearest registered ancestor's. **`id`** string, and **`name`** string or `null` (`null` when it cannot be read). `null` when no group on the chain has one.
- **`own_organization`** object or `null` — the organization chosen for this group itself (`{id, name}`); `null` when it follows its parent.
- **`inherited`** boolean — `true` when `organization` comes from an ancestor.
- **`inherited_from`** object or `null` — that ancestor when `inherited`: **`id`**, **`client_id`** and **`name`**, all strings.
- **`billing_label`** string — the sentence to show, e.g. `Billed to Aitronos AG` (its own organization), `Billed to Aitronos AG, from Clients` (inherited from the group named Clients) or `Not billed to an organization`. When the organization's name cannot be read it still says the group is billed: `Billed to an organization whose name cannot be shown`.
- **`reason`** string or `null` — why Forge spend can no longer be billed to `organization`, as a sentence to show: `You don't have permission to use Forge in this organization.`, `You are not a member of this organization.` or `This key cannot be used in this organization.`; `null` when it can, and when the group bills to no organization.
- **`month_to_date_label`** string or `null` — what you spent inside the group this calendar month (UTC), across every organization you are or were a member of, e.g. `CHF 12.40 this month`; `CHF 0.00 this month` when nothing was spent. A group whose organization changed, or that bills to an organization you have since left, keeps what it spent before. With an API key limited to some organizations it is `null` for a group whose spend lies outside them. `null` when the spend cannot be read right now (never `CHF 0.00` in its place).
- **`created_at`**, **`updated_at`** string or `null` — when the group was registered and when it last changed (ISO 8601, UTC).



```json
{
  "title": "Bill to",
  "help": "Forge spend inside this group's projects is billed to this organization: rented servers and Forge's AI features. Groups inside it follow it unless they choose their own.",
  "unassigned_label": "Not billed to an organization",
  "organizations": [
    {
      "id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",
      "name": "Acme Engineering",
      "logo_url": "https://cdn.example.com/logos/acme.png",
      "selectable": true,
      "reason": null,
      "order": 0
    },
    {
      "id": "org_8f2d4b6a1c3e4f5a8b7c9d0e1f2a3b4c",
      "name": "Side Project",
      "logo_url": null,
      "selectable": true,
      "reason": null,
      "order": 1
    },
    {
      "id": "org_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d",
      "name": "Client Workspace",
      "logo_url": null,
      "selectable": false,
      "reason": "You don't have permission to use Forge in this organization.",
      "order": 2
    }
  ],
  "groups": [
    {
      "id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c",
      "client_id": "grp-clients",
      "name": "Clients",
      "parent_id": null,
      "parent_client_id": null,
      "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "own_organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "inherited": false,
      "inherited_from": null,
      "billing_label": "Billed to Acme Engineering",
      "reason": null,
      "month_to_date_label": "CHF 12.40 this month",
      "created_at": "2026-10-09T08:12:03.418227Z",
      "updated_at": "2026-10-09T08:12:03.418227Z"
    },
    {
      "id": "fpgrp_9d3a6e1c5b7f4a2e8c0d4b6f1a3e5c7d",
      "client_id": "grp-acme-shop",
      "name": "Acme Shop",
      "parent_id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c",
      "parent_client_id": "grp-clients",
      "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "own_organization": null,
      "inherited": true,
      "inherited_from": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
      "billing_label": "Billed to Acme Engineering, from Clients",
      "reason": null,
      "month_to_date_label": "CHF 3.10 this month",
      "created_at": "2026-10-09T08:12:04.902114Z",
      "updated_at": "2026-10-09T08:12:04.902114Z"
    },
    {
      "id": "fpgrp_2f8c1a5e9d3b4c7a6e0f2d4b8a1c3e5f",
      "client_id": "grp-side-work",
      "name": "Side work",
      "parent_id": null,
      "parent_client_id": null,
      "organization": null,
      "own_organization": null,
      "inherited": false,
      "inherited_from": null,
      "billing_label": "Not billed to an organization",
      "reason": null,
      "month_to_date_label": "CHF 0.00 this month",
      "created_at": "2026-10-09T08:12:05.117390Z",
      "updated_at": "2026-10-09T08:12:05.117390Z"
    },
    {
      "id": "fpgrp_7a1e3c5b9d2f4e6a8c0b1d3f5a7e9c2b",
      "client_id": "grp-old-client",
      "name": "Old client",
      "parent_id": null,
      "parent_client_id": null,
      "organization": {"id": "org_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d", "name": "Client Workspace"},
      "own_organization": {"id": "org_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d", "name": "Client Workspace"},
      "inherited": false,
      "inherited_from": null,
      "billing_label": "Billed to Client Workspace",
      "reason": "You don't have permission to use Forge in this organization.",
      "month_to_date_label": "CHF 0.00 this month",
      "created_at": "2026-10-09T08:12:05.664021Z",
      "updated_at": "2026-10-09T08:12:05.664021Z"
    }
  ]
}
```

## Errors

| Status | Code | When |
|  --- | --- | --- |
| 401 | `AUTHENTICATION_REQUIRED` | No valid credential. |
| 403 | `API_KEY_PERSON_REQUIRED` | An organization API key: it has no person of its own. |



```bash cURL
curl "https://api.aitronos.com/v1/forge/project-groups" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```


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

ACCESS_TOKEN = "your-access-token"

listing = httpx.get(
    "https://api.aitronos.com/v1/forge/project-groups",
    headers={"Authorization": f"Bearer {ACCESS_TOKEN}"},
).json()
for group in listing["groups"]:
    print(group["name"], "-", group["billing_label"], "-", group["month_to_date_label"])
    if group["reason"]:
        print("  cannot be billed:", group["reason"])
```


```python Python
import os
import requests

token = os.environ["AITRONOS_TOKEN"]
response = requests.get(
    "https://api.aitronos.com/v1/forge/project-groups",
    headers={"Authorization": f"Bearer {token}"},
)
body = response.json()
choices = [o["name"] for o in body["organizations"] if o["selectable"]]
print(body["title"], "->", choices)
```


```javascript JavaScript
const response = await fetch("https://api.aitronos.com/v1/forge/project-groups", {
  headers: { Authorization: `Bearer ${process.env.AITRONOS_TOKEN}` },
});
const { groups } = await response.json();
console.log(groups.map((g) => `${g.name}: ${g.billing_label}${g.reason ? ` (${g.reason})` : ""}`));
```

**Response:**

200 OK

```json
{
  "title": "Bill to",
  "help": "Forge spend inside this group's projects is billed to this organization: rented servers and Forge's AI features. Groups inside it follow it unless they choose their own.",
  "unassigned_label": "Not billed to an organization",
  "organizations": [
    {
      "id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c",
      "name": "Acme Engineering",
      "logo_url": "https://cdn.example.com/logos/acme.png",
      "selectable": true,
      "reason": null,
      "order": 0
    }
  ],
  "groups": [
    {
      "id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c",
      "client_id": "grp-clients",
      "name": "Clients",
      "parent_id": null,
      "parent_client_id": null,
      "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "own_organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "inherited": false,
      "inherited_from": null,
      "billing_label": "Billed to Acme Engineering",
      "reason": null,
      "month_to_date_label": "CHF 12.40 this month",
      "created_at": "2026-10-09T08:12:03.418227Z",
      "updated_at": "2026-10-09T08:12:03.418227Z"
    },
    {
      "id": "fpgrp_9d3a6e1c5b7f4a2e8c0d4b6f1a3e5c7d",
      "client_id": "grp-acme-shop",
      "name": "Acme Shop",
      "parent_id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c",
      "parent_client_id": "grp-clients",
      "organization": {"id": "org_3c1e9a7b5d2f4e8a9b0c6d1e2f3a4b5c", "name": "Acme Engineering"},
      "own_organization": null,
      "inherited": true,
      "inherited_from": {"id": "fpgrp_4b9e2c7a1d3f4e8a9c0b6d2e1f3a5b7c", "client_id": "grp-clients", "name": "Clients"},
      "billing_label": "Billed to Acme Engineering, from Clients",
      "reason": null,
      "month_to_date_label": "CHF 3.10 this month",
      "created_at": "2026-10-09T08:12:04.902114Z",
      "updated_at": "2026-10-09T08:12:04.902114Z"
    }
  ]
}
```

403 Forbidden

```json
{
  "success": false,
  "error": {
    "code": "API_KEY_PERSON_REQUIRED",
    "message": "This API key acts as the organization, not as a person, and this operation needs a person.",
    "system_message": "This API key acts as the organization, not as a person, and this operation needs a person.",
    "type": "authorization_error",
    "status": 403,
    "details": {"reason": "api_key_person_required", "acts_as": "organization", "hint": "Use a key that acts as a person, or a signed-in user's access token."},
    "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)
- [Assess a working tree's impact](/assets/assess-git-impact.a7bae1761a3dd82a227de8c76df41608e7e238562f3d2f420b7b3eccb4ee1234.23c4b6e8.md)
- [Get usage detail report](/assets/get-usage-detail-report.45870ea5b94806d0570403fa53ae031e4b48417dddf0f27bd3aa2fc29b7ba55c.49b960d1.md)