---
title: Plans and billing
description: Upgrade from Nestling, manage the subscription, download invoices, and what happens when a payment fails.
---

**Not generally available.** Paid plans are built but not yet switched on
at `api.tori.host`. Every account is on the free **Nestling** plan,
`GET /api/billing` answers `configured: false`, the console's billing section
shows the free tier without an upgrade button, and the checkout and portal
endpoints answer `503 billing_unavailable`. This page describes the workflow
as it works once billing is enabled; nothing here can be paid for today.

## Plans

Every new account starts on Nestling, which is free and has the smallest
limits. Paying for **Songbird** or **Flock** raises them. What each plan
allows and costs is served by the API — `GET /api/plans` (no sign-in needed)
and the `catalog` on `GET /api/billing` carry every plan's name, prices and
limits, and `GET /api/account` carries the limits of your own plan under
`limits` — from the same table the platform enforces, so the pricing page and
the console show the numbers that apply rather than a copy of them. The console's **Settings → Billing** section lists the plans
with those numbers: apps, custom domains, concurrent deploys and upload size,
previous static deploys kept for rollback, database size and connections, and build
time.

Prices are flat, in euro, and include VAT for consumers. A business in
another EU member state that enters a valid VAT ID at checkout is charged
without VAT under the reverse-charge rule. A Czech business is charged Czech
VAT whatever its VAT ID, because the sale is domestic. There are no meters and
no overage charges.

Those terms come from the same table as the limits, so each catalog entry
states them too:

- `billing.taxInclusive` is `true` when the listed prices already include
  VAT.
- `billing.overage` is `"none"`: nothing is metered and nothing is billed
  beyond the plan's price. An app that reaches a limit is held there — a
  deploy or an upload past the cap is refused, and a service at its CPU
  ceiling runs slower — rather than charged for the excess.
- `limits.minScale` is the number of instances an app of that plan keeps
  running when idle. `0` means the app scales to zero and the first request
  wakes it.
- `limits.rollbackDeploys` is how many previous static deploys of each app
  keep their files for rollback, on top of the live one. Older deploys stay in
  the history, but their files are removed and they cannot be rolled back to
  ([Deploys](/guides/deploys/)).

The pricing page shows the "Flat", "VAT included" and "No meter" labels only
while every plan's entry says so.

## Upgrading

In the console, open **Settings → Billing**, pick monthly or yearly, and
press **Upgrade to Songbird** or **Upgrade to Flock**. The console sends the
browser to a Stripe-hosted checkout page. The card details are entered there
and never reach Tori. After payment the browser comes back to the console,
which refreshes the account and confirms the new plan: it applies at once.
Backing out of the checkout page returns you to the console with nothing
charged.

Through the API the same flow is `POST /api/billing/checkout` with a body of
`{ "plan": "songbird", "interval": "month" }`; the response carries the `url`
to open. See the [API reference](/api/reference/).

An account that already has a subscription cannot start a second checkout
(`409 already_subscribed`). Plan changes go through the portal below.

## Managing the subscription

**Settings → Billing → Manage billing** opens the Stripe billing portal for
the account. There you can:

- switch between Songbird and Flock, and between monthly and yearly. An
  upgrade applies immediately with a prorated charge; a downgrade or a move
  to a shorter interval takes effect at the end of the period you have paid
  for. Running services are redeployed with the new plan's resources within
  about a minute of the change ([Deploy a service](/guides/service-deploy/#plan-changes));
- update the card, the billing name and address, and the VAT ID;
- download every invoice;
- cancel. Cancelling stops the next charge; the plan stays until the end of
  the paid period and the account then returns to Nestling. No e-mail to
  support is needed.

Through the API, `POST /api/billing/portal` returns the portal `url`.

## Invoices

Every charge produces an invoice with a sequential number, the VAT rate that
applied, and Fortion Networks s.r.o. as the seller. Invoices are listed on
**Settings → Billing** and on `GET /api/billing`, with a link to the hosted
invoice and to the PDF. A refund, when one is issued, is a credit note
against the invoice rather than a bare card refund, so your records and ours
keep matching.

## When a payment fails

Stripe retries the card over several days and e-mails you each time. What
happens on Tori's side is a ladder with dates, counted from the day the
first attempt failed, and every step of it is undone the moment the open
invoice is paid:

| When | What |
|---|---|
| The payment fails | You are told, in the console and by mail. Nothing changes: your apps serve and you can deploy. |
| 7 days later | New deploys are refused (`402 billing_hold` from the API, with the dates). Everything keeps serving. Rollbacks still work. |
| 14 days later | Every hostname of every app on the account stops serving. Nothing is deleted. |
| 30 days later | Your deploy artifacts become eligible for reclamation. Today nothing acts on that date; it will be announced before anything does. |

The console shows the subscription as *payment failed — retrying* and names
the two dates. If every retry fails, Stripe marks the subscription *unpaid*
and the account falls back to the Nestling limits as well: anything above
the Nestling caps — a new app, a larger upload, another custom domain — is
refused until the subscription is paid. The console says so and points at
**Manage billing**; paying the open invoice there restores the plan, the
deploys and the serving without any further step.

Through the API, `GET /api/billing` carries the ladder under `hold`: the
`since` date, the current `stage` and the date each step applies. It is null
when nothing is outstanding.

## Reading the state

`GET /api/billing` returns the account's plan, the subscription it comes from
(status, interval, current period, whether it is set to cancel at period end)
and the invoices. It reads Tori's copy of that state; `POST /api/billing/sync`
refreshes the copy from Stripe first and returns the same shape. The console
calls `sync` when you return from checkout.
