Billing & plans
Otapush is metered by MAU — monthly active users (unique devices): the number of distinct devices that contact your update server during a calendar month. Everything else — updates published, channels, storage, bandwidth — is unmetered on every plan. Prices are in rubles, and payments run through T-Bank.
Draft pricing — final prices will be announced before launch.
Where the device id comes from and how the server attributes requests is documented in Protocol; registering one in your app is part of the Quickstart and Expo setup.
What counts as a MAU, and what does not
A "device" is the device id string the client sends with every protocol request — as a query parameter, an x-device-id header, or a deviceid extra param. The server keeps exactly one record per (app, device, calendar month): the first manifest check or asset download of the month creates it, and nothing the device does for the rest of that month changes the count.
The consequences are worth spelling out:
- A device counts once. One that checks for updates every hour all month is one MAU.
- Checks that find no update count. The device record is written before the server decides whether an update exists, so idle devices polling a quiet channel are metered too.
- Requests that fail early do not count. A request rejected for a missing device id, an unknown app slug or an unknown channel is answered before any device record is written.
- Uncounted traffic exists. With
REQUIRE_DEVICE_ID=falseon the server, requests without any id are served normally and stay unattributed — they are not counted. - Test devices count. A
curlwith?deviceId=curl-testis a MAU, and so is an emulator. Keep load tests and CI smoke checks on a server you are not billed for.
The month is a UTC month: the counter resets at 00:00 UTC on the 1st, not in your local timezone. A device that does not contact the server in a given month is simply absent from it — there is no permanent device registry that remembers previous months.
You can watch the current number on the app's Overview tab and on the portal Billing page.
One limit covers all the apps on your account
The plan's MAU limit applies to the sum over every app you own, not per app: the Billing page adds up the current month's devices across all your apps. An individual app's Overview tab shows that app's own count measured against the same account limit.
The number of apps is a separate limit and it is enforced differently. On Free (1 app), Start (3) and Pro (10) the server refuses to create another app with 403 plan_limit once the cap is reached; Business and Enterprise have no cap. So apps-over-limit is blocked at creation — MAU-over-limit never is, as the next section explains.
What happens when you go over the limit
Updates are never blocked. The endpoints that serve manifests and assets do not consult the plan limit — there is no code path that stops serving when the MAU count passes the limit, for any plan. What actually happens:
- the stats API reports
overLimit: truealongside the count and the limit; - the Overview and Billing pages show the usage bar in a warning state: "Limit exceeded — updates keep working, but please upgrade your plan."
There is no email notification — the code contains no mailer or notification system of any kind. The warning state in the portal is the entire signal.
Upgrading takes effect the moment the payment is confirmed, and the new limit applies to the current month immediately.
Plans
| Plan | MAU | Apps | Monthly | Yearly |
|---|---|---|---|---|
| Free | 10 | 1 | 0 ₽ | 0 ₽ |
| Start | 1 000 | 3 | 490 ₽ | 4 900 ₽ |
| Pro | 10 000 | 10 | 2 490 ₽ | 24 900 ₽ |
| Business | 100 000 | Unlimited | 9 990 ₽ | 99 900 ₽ |
| Enterprise | Custom | Unlimited | Contact us | Contact us |
A year costs ten months: the yearly price equals ten monthly payments — 4 900 ₽ instead of 5 880 ₽ on Start, 24 900 ₽ instead of 29 880 ₽ on Pro. Free and Start are aimed at individual developers; Pro and Business can also be paid by legal entities (by invoice — below). Enterprise is not available through self-service checkout: the portal links to sales instead, and the checkout API refuses it outright.
Monthly and yearly periods
A payment buys one period: one calendar month or one calendar year, added to the moment of activation. The periods differ in price and in arithmetic — limits, channels and signing work identically under both.
If you pay again while a subscription is still active, the new period is appended to the existing end date, not to the payment date: buy a year of Pro in March with the current period ending in April, and the subscription runs to the following April. The activation webhook is idempotent — a repeated notification does not extend the period twice.
Changing your plan
There is no separate "change plan" operation: you pay for the new plan, and on the confirmed payment the account switches to it immediately. The paid period extends from the later of "now" and the previous period's end, so time you have already paid for is not lost. Two consequences worth knowing before you click:
- No proration. Moving from Pro to Business mid-month charges the full Business price; the server computes no partial amounts in either direction.
- Downgrading is the same operation. The lower limit applies at once, and the new period still starts after the current one ends.
Paying by card (T-Bank)
Card payments go through T-Bank internet acquiring; the portal labels the method "Bank card / SBP (T-Bank)" — the T-Bank payment page supports bank cards and SBP. A fiscal receipt (54-ФЗ) is issued for every payment and sent to your account's email address.
- Open Billing in the portal, pick a plan, a period, and the card method.
- You are redirected to the T-Bank payment page (the
paymentUrlthe checkout API returns). - After you pay, T-Bank confirms the payment with a signed webhook; the server verifies the token and activates the plan. Repeated notifications for the same payment change nothing.
- Reload the Billing page — the current plan and period end date come from
GET /api/billing/subscription.
Paying by invoice (legal entities)
On Pro and Business, a legal entity can pay by bank transfer:
- On Billing pick the plan, set the payer to Legal entity and the method to Invoice.
- The server records the payment and shows an invoice id plus the payee requisites. There is no generated PDF document — the requisites come from the server's billing configuration, and a default deployment carries placeholders.
- Pay the invoice from your company account.
One thing to know, stated plainly: the code contains no automatic activation for invoice payments. The only thing that turns a plan on is the T-Bank confirmation webhook — the same one cards use — and until a confirmation for the invoice payment arrives, the payment record stays pending. (The API test suite pins this behaviour verbatim: "Invoice payments never activate a subscription on their own.")
The Free plan needs no payment — checkout refuses it. Enterprise refuses checkout too; use the contact-sales link.
End of period, cancellation, refunds
Stated plainly, because this is money:
- Nothing auto-renews. Payments are one-off. There is no stored card, no recurring charge, and no scheduled job that bills you again.
- There is no cancel button. Because nothing renews, there is nothing to cancel: the plan simply runs to the end of the period you paid for, and nothing is charged afterwards.
- The code never expires a plan. No job switches an account back to Free when the period ends; the limit is read from the account's current plan at request time.
- Refunds are not automated. The API has no refund operation; the payment webhook can record refund statuses reported by T-Bank, but nothing in Otapush issues a refund.
Questions and answers
Does a check that returns "no update" still count as a MAU?
Yes. The device record is written on every manifest request that makes it past app and channel lookup, before the server decides what to answer — noUpdateAvailable, a manifest, or a rollback directive all follow the recording.
We have three apps on one account. Does each get its own 10 000 MAU on Pro?
No. The limit is per account: the devices of all three apps are added together and compared against one limit of 10 000. The Billing page always shows the combined number.
What happens if a traffic spike doubles my MAU overnight?
Nothing stops. Manifests and assets keep being served — no plan has a serving cutoff. The portal shows the warning state and the stats API flags overLimit; what you do next (upgrade, or not) is up to you.
Can a legal entity pay by card?
Yes. Payer type and payment method are independent: a legal entity can pay by card through T-Bank, or by invoice on the plans where invoice payment exists (Pro and Business).
When exactly does the counter reset?
At 00:00 UTC on the first day of the month. All month keys are computed in UTC, regardless of where you or your users are.
Will I be charged again automatically when the period ends?
No. There is no recurring billing in the code: every payment is a one-off initiated by you, no card is stored, and nothing is charged when a period ends.
Can I get a refund for unused time?
Not automatically. There is no refund endpoint and no refund flow in the portal; the payment webhook only records refund notifications that T-Bank sends.
Do emulators, CI runs and curl count as devices?
Yes — anything that sends a device id with a protocol request is a MAU for that month. That includes curl with a deviceId query parameter and every release-build launch in an emulator.
Where do I see how much of the limit I have used?
Two places: the app's Overview tab (that app's device count for the current month against the account limit) and the portal Billing page (the sum across all your apps, plus the plan and period end date).