---
title: "Read the monthly plan (null when none), the tiers on offer, the topped-up balance, whether a new plan can be started, the cheapest path for the recent spend and the last period's usage"
method: GET
path: "/v1/subscription"
---

# Read the monthly plan (null when none), the tiers on offer, the topped-up balance, whether a new plan can be started, the cheapest path for the recent spend and the last period's usage

`GET /v1/subscription`

## Request

- Base URL: `https://volai.cz`
- URL: `https://volai.cz/v1/subscription`
- Auth: HTTP bearer

The account's monthly plan and everything needed to offer one. `subscription` is `null` when the account never had a plan; a plan that has ended is still returned, with `status: "canceled"`. `tiers` lists the tiers on offer with their `priceHal` and `creditHal` (hellers, excluding VAT). `topupBalanceHal` is the topped-up credit; `GET /v1/balance` carries the same two blocks next to the total. `available` says whether this account can start a NEW plan right now - an existing plan is always returned and keeps working when it is `false`. `recommendation` is the cheapest way to pay for what the account actually spent in the last 30 days (the same calculation as the calculator on the website): `spendHal`, `cheapestPath` (`per_second` or `plan`), the cheapest tier with top-ups `tier` and its cost `tierTotalHal`, the saving `savingsHal`, `worthIt`, whether the saving is big enough, `steady`, whether the spend is ongoing rather than a one-off peak (usage over the last 14 days scaled to 30 days, plus monthly number fees, reaches at least the price of the recommended tier; the portal offers the plan only when `worthIt` and `steady` are both true), and `options`, every way to pay for the same spend (per second and each tier with top-ups; the same figures the portal shows when changing the plan level). It is `null` when the plan is not offered to the account or the credit history does not reach 30 days back (a new account). `previousPeriod` summarizes the paid period before the current one (`subscription.periodStart`), with the same figures as the renewal e-mail: the `tier`, `periodStart` and `periodEnd` (ISO 8601), its monthly credit `creditHal`, how much of it was used `usedHal` and `usedPercent` (rounded down), spending beyond the monthly credit `overHal` (with top-ups without debt that the next credit paid off, with the cap including debt; `null` when the credit history cannot prove it), what expired `expiredHal`, `exhaustionMode` and `exhaustedAt`, when the monthly credit ran out (`null` when it did not, or when the credit history cannot show when). It is returned only while the plan is active, whatever `available` says; it is `null` without a plan, with status `past_due` or `canceled`, in the first period, when the credit history could not prove the usage, and 45 days after the renewal that saved it.

## Response `200`

Monthly plan state

- object
  - `subscription` object, nullable, required: The account's monthly plan, or null when it never had one. A plan that has ended is still returned, with status canceled.
    - `tier` '490' | '990' | '1990', required: Tier that is paid for the current period.
    - `status` 'active' | 'past_due' | 'canceled', required: active: the current period is paid. past_due: the last renewal payment failed and retries continue (monthly credit is 0 until it is paid; pay by hand with POST /v1/subscription/pay). canceled: the plan has ended.
    - `periodStart` string, required: Start of the paid period as an ISO 8601 string in UTC. Unlike the *At fields elsewhere in the API, which are Unix milliseconds, this is a string.
    - `periodEnd` string, required: End of the paid period as an ISO 8601 string in UTC: when the saved card is charged for the next one, unless the plan is canceled.
    - `monthlyCreditHal` number, required: Monthly credit of the paid tier, in hellers.
    - `monthlyRemainingHal` number, required: What is left of the monthly credit in this period, in hellers. It is spent first and what remains expires at the end of the period.
    - `exhaustionMode` 'topup' | 'cap', required: What happens once the monthly credit is used up. topup: credit is bought with the saved card (the account's auto top-up). cap: nothing more is bought; outbound actions fail with subscription_cap_reached until the next renewal.
    - `cancelAtPeriodEnd` boolean, required: true when the plan is canceled and ends at periodEnd without another charge. Until then the monthly credit stays usable.
    - `nextTier` '490' | '990' | '1990', nullable, required: Tier that takes effect from the next period, or null when the tier does not change.
    - `card` object, required: The saved card that renewals are charged to. Only the brand and the last four digits are ever returned.
      - `brand` string, nullable, required: Card brand, for example visa, or null when unknown.
      - `last4` string, nullable, required: Last four digits of the saved card, or null when unknown.
  - `tiers` object[], required: The tiers on offer, cheapest first, with price and monthly credit.
    - `id` '490' | '990' | '1990', required: Tier id: the monthly price in CZK excluding VAT, written as a string.
    - `priceHal` number, required: Price per month in hellers (hundredths of a koruna), excluding VAT.
    - `creditHal` number, required: Monthly credit the tier adds, in hellers. It is spent before topped-up credit and expires at the end of the period.
  - `topupBalanceHal` number, required: The topped-up credit in hellers (same as topupBalanceHal in GET /v1/balance). Negative when the account owes.
  - `available` boolean, required: Whether this account can start a NEW plan right now. An existing plan is always returned and keeps working when this is false.
  - `recommendation` object, nullable, required: The cheapest way to pay for what the account actually spent in the last 30 days (same calculation as the calculator on volai.cz). null when the plan is not offered to the account (available is false) or the credit history does not reach 30 days back.
    - `spendHal` number, required: What the account spent in the last 30 days on calls, the agent, SMS and number fees, in hellers excluding VAT. Actual spend, not extrapolated; one-off charges are left out.
    - `days` number, required: Length of the spend window in days.
    - `cheapestPath` 'per_second' | 'plan', required: The cheaper way to pay for that spend: per_second (prepaid credit, no plan) or plan (the tier below, topping up from the saved card once its monthly credit runs out). A tie goes to per_second.
    - `tier` '490' | '990' | '1990', required: The tier that would have cost least for that spend, with top-ups. Compare it with subscription.tier on an account that already has a plan.
    - `tierTotalHal` number, required: What that tier would have cost for that spend: its price plus top-ups, in hellers excluding VAT.
    - `savingsHal` number, required: How much less the plan would have cost than paying per second, in hellers excluding VAT; 0 when per_second is cheaper.
    - `worthIt` boolean, required: Whether the saving is big enough for volai to suggest the plan: at least 50 CZK and 5% of the spend. The portal offers the plan only when this and steady are both true.
    - `steady` boolean, required: Whether the spend is ongoing rather than a one-off peak: usage over the last 14 Prague days scaled to 30 days, plus the monthly number fees of the 30-day window counted once, reaches at least the price of the recommended tier. The portal and the MCP sentence offer the plan only when worthIt and steady are both true.
    - `options` object[], required: Every way to pay for the same spend: paying per second and each tier with top-ups. The same figures the portal shows when changing the plan level. For an account that already has a plan, compare them with what the current plan costs.
      - `path` 'per_second' | 'plan', required
      - `tier` '490' | '990' | '1990', nullable, required: The tier for path plan; null for per_second.
      - `totalHal` number, required: What that path would have cost for the same spend, in hellers excluding VAT (a plan with top-ups from the saved card).
  - `previousPeriod` object, nullable, required: Summary of the paid period before the current one (subscription.periodStart), with the same figures as the renewal e-mail and the plan card in the portal. Returned only while the plan is active, whatever available says: null without a plan, with status past_due or canceled, in the first period, when the credit history could not prove the usage, and 45 days after the renewal that saved it.
    - `tier` '490' | '990' | '1990', required: Tier that was paid for that period.
    - `periodStart` string, required: Start of that period as an ISO 8601 string in UTC.
    - `periodEnd` string, required: End of that period as an ISO 8601 string in UTC.
    - `creditHal` number, required: Monthly credit of that period, in hellers excluding VAT.
    - `usedHal` number, required: How much of that monthly credit was used, in hellers (0 up to creditHal).
    - `usedPercent` number, required: usedHal as a share of creditHal, in percent rounded down (the figure the renewal e-mail shows).
    - `overHal` number, nullable, required: Spending in that period beyond its monthly credit, in hellers excluding VAT. With exhaustionMode topup it is what topped-up credit paid (debt that the next monthly credit paid off at the renewal is left out); with cap it also includes any debt the account ran up. null when the credit history no longer reaches back to that period.
    - `expiredHal` number, required: Unused monthly credit that expired with that period, in hellers.
    - `exhaustionMode` 'topup' | 'cap', required: What happened in that period once its monthly credit was used up (see subscription.exhaustionMode).
    - `exhaustedAt` string, nullable, required: When the monthly credit of that period ran out (its last charge), as an ISO 8601 string in UTC; null when some was left or when the credit history cannot show when it ran out.

## Other responses

- `401`: Error codes: unauthorized (request).
- `403`: Error codes: account_suspended (account).
- `429`: Error codes: rate_limited (busy).
- `500`: Error codes: internal_error (service).
- `503`: Error codes: ledger_unavailable (service).

---

[API](https://skmtc.dev/volai/apis/volai-rest-api.md) · [All operations](https://skmtc.dev/volai/apis/volai-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/volai/apis/volai-rest-api/revisions/12029b05e2fa?raw)
