# Billing

**Billing** is your Workspace's own hlix plan — what you pay us. These operations read the current plan, its meters and its order history, open a checkout, and open the billing portal. It is not [Client billing](/api/reference/client-billing/), which is what you invoice your own customer for delivered work; the two are different money and never meet.

Generated from contract version `1.0.0` — the same document [`/v1/api/openapi.json`](/api/openapi/) serves.

## Prerequisites

- An API key in `x-api-key`, or a browser session cookie
- `X-Organization-Id` naming the workspace to act in, unless the session already has an active one
- The base URL for your deployment, `https://server.hlix.ai` by default

## Operations

| Method | Path | Operation |
| --- | --- | --- |
| `GET` | `/v1/api/billing` | [Read the workspace's plan, meters, orders and entitlement](#read-the-workspaces-plan-meters-orders-and-entitlement) |
| `POST` | `/v1/api/billing/checkout` | [Open a hlix billing checkout billed to the workspace](#open-a-hlix-billing-checkout-billed-to-the-workspace) |
| `POST` | `/v1/api/billing/portal` | [Open the billing portal for the workspace](#open-the-billing-portal-for-the-workspace) |

## Read the workspace's plan, meters, orders and entitlement

`GET /v1/api/billing` · operation ID `getOrgBilling`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | OrgBillingState | The live billing state read by organization id, plus the ENTITLEMENT verdict. `configured: false` is a confirmed absence of a provider on this deployment; `entitlement.kind` distinguishes an override, a real subscription, the free tier, an unconfigured deployment, and a lookup that failed — a client must not collapse the last two into 'no subscription'. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Billing is agency-only — an external `client` collaborator may not read the agency's plan or invoices. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |
| `502` | ApiError | The billing provider did not answer. The workspace's plan is unknown, not absent. |

## Open a hlix billing checkout billed to the workspace

`POST /v1/api/billing/checkout` · operation ID `createOrgBillingCheckout`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Request body** — `application/json`, `BillingCheckout` (required)

| Property | Type | Required | Notes |
| --- | --- | --- | --- |
| `plan` | `free` | `basic` | `pro` | `ultra` | **yes** |  |
| `successUrl` | string (uri) | no |  |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | BillingCheckoutSession | A hlix billing checkout URL bound to the ORGANIZATION as external customer. `plan: "free"` opens the €0 Hlix-Free product, which is how a workspace puts a card on file and converts its monthly credit ceiling into pay-as-you-go. |
| `400` | ValidationError \| ApiError | The JSON body failed schema validation (`ValidationError`), the request named no active organization, or no billing product is configured for the requested plan on this deployment (`ApiError`). |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only workspace owners and admins may open a checkout or a customer portal. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |
| `409` | ApiError | The workspace's own state blocks the checkout — it has no member to bill, or the owner's email is already the billing contact for another workspace and no per-workspace alias can be formed. Not retryable; the message names the change that would fix it. |
| `502` | ApiError | The billing provider did not answer. The workspace's plan is unknown, not absent. |
| `503` | ApiError | Billing is not configured for this deployment. |

## Open the billing portal for the workspace

`POST /v1/api/billing/portal` · operation ID `createOrgBillingPortal`

**Parameters**

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `X-Organization-Id` | header | no | string | The workspace (organization) to act in. Omitted, the session's active organization is used. |

**Responses**

| Status | Body | Description |
| --- | --- | --- |
| `200` | BillingPortalSession | A billing portal URL for the WORKSPACE's customer, where the plan can be changed or cancelled and past invoices read. |
| `400` | ApiError | The request named no active organization. |
| `401` | ApiError | No valid session or API key. |
| `403` | ApiError | Only workspace owners and admins may open a checkout or a customer portal. |
| `404` | ApiError | The resource does not exist, or the caller is a task-scoped credential and this endpoint is outside its allowlist. |
| `409` | ApiError | The workspace has no member to bill, or its billing email is unusable. Not retryable. |
| `502` | ApiError | The billing provider did not answer. The workspace's plan is unknown, not absent. |
| `503` | ApiError | Billing is not configured for this deployment. |

## If a request fails

These apply to every operation on this page.

- `400` — the body failed schema validation, or the request named no active organization. A `ValidationError` body carries the failing fields; an `ApiError` body carries only `error`.
- `401` — no valid session or API key.
- `403` — authenticated, but not a member of the named organization, or a client collaborator without the required access.
- `404` — no such resource **in this workspace**. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
- `409` — the expected revision or state is stale, or another operation currently owns the transition.
- `500` — the operation failed server-side. Retry only where an idempotency key makes that safe.

## Next steps

[API reference](/api/reference/)
  [API & OpenAPI](/api/openapi/)
  [TypeScript SDK](/sdk/typescript/)
  [CLI reference](/reference/cli/)