# Billing accounts

Billing settings and credit, shared by the organizations that belong to the billing account

Base URL: `https://api.cv-transformer.com/v1`. Endpoints: `GET /billing_accounts`, `PATCH /billing_accounts`. Authenticate with the header `Authorization: Bearer YOUR_API_KEY` (see [authentication](https://www.cv-transformer.com/en-GB/api-reference/authentication.md)).

## The billing account object

| Attribute | Type | Description |
| --- | --- | --- |
| `id` | `uuid` | Unique identifier. Read-only. |
| `paddle_subscription_id` | `text \| null` | Identifier of the subscription in Paddle. Read-only. |
| `created_at` | `timestamp with time zone` | Creation timestamp. Read-only. |
| `updated_at` | `timestamp with time zone` | Last modification timestamp. |
| `allow_pre_paid` | `boolean` | Whether the billing account can buy credits up front, for a pre-paid subscription. Read-only. |
| `credit` | `integer` | Number of credits currently available. Read-only. |
| `currency` | `CurrencyCode` | Currency in which the billing account is billed. |
| `maximum_usage` | `integer` | Number of credits a subscription can use beyond its credit. `credit` goes down to minus this number. Read-only. |
| `minimum_guarantee` | `integer` | Minimum number of credits billed per month. Read-only. |
| `next_billed_at` | `timestamp with time zone \| null` | Next billing timestamp. Read-only. |
| `overage_billed_for` | `timestamp with time zone \| null` | Renewal date, read from Paddle, of the last period whose overage was billed, so overage is charged once per period. Read-only. |
| `prev_usage` | `integer` | Number of credits used in the 7 days before the last 7 days. Read-only. |
| `price_per_credit` | `integer` | Agreed price per credit. Read-only. |
| `price_per_user` | `integer` | Agreed price per user license. Read-only. |
| `pricing_version` | `PricingVersion` | Pricing version of the billing account. Read-only. |
| `recent_usage` | `integer` | Number of credits used in the last 7 days. Read-only. |
| `subscription_type` | `SubscriptionType` | Type of the active subscription. Read-only. |
| `trial_expires_at` | `timestamp with time zone \| null` | Trial expiration timestamp. Read-only. |
| `user_licenses` | `integer \| null` | Maximum number of users with the `edit_candidates` permission in the billing account. Only limits subscriptions; null means no limit. Read-only. |

```json
{
  "id": "00000000-0000-0000-0000-000000000000",
  "paddle_subscription_id": "sub_01h8bx3z9k7mq2w4e6r8t0y2u4",
  "created_at": "2026-01-01T12:00:00+00:00",
  "updated_at": "2026-01-01T12:00:00+00:00",
  "allow_pre_paid": false,
  "credit": 0,
  "currency": "USD",
  "maximum_usage": 0,
  "minimum_guarantee": 0,
  "overage_billed_for": "",
  "prev_usage": 0,
  "price_per_credit": 0,
  "price_per_user": 0,
  "pricing_version": "v3",
  "recent_usage": 0,
  "subscription_type": "subscription",
  "trial_expires_at": null,
  "user_licenses": 0
}
```

### Types

```typescript
type SubscriptionType = "pre-paid" | "subscription" | "trial";

type PricingVersion = "v1" | "v2" | "v3";

type CurrencyCode = 
  | "USD"
  | "EUR"
  | "GBP"
  | "JPY"
  | "AUD"
  | "CAD"
  | "CHF"
  | "CLP"
  | "HKD"
  | "SGD"
  | "SEK"
  | "ARS"
  | "BRL"
  | "CNY"
  | "COP"
  | "CZK"
  | "DKK"
  | "HUF"
  | "ILS"
  | "INR"
  | "KRW"
  | "MXN"
  | "NOK"
  | "NZD"
  | "PEN"
  | "PLN"
  | "RUB"
  | "THB"
  | "TRY"
  | "TWD"
  | "UAH"
  | "VND"
  | "ZAR";
```

### Related resources

Embed related resources with the [`select` parameter](https://www.cv-transformer.com/en-GB/api-reference/selecting.md), for example `select=*,credit_mutations(*)`. Resources related through more than one column need the column as a hint, like `table!column(*)`.

| Embed | Type | Description |
| --- | --- | --- |
| `credit_mutations(*)` | `array` | The [credit mutations](https://www.cv-transformer.com/en-GB/api-reference/credit_mutations.md) referencing this billing account through `credit_mutations.billing_account_id`. |
| `organizations!billing_account_id(*)` | `array` | The [organizations](https://www.cv-transformer.com/en-GB/api-reference/organizations.md) referencing this billing account through `organizations.billing_account_id`. |

## List billing accounts

`GET /v1/billing_accounts` · requires the `organization:read` scope

Filter on any attribute with `column=operator.value` (see [filtering](https://www.cv-transformer.com/en-GB/api-reference/filtering.md)). Choose columns and embed related resources with `select` (see [selecting](https://www.cv-transformer.com/en-GB/api-reference/selecting.md)), and sort and paginate with `order`, `limit` and `offset` (see [sorting and pagination](https://www.cv-transformer.com/en-GB/api-reference/sorting-pagination.md)).

```bash
curl "https://api.cv-transformer.com/v1/billing_accounts?limit=10&select=*" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Responses:

- `200`: A list of billing accounts with the selected columns. The `Content-Range` header holds the range returned and the total count, like `0-9/42`.
- `206`: Partial Content
- `400`: The request is malformed, for example an unknown column or an invalid filter.
- `401`: The API key is missing or invalid.
- `403`: The API key doesn't have the scope this request needs.
- `429`: The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the `Retry-After` header.

## Update billing accounts

`PATCH /v1/billing_accounts` · requires the `organization:write` scope

Filter on any attribute with `column=operator.value` (see [filtering](https://www.cv-transformer.com/en-GB/api-reference/filtering.md)). Without filters, this request updates all billing accounts the API key has access to. Always filter on at least one column, like `id=eq.{id}`. The body holds the attributes to change.

```bash
curl -X PATCH "https://api.cv-transformer.com/v1/billing_accounts?id=eq.00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "currency": "USD" }'
```

Responses:

- `204`: Updated. With the header `Prefer: return=representation`, the response is a `200` whose body holds the updated billing accounts with the selected columns.
- `400`: The request is malformed, for example an unknown column, an invalid filter or an invalid body.
- `401`: The API key is missing or invalid.
- `403`: The API key doesn't have the scope this request needs, or no permission for this change, for example when writing rows of another organization.
- `409`: The change conflicts with existing data, for example a duplicate key or a reference to a row that does not exist.
- `429`: The API key made more requests per minute than its rate limit allows. Retry after the number of seconds in the `Retry-After` header.

Errors have a JSON body with a `message`, `details` and `hint`, and for database errors a `code`. See the [introduction](https://www.cv-transformer.com/en-GB/api-reference.md) for more on errors. The full API is described by the OpenAPI spec at https://api.cv-transformer.com/v1/openapi.json.
