<!-- /en/docs/billing (en) -->

# Billing

All amounts are in franks (₣): the platform's internal accounting unit (1₣ = 1 RUB at the reference rate). A frank is not a currency and not a payment instrument.

## The charge cycle

1. **Reservation (hold)** — when an operation starts, its cost is reserved on the balance (`reserved`).
2. **Execution** — the task runs at the provider.
3. **Confirm** — actual consumption is charged; if the provider delivered less, the surplus of the reservation is returned automatically.
4. **Refund** — on failure the full reservation is returned.

Transaction types in the ledger: `topup`, `reservation`, `confirm`, `refund`; `debit` is a rare legacy row kind.

## Endpoints

| What | Endpoint |
|---|---|
| Balance | `GET /v1/billing/balance` |
| Tariff plan | `GET /v1/billing/tariff` |
| Transactions | `GET /v1/billing/transactions` |
| CSV export | `GET /v1/billing/transactions/export?format=csv` |
| Daily usage | `GET /v1/billing/usage/daily` |
| Price catalog | `GET /v1/billing/pricing/catalog` |
| Cost estimate | `POST /v1/billing/pricing/estimate` |
| Top-up payment link | `POST /v1/billing/payment/link` (Idempotency-Key) |
| Top-up history | `GET /v1/billing/payment/history` |
| Legal invoices | `POST/GET /v1/billing/legal-invoices/*` |

## Transactions

A paginated ledger with filters:

```bash
curl -H "X-API-Key: $FRANKLAB_KEY" \
  "https://apergrex.ru/franklab/api/v1/billing/transactions?type=confirm&page=1&limit=50"
```

Parameters: `type` (topup/reservation/confirm/refund/debit), `attribution` (all/company/personal — whose top-ups to include), `dateFrom`/`dateTo` (ISO 8601), `page` (≥1), `limit` (1–100, default 20). The CSV export accepts the same filters and returns up to 10,000 rows; beyond that it appends a `# truncated: …` comment line with the full count.

## Top-ups

`POST /v1/billing/payment/link` with the required `Idempotency-Key` header (up to 128 characters) creates a card payment link via T-Bank. Retrying with the same key returns the same link while the payment has not terminally failed — no second order is created at the bank.

The fiscal receipt (54-ФЗ, Russian fiscal law) is issued automatically for the email of the partner account the API key belongs to and is sent to the payment terminal together with the Init request — there is no separate payer-address field to fill and none can be supplied.

## Tariffs

The tariff tier applies automatically by lifetime spend:

| Tier | Discount off base | Threshold |
|---|---|---|
| BASE | — | — |
| PRO | 12.5% | > 5,000 ₣ |
| MAX | 25% | > 15,000 ₣ |
| ULTRA | 35% | > 50,000 ₣ |

An earned tier never degrades. Current plan and progress to the next tier: `GET /v1/billing/tariff`; the exact price at your tariff: `POST /v1/billing/pricing/estimate`.

## Cost estimate

The estimate respects your tariff, model parameters and promo windows. There are no side effects: it reserves nothing and starts no tasks.

```bash
curl -X POST -H "X-API-Key: $FRANKLAB_KEY" -H "Content-Type: application/json" \
  -d '{"modelId":"mars-v1-5","duration":5,"resolution":"720p","operation":"text_to_video"}' \
  https://apergrex.ru/franklab/api/v1/billing/pricing/estimate
```

For reference-based models pass counts (`referenceImageCount` etc.) — URLs are not accepted; they only exist after upload at submit time.
