# Billing, Balance & AI credits

A plan is bought by one workspace and can cover several of its owner's workspaces; each workspace has its own Balance. The plan decides what you can create and what is included each month, shared by the workspaces it covers; the paying workspace's Balance pays for AI and for use past it in every workspace it covers, and each workspace's Balance pays for the domains bought in it. Money your customers pay you through Payments is Earnings, held per project — it never pays Harakumo and the Balance never pays you.

## Plans

Limits & scaling lists every count and allowance. Plans limit how many things you create, and include an amount of file storage, database storage and build minutes (past it, Hobby stops and paid plans pay per unit from the Balance); bandwidth and function traffic have no plan quota yet.

Free limits are per person, across all your free workspaces. A paid plan's limits are shared across the workspaces it covers. Hobby is free: static sites, functions, databases, storage, sign-in, email and payments within its counts. Server apps are on Pro and up, videos and live channels on Pro and up, and AI on Hobby is paid from the Balance.

Enterprise is arranged with us, from $2,000 a month, and is not bought online (`POST /api/billing` and checkout answer 409 `contact_sales` with `contact_url`); workspaces already on Enterprise keep it, at the price they pay. A plan whose price is not set up yet answers 503 `price_missing` with `contact_url`: nothing is charged, and we set it up for you.

Every price is in US dollars and does not include taxes such as sales tax, VAT or GST.

|  | Hobby | Pro | Team | Scale |
| --- | --- | --- | --- | --- |
| Price (per subscription) | Free | $20 a month | $100 a month | $500 a month |
| Workspaces covered (limits shared) | Per person | Up to 3 | Up to 10 | Up to 25 |
| Usage credit | None | None | $20 a month | None |
| AI usage | Pay as you go from your balance | Pay as you go from your balance | Pay as you go from your balance | Pay as you go from your balance |
| Emails (rolling 30 days) | 100 | 2,000 | 10,000 | 100,000 |

## One plan, several workspaces

- One subscription covers several of the owner's workspaces: up to Pro 3, Team 10 and Scale 25. The workspace that buys it pays. Its owner adds another workspace they own in Billing → Workspaces, or `POST /api/billing/workspaces { workspace_id }` signed in to the dashboard, and takes one off with `DELETE /api/billing/workspaces/:id`. Both workspaces must be the caller's own; an AI connector gets 403 `dashboard_only`.
- A covered workspace is on the plan: the counts and usage of every workspace the plan covers add up against one allowance, so spreading work over more workspaces never adds to it. Team members stay per workspace.
- Use past the plan in any covered workspace is charged daily to the paying workspace's Balance, under its spending limit, after Team's $20 monthly usage credit; Billing → Workspaces shows which workspace used what (`usage` in `GET /api/billing/workspaces`).
- AI in any covered workspace is paid from the paying workspace's Balance too, under its spending limit and after any included AI the subscription keeps (Team's $20 usage credit does not pay AI); the paying workspace's `GET /api/billing/balance` splits this month's AI by workspace (`ai_usage.by_workspace`). In a covered workspace, `GET /api/billing/balance` answers with the paying workspace's balance and AI (`paid_by` names it; `own_balance_usd` is the covered workspace's own), and adding funds or changing auto-reload there goes to the paying workspace's Balance and card, for an owner of the paying workspace only (403 `payer_only` otherwise). Domains are paid from the Balance of the workspace that buys them. In a covered workspace that is its own Balance, under its own spending limit: with `own: true`, `POST /api/billing/balance` and `POST /api/billing/balance/checkout` add to it on its own card, and `PATCH /api/billing/limits` sets its own limit (`own_spend` in `GET /api/billing/limits` and `GET /api/billing/balance`), for an owner of the covered workspace. A domain refused there for a short Balance or a spending limit says so, and its `add_funds_url` or `limits_url` opens that own Balance or limit.
- A workspace taken off moves to Hobby at once (nothing is deleted), and its place stays held for 7 days. When the paying subscription ends, the workspaces it covers move to Hobby too; while it is unpaid they have Hobby limits, and they get the plan back once it is paid. Deleting the paying workspace moves them to Hobby.
- A covered workspace does not change its own plan (409 `covered_by_subscription`): the paying workspace's Billing page does. Moving to a plan that covers fewer workspaces than are on it is refused until some are taken off (409 `covers_too_many`).
- Existing subscriptions keep their plan and price: a subscription from before covers its own workspace, and a Pro owner can add up to 2 more. It also keeps what its plan included before, shared across the workspaces it covers (Pro: 100 GB of files, 10 GB of database storage, 5,000 emails a month, $10 of AI usage a month included and server apps with no hourly charge), until we move it to the plan as listed here; we email the owner first. Billing shows which a workspace has (`terms` in `GET /api/billing`).
- Use past the plan counts each workspace's build minutes and server-app awake hours only while it is covered: a workspace added during the month brings none of its earlier use, and one taken off keeps its use while it was covered in the month's total.

## Changing plan

- Only the owner changes the plan, signed in to the dashboard: Dashboard → Billing, or `POST /api/billing { plan }` from that session. A change charges or changes what the card on file pays, so an AI connector gets 403 `dashboard_only` with `dashboard_url` (Billing → Plan).
- An owner's AI connector can instead make a checkout link for a workspace without a paid plan (`POST /api/billing/checkout { plan }`): the person opens it in a browser and pays, and the plan changes once they have.
- Upgrading charges the prorated difference now; the plan changes once that payment succeeds.
- Downgrading between paid plans starts at the next renewal. Moving to Hobby ends the subscription at the end of the period; `POST /api/billing { action: "resume" }` (Keep plan) withdraws a pending cancel or downgrade.
- Nothing is deleted on a downgrade; creating more than the new plan allows is refused.
- Hobby does not include server apps, videos or live channels: new deployments of a server app, new video uploads and going live are refused there, and AI is paid from the balance.
- A missed subscription payment keeps the plan while the processor retries, with included AI paused (AI is then paid from the Balance); an unpaid subscription drops to Hobby limits until it is paid.
- If checkout says a plan's price is being updated, nothing was charged; try again later.

## Included AI usage

- Hobby, Pro, Team and Scale include no AI usage: every AI request is pay as you go from the Balance (on a paid plan, the Balance of the workspace that pays for the plan, for every workspace it covers, under that workspace's spending limit; on Hobby, the workspace's own), and on Hobby vendor models need the owner's verified email. Workspaces already on a plan that includes some keep it ($10 a month on a Pro subscription from before these plans and $100 a month on Enterprise). Team's $20 monthly usage credit pays for use past the plan, not for AI or domains, and what is not used does not carry over.
- It resets on the 1st at 00:00 UTC and does not carry over. It is used first; then the Balance pays.
- AI is priced at each model's per-token price: the model maker's list price, plus up to 5% on third-party models to cover buying that usage (edge models never carry it). `GET /api/ai/chat` lists the exact price of every model. Every answer reports its exact cost.
- Billing → Balance breaks this month's AI usage down by model: requests, tokens in and out, and spend for each, from the records the charges were made from — chat, embeddings, memory and vectors alike (`ai_usage.by_model` in `GET /api/billing/balance`). Charges recorded without a model, from before per-model recording and from agent runs, are one Unattributed row; each agent run shows its own model and cost.

## Domains

Domains are not part of any plan. Every purchase, renewal and transfer is paid from the Balance at the price shown first (or the card, when the owner asks signed in to the dashboard; AI connectors and API keys pay from the Balance), and there is no limit on how many you buy. Connecting a domain you already own is free, up to the plan's custom-domain limit.

## The Balance

- Prepaid dollars the owner loads from Dashboard → Billing → Balance: $10 to $1,000 at a time, with the card on file or through checkout (which saves the card). An owner's AI connector cannot charge the card for it; it makes a checkout link instead (`POST /api/billing/balance/checkout`), which the person opens and pays.
- It never expires and is not refundable. Deleting a workspace gives it up only after you confirm.
- It pays for every domain purchase, renewal and transfer in its workspace. On Pro, Team and Scale the paying workspace's Balance pays for AI and for use past the plan in every workspace the plan covers: file storage at $0.05 per GB a month, database storage at $1.00 per GB a month, build minutes at $0.01 per minute and server-app awake time at $0.05 per awake hour, charged daily, after Team's $20 monthly usage credit (which does not pay AI). On Hobby it pays for its own workspace's AI, and use past the plan stops at the plan's amounts instead.
- A card is charged only when the owner chose it, signed in to the dashboard: paying with the card for one purchase (`payWithCard: true`), auto-reload, or domain renewal card backup.
- Every movement — funds added, AI usage, usage past the plan, domains, refunds, plan invoices — is a transaction on the Billing page, with receipts for card charges.

## Spending limit and alerts

- Set a monthly spending limit ($1 to $100,000; 0 for none) in Billing → Limits & alerts or `PATCH /api/billing/limits { spendLimitCents }` (the owner, signed in to the dashboard; an AI connector gets 403 `dashboard_only`). It covers everything paid beyond the plan: AI beyond the included amount, domain purchases from the Balance or the card, and file storage, database storage, build minutes and server-app awake time past a paid plan. Past it, AI requests and purchases answer 402 `spend_limit_reached`; a usage charge that does not fit is left unpaid, and uploads, database writes that add data or deploys pause (402 `usage_paused`) until it is paid.
- Alerts (`alertLevels`, default 50, 80 and 100 percent) email the owner once per level per month, for the included AI amount and for the limit.
- Auto-reload charges the card a chosen amount when available AI credit drops below a threshold, at most 10 times a month. It fires only for requests from a signed-in person unless the owner sets `autoReloadForKeys: true`.
- In a workspace another workspace's plan covers, AI and use past the plan run under the paying workspace's limit, alerts and auto-reload: `GET /api/billing/limits` there shows them (with `paid_by`), and `PATCH` sets them, for an owner of the paying workspace only (403 `payer_only` otherwise). Domains bought in it stay under its own.
- That own limit is shown as `own_spend` and set with `PATCH /api/billing/limits { spendLimitCents, own: true }` (Billing → Limits & alerts, own spending limit), by an owner of the covered workspace, signed in to the dashboard.

**curl (owner session)**

```bash
PATCH /api/billing/limits
{ "spendLimitCents": 5000, "alertLevels": [50, 80, 100], "autoReloadForKeys": false }
```

## What needs the dashboard

Anything that charges the card on file or decides what it is charged needs the owner signed in to the dashboard. An owner's AI connector with read and write access gets these answers instead (a read-only one makes none of these changes either); the `dashboard_only` and `card_requires_owner` ones carry `dashboard_url`, the page to do it on:

- What works from an AI connector instead: paying from the Balance (domains, AI usage), and links the person opens and pays in a browser: `POST /api/billing/checkout { plan }` for a workspace without a paid plan, and `POST /api/billing/balance/checkout { cents }` to add funds. Both are the owner's.
- API keys never make billing changes. A full workspace key acts as a developer: billing changes answer it 403 for its role, and the domain card options `card_requires_owner`; a read key is told it is read-only, and a project key that it works on one project. An admin hears that their role does not allow a billing change, at a browser or through an AI connector, read-only or not.

| Call | The owner's AI connector gets |
| --- | --- |
| `POST /api/billing`: change, cancel or resume a paid plan | 403 `dashboard_only`, Billing → Plan |
| `POST /api/billing/portal`: invoices, the card, cancelling | 403 `dashboard_only`, Billing |
| `PATCH /api/billing/limits`: the spending limit, alerts, `autoReloadForKeys` | 403 `dashboard_only`, Billing → Limits & alerts |
| `POST /api/billing/balance`: add funds with the card on file | 403 `dashboard_only`, Billing → Balance |
| `PATCH /api/billing/balance`: switch auto-reload on (switching it off works) | 403 `dashboard_only`, Billing → Balance |
| `POST /api/billing/workspaces` or `DELETE /api/billing/workspaces/:id`: which workspaces a plan covers | 403 `dashboard_only`, Billing → Workspaces |
| `POST` or `DELETE /api/billing/payment-methods`: add or remove a card | 403 `payouts_require_owner` |
| `payWithCard`, `autoRenewCard` or `cardBackup` on a domain | `card_requires_owner` (see Domains), the Domains page |

## Seller earnings

Payments you take are Earnings on the project: each sale less the 3.9% + 30¢ fee, held 7 days, then withdrawn by the workspace owner. See Payments.

## When things reset

| What | Clock |
| --- | --- |
| Included AI usage | The 1st of each month, 00:00 UTC |
| Build minutes | The 1st of each month, 00:00 UTC |
| Server-app awake time and the usage credit | The 1st of each month, 00:00 UTC |
| Spending limit, alerts, auto-reload count | Calendar month (UTC) |
| Email quota | Rolling 30 days |
| Subscription | Monthly from the day you subscribed |
| Domain renewals | Each domain's own expiry date |
| Earnings hold | 7 days after each payment |

## Who can see and change billing

- Admins and owners can see billing; only the owner can change the plan, cards, Balance, auto-reload and limits, and the changes that charge the card or decide what it is charged need the owner signed in to the dashboard (What needs the dashboard).
- API keys see the AI credit summary in `GET /api/usage` (`aiCredits`) and cannot read or change billing. An owner's AI connector can read the Balance.

## Reference

**SDK**

```js
const { aiCredits } = await hk.usage.get();
// { balance_usd, available_usd, included_usd, included_used_usd, included_remaining_usd, resets_on, buy_url, auto_reload }
// Billing changes are made by the owner in the dashboard (an API key acts as developer).
```

**CLI**

```bash
harakumo balance      # Balance, included AI this month, what is available
harakumo usage
```

**REST**

```http
GET   /api/usage                       → aiCredits { balance_usd, available_usd, included_usd, included_remaining_usd, resets_on, buy_url }
GET   /api/billing                     # plan, subscription state, limits and usage (admin+)
POST  /api/billing                     { "plan": "hobby"|"pro"|"team"|"scale" } | { "action": "resume" }   (owner, dashboard)
POST  /api/billing/checkout            { "plan": "pro"|"team"|"scale" }   → { url }   (owner; from an AI connector, only without a paid plan)
GET   /api/billing/workspaces          # the workspaces this plan covers, places left, which workspace used what (admin+)
POST  /api/billing/workspaces          { "workspace_id": 12 }   (owner of both, dashboard)
DELETE /api/billing/workspaces/:id     # take one off: it moves to Hobby (owner, dashboard)
POST  /api/billing/portal              → { url }   (owner, dashboard)
GET   /api/billing/balance             # balance, credits, transactions, this month's AI usage by model (admin+)
POST  /api/billing/balance             { "cents": 2500 }   Idempotency-Key: <unique>   (owner, dashboard; card on file)
POST  /api/billing/balance/checkout    { "cents": 2500 }   → { url }
PATCH /api/billing/balance             { "autoReloadCents": 1000, "autoReloadBelowCents": 200 }
GET   /api/billing/limits · PATCH { "spendLimitCents"?, "alertLevels"?, "autoReloadForKeys"? }   (PATCH: owner, dashboard)
```
