Skip to Content
DocumentationCI AccountBilling and subscriptions

Billing & Subscriptions

Organizations in your CI Account have a Billing tab in Organization settings. From it an organization owner or admin can put the organization on the Pro plan, add priced extras on top of it — custom domains, extra public subdomains, extra paired devices, user support — change how many of each the organization holds, and open the Stripe billing portal for invoices, the payment method and cancellation.

Billing is scoped to an organization, not to an individual account. Payment is handled by Stripe on Stripe-hosted pages; your card details never pass through the CI Account.

Availability. The Billing tab only appears on deployments where the operator has turned on the orgSettings.billing feature flag and connected the deployment to Stripe. On hub.ci.computer  that flag is switched off today, so most readers will not see a Billing tab yet, and there is no way to buy a plan there. Nothing is refused over a plan on that deployment either — billing.enforcement is off as well. This page describes what ships in the software so you can recognise it when your deployment turns it on.

Organization settings with the Billing tab selected, for an organization on Pro. The summary card reads Pro, Active, with a renewal date, the add-ons Custom Domain and Extra Subdomain, an Invoices and payment button, and usage rows: public subdomains 5 of 15 used, paired devices 1 of 2 used, custom domains 5 of 8 used. Below it, the Plan section shows the Free and Pro cards, with Pro marked as the current plan, and the Add-ons section shows Custom Domain at $4.00 a month each and Extra Subdomain at $1.00 a month each, each with an active badge and Change quantity and Remove controls, plus Extra Device at $5.00 a month each and User Support at $29.00 a month, which are not added yet.Organization settings with the Billing tab selected, for an organization on Pro. The summary card reads Pro, Active, with a renewal date, the add-ons Custom Domain and Extra Subdomain, an Invoices and payment button, and usage rows: public subdomains 5 of 15 used, paired devices 1 of 2 used, custom domains 5 of 8 used. Below it, the Plan section shows the Free and Pro cards, with Pro marked as the current plan, and the Add-ons section shows Custom Domain at $4.00 a month each and Extra Subdomain at $1.00 a month each, each with an active badge and Change quantity and Remove controls, plus Extra Device at $5.00 a month each and User Support at $29.00 a month, which are not added yet.
The Billing tab for a Pro organization with two add-ons. Example data.

Plans

There is one plan per organization: Free or Pro. Pro is sold monthly or annually; both grant the same things.

FreePro
Price$0.00$9.00 / month or $99.00 / year (the tab shows the annual price as “Save 8%”, equal to $8.25 / month)
Public subdomains310
Paired devices12
Add-onsNot availableUnlocked — see Add-ons
Custom domains00 included; bought as an add-on

Prices are in USD and are the same for every organization. There are no trials, coupons or custom pricing.

Companion Memory is free, on both plans. It is not something Pro unlocks: it installs from the store like any other free app, and the Hub offers it during setup whatever plan you are on. Earlier versions of this page listed it as a Pro feature; that was wrong and has been corrected.

The Billing tab for an organization on the Free plan. The summary card reads Free, Current plan, You're on the Free plan, with an Upgrade to Pro button and usage rows: public subdomains 0 of 3 used, paired devices 0 of 1 used, custom domains 0 of 0 used. The Plan section shows three cards: Free at $0.00 marked Current plan, Pro Monthly at $9.00 a month with a Subscribe button, and Pro Annual at $99.00 a year with a Save 8% badge and a Subscribe button.The Billing tab for an organization on the Free plan. The summary card reads Free, Current plan, You're on the Free plan, with an Upgrade to Pro button and usage rows: public subdomains 0 of 3 used, paired devices 0 of 1 used, custom domains 0 of 0 used. The Plan section shows three cards: Free at $0.00 marked Current plan, Pro Monthly at $9.00 a month with a Subscribe button, and Pro Annual at $99.00 a year with a Save 8% badge and a Subscribe button.
The top of the Billing tab on the Free plan. Example data.

Add-ons

Add-ons are à la carte extras on top of Pro. An organization on Free sees them locked with Requires the Pro plan.

Add-onPricePriced perMaximum per organizationWhat it gives you
Custom Domain$4.00 / monthdomain25One custom domain per unit. acme.com and www.acme.com are two units.
Extra Subdomain$1.00 / monthsubdomain100One more public subdomain per unit, on top of the 10 that Pro includes
Extra Device$5.00 / monthdevice100One more paired Hub per unit, on top of the 2 that Pro includes
User Support$29.00 / monthorganization1Direct support for your organization’s users

Every add-on is billed as an item on the Pro subscription — there is one subscription per organization, and its items are the plan plus whatever add-ons you hold. That has three consequences:

  • Adding or changing an add-on charges the card already on file, and removing one credits it; you are never sent back through Checkout.
  • A change part-way through a billing period is prorated: Stripe bills or credits the difference for the rest of the period, and the new amount applies from the next invoice.
  • The add-ons share the plan’s renewal date and end with the plan if you cancel it.
The Change Custom Domain dialog over a dimmed Billing tab. It reads Choose how many this organization should have, your bill changes to match, with a stepper set to 8, the note Up to 25 per organization, the total 8 × $4.00 = $32.00/mo, a note that Stripe bills or credits the difference for the rest of this billing period and the new total applies once Stripe confirms it, and Cancel and Save buttons.The Change Custom Domain dialog over a dimmed Billing tab. It reads Choose how many this organization should have, your bill changes to match, with a stepper set to 8, the note Up to 25 per organization, the total 8 × $4.00 = $32.00/mo, a note that Stripe bills or credits the difference for the rest of this billing period and the new total applies once Stripe confirms it, and Cancel and Save buttons.
The quantity dialog for a per-unit add-on.

Subscribe to Pro

You need to be an owner or admin of the organization.

Open Billing

Sign in to your CI Account, open Organization settings and select the Billing tab. If you do not see the tab, check the Availability note at the top of this page and read Who can see and change billing.

Choose monthly or annual

In the Plan section, click Subscribe — $9.00/mo on the Pro Monthly card or Subscribe — $99.00/yr on the Pro Annual card.

Pay on Stripe Checkout

Your browser is sent to a Stripe-hosted Checkout page. Enter your card there; it is never shown to or stored by the CI Account. Cancelling on that page brings you back to the Billing tab with a “Checkout cancelled — you haven’t been charged” notice.

Wait for “Purchase confirmed”

After payment Stripe returns you to the Billing tab, which shows Checkout complete. followed by “We’re confirming your purchase with Stripe — this page will update automatically.” The plan is granted when Stripe’s webhook reaches the CI Account, which normally happens within seconds — often before your browser finishes coming back. The banner then changes to Purchase confirmed and the summary card reads Pro — Active.

The tab polls every three seconds for about a minute. If the webhook has still not arrived by then it shows Still confirming — if you completed payment it can take another minute; refresh the page, or open the billing portal to see what Stripe has recorded. Nothing further is needed from you.

How the confirmation actually happens — the tab never trusts the return URL, only the record written by Stripe’s webhook:

Add, change or remove an add-on

All three happen on the add-on’s card in the Add-ons section and require the Pro plan.

Add. For the per-unit add-ons (Custom Domain, Extra Subdomain, Extra Device) the card’s Add … button opens a quantity dialog: pick how many with the stepper, up to the card’s ceiling (Up to 25 per organization for custom domains, 100 for the others), and confirm. User Support has no quantity — its button reads Add — $29.00/mo and adds it directly. The card shows Activating… until Stripe’s webhook records the new item, then a badge such as 5 active.

Change quantity. Click Change quantity on a per-unit add-on you already hold. The dialog opens on the number you currently have, shows the new monthly total, and notes that Stripe bills or credits the difference for the rest of this billing period; the new total applies once Stripe confirms it. On a deployment that enforces entitlements, reducing the Custom Domain quantity below the number of domains you have connected is refused — disconnect a domain first.

Remove. Click Remove on an add-on you hold. The confirmation says what happens: the charge stops and the capability is taken away immediately — for a per-unit add-on, all of the units at once (the dialog reads, for example, “Remove all 5 × Custom Domain?”). The unused part of the period you already paid for is credited against the next invoice. The Pro plan and every other add-on keep running.

Removing the Custom Domain add-on while domains are connected leaves those domains without an entitlement. On a deployment that enforces entitlements they stop being served (they show as Paused in the Domains tab) until you add the add-on back. Disconnect domains you no longer want before removing the add-on.

Invoices, payment method and cancelling

Invoices, receipts, the payment method and plan cancellation all live in the Stripe billing portal, opened from the Invoices & payment button on the summary card or Manage in billing portal on the Pro card. The button appears for any organization that has ever paid, so you can still reach past invoices after cancelling.

In the portal you can:

  • download invoices and receipts;
  • update the card on file;
  • cancel the Pro plan.

Cancellation takes effect at the end of the current billing period. Until then nothing changes: the Billing tab shows a Cancelling badge beside Active, and the summary reads “Cancelled. Pro stays active until date, then this organization moves to Free.” At period end the plan and every add-on end together and the organization returns to Free with its Free limits.

The summary card of a Pro plan that has been cancelled in the billing portal. It shows Active and Cancelling badges and reads Cancelled, Pro stays active until a date, then this organization moves to Free, with the add-ons Custom Domain and Extra Subdomain and the usage rows unchanged.The summary card of a Pro plan that has been cancelled in the billing portal. It shows Active and Cancelling badges and reads Cancelled, Pro stays active until a date, then this organization moves to Free, with the add-ons Custom Domain and Extra Subdomain and the usage rows unchanged.
A cancelled plan keeps working until the end of the period. Example data.

The portal does not let you change quantities or drop a single add-on — those are the Change quantity and Remove controls on the Billing tab, described above. While the plan is in its Cancelling window it is still active and owned, so the Billing tab does not offer Upgrade to Pro (a new checkout would be refused with 409 ALREADY_PURCHASED); reversing a pending cancellation is done in the billing portal. Once the period ends and the organization is back on Free, Upgrade to Pro returns to the Billing tab and re-subscribing is a fresh purchase.

What a plan actually enforces

A plan is a set of limits that the CI Account checks at the moment you use them, not a badge. What the current plan includes is shown in the summary card’s usage rows (public subdomains, paired devices, custom domains).

CapabilityWhere it is checkedFreeProAdd-on
Paired devicesWhen a Hub is paired — the pairing is refused with “This organization’s plan includes N devices. Remove a device or upgrade to pair another.”12Extra Device, +1 each
Public subdomainsWhen an app is published to a public hostname; the Hub’s own dashboard hostname does not count310Extra Subdomain, +1 each
Custom domainsWhen a domain is connected (creation) and on every Hub heartbeat (delivery) — a domain the organization is no longer entitled to stops being served00Custom Domain, +1 each, up to 25

Companion Memory is not in this table because it is not limited by plan — it is free on Free and Pro alike.

Two things are worth knowing:

  • Enforcement is a separate switch. Resolving the plan and refusing over it are controlled by different feature flags. An operator can leave billing.enforcement off, in which case the CI Account works out what it would refuse, logs it, and lets the action through. On hub.ci.computer enforcement is off today.
  • The CI Account fails closed. A plan only counts when its Stripe record is present, trusted, active and inside its paid period. The one exception is a failed renewal, which keeps Pro for a grace period — see Failed payments. If the deployment has no Stripe key at all, every organization is treated as Free — even one with a Pro row in the database.

Failed payments

When a renewal payment fails, Stripe keeps the subscription past_due and retries the card. The CI Account keeps Pro, and every add-on on it, working for seven days from the first failure, then treats the organization as Free if the payment is still unpaid. A card declined on renewal day therefore costs nothing if you fix it within the week.

During those seven days the Billing tab shows an amber banner: Your last payment failed. with “Update your payment method by date to keep Pro.” After the deadline the banner turns red and reads Pro is paused because a payment failed. Either banner has an Update payment method button that opens the Stripe billing portal. Stripe retries the open invoice once the card is fixed, and a successful payment clears the banner.

The Billing tab during the grace period after a failed renewal. An amber banner reads Your last payment failed, Update your payment method by a date to keep Pro, with an Update payment method button. Below it, the summary card still reads Pro, Active, with its add-ons and usage rows.The Billing tab during the grace period after a failed renewal. An amber banner reads Your last payment failed, Update your payment method by a date to keep Pro, with an Update payment method button. Below it, the summary card still reads Pro, Active, with its add-ons and usage rows.
The grace-period banner above the summary card. Example data.

While a renewal payment is unpaid, nobody can buy anything new: the tab offers Update payment method instead of Upgrade to Pro, and add-on purchases and quantity changes are refused with 409 PAYMENT_OUTSTANDING. Retries do not extend the deadline. A subscription that Stripe has ended (unpaid, canceled) gets no grace period.

Over the plan’s limits

An organization can hold more than its plan includes — because devices were paired or apps published before limits applied, or because a plan lapsed. Where billing.enforcement is on, the Billing tab then shows This organization is over its plan’s limits, listing each capability with what is in use against what the plan includes, for example “Paired devices: 2 in use, 1 included (1 over)”. Everything you already have keeps working, and custom domains stay paused until your plan includes them. To add more, buy an add-on or upgrade to Pro, or remove some. Home shows a matching notice above the device list when paired devices exceed the limit. With enforcement off, as on hub.ci.computer today, no notice appears and nothing is refused.

Who can see and change billing

RoleBilling tab
OwnerSees the tab; can subscribe, add, change and remove add-ons, and open the billing portal
AdminSame as owner
MemberDoes not see the tab at all

The tab is also hidden — for everyone — when the deployment’s orgSettings.billing flag is off or the server reports that Stripe is not connected. Hiding it is deliberate: the CI Account never offers a purchase it cannot honour.

For developers

These endpoints back the Billing tab. All but the webhook are scoped to an organization you belong to; requests for organizations you are not a member of return 404, and every organization-scoped route returns 404 when the deployment’s orgSettings.billing flag is off. The webhook is the exception: it carries no session and no membership check, is authenticated by its Stripe signature alone, and is not behind that flag.

MethodPathWho can call itWhat it does
GET/api/organizations/:orgId/billingowner or adminReturns stripeEnabled, the purchasable catalog (featureKey, name, unitAmount in cents, currency, billingInterval, maxQuantity) and the organization’s ownership (planKey, ownedFeatureKeys, ownedQuantities, currentPeriodEnd, cancelAtPeriodEnd, cancellingFeatureKeys, hasBillingAccount)
POST/api/organizations/:orgId/billing/checkoutowner or adminBody { featureKey: "pro_monthly" | "pro_annual" }. Opens a hosted Stripe Checkout session for the Pro plan and returns 201 { url, … }. Any other featureKey — an add-on, or a feature that is not for sale — fails request validation with a plain 400 before the handler runs; an organization already on Pro gets 409 ALREADY_PURCHASED, and one with an unpaid renewal gets 409 PAYMENT_OUTSTANDING
POST/api/organizations/:orgId/billing/portalowner or adminReturns 201 { url } for a Stripe billing portal session; the portal returns to /org-settings?tab=billing&portal=return
POST/api/organizations/:orgId/billing/addons/:featureKeyowner or adminBody { quantity }. Adds custom_domain, subdomain_pack, extra_device or user_support as an item on the plan’s subscription. 402 PLAN_REQUIRED without Pro; 409 ALREADY_PURCHASED if already held (use PATCH)
PATCH/api/organizations/:orgId/billing/addons/:featureKeyowner or adminBody { quantity }. Changes a held add-on’s quantity, prorated. 409 CAPABILITY_IN_USE when lowering custom_domain below the number of connected domains and enforcement is on
DELETE/api/organizations/:orgId/billing/addons/:featureKeyowner or adminRemoves the add-on’s subscription item immediately with a proration credit. Plans cannot be deleted this way — cancel them in the portal
GET/api/organizations/:orgId/entitlementsany memberAdvisory report of the plan: limit, used and enforced for custom domains, extra subdomains and devices
POST/api/webhooks/stripeStripe onlySigned webhook receiver. The only thing that ever grants or revokes a plan or add-on.

Three rules follow from the last row:

  • Every purchase route answers with grantsEntitlement: false (or applied: false). The entitlement lands when Stripe’s customer.subscription.* event is verified and applied, so a client must poll GET …/billing until ownership.ownedFeatureKeys includes what was bought — which is exactly what the tab does.
  • Nothing read from the Stripe API becomes an entitlement; only the webhook writes plan rows, and each event is applied at most once and only if it is newer than the last one applied for that subscription.
  • 503 BILLING_NOT_CONFIGURED is terminal, not transient. From the purchase routes it means the deployment has no Stripe key. POST …/billing/portal answers with the same code when Stripe refuses the portal session — the customer-portal configuration was never saved for that mode, or the API key lacks the portal permission — even though a key is present.

The subdomain_pack key is a stable identifier that predates the rename to “Extra Subdomain”; read name and unitAmount from the catalog rather than hard-coding either.

Configuration (operators)

Names only — never commit or paste the values. Full setup, including creating the products and prices, the webhook endpoint, the portal configuration and test-mode versus live-mode, is kept with the CI Account source, which is not public.

NameKindPurpose
STRIPE_SECRET_KEYsecretConnects the deployment to Stripe. Absent ⇒ Billing is hidden, purchases return 503, and every organization resolves to Free
STRIPE_WEBHOOK_SECRETsecretSigning secret for /api/webhooks/stripe. Absent ⇒ no event is accepted and nothing is ever granted
STRIPE_PRICE_PRO_MONTHLY, STRIPE_PRICE_PRO_ANNUALsecretStripe price ids for the Pro plan. Not sensitive in themselves, but delivered as Worker secrets like the two above
STRIPE_PRICE_CUSTOM_DOMAIN, STRIPE_PRICE_SUBDOMAIN_PACK, STRIPE_PRICE_EXTRA_DEVICE, STRIPE_PRICE_USER_SUPPORTsecretStripe price ids for the add-ons. A subscription item whose price id matches none of these grants nothing
REACT_APP_BASE_URLvariablePublic origin Stripe returns to after Checkout and the portal
orgSettings.billingfeature flagShows the Billing tab and enables the billing routes
billing.enforcementfeature flagWhether plan limits refuse actions or only log what they would refuse

The catalog prices on this page are what the tab displays; the amount charged is whatever the Stripe price behind each STRIPE_PRICE_* id says. Keep them in step — nothing in the CI Account detects a mismatch.

Troubleshooting

IssueCause / fix
No Billing tab in organization settingsEither you are a member (owners and admins only), or the deployment has billing switched off or Stripe not connected. On hub.ci.computer the flag is off today, so this is expected.
Add-on cards read Requires the Pro planAdd-ons are sold only on top of Pro. Click Upgrade to Pro first.
Still confirming after CheckoutStripe’s webhook has not reached the CI Account within about a minute. If you paid, refresh the page or open Invoices & payment to see what Stripe recorded; the plan appears when the event arrives. If it never does, ask your operator to check the deployment’s webhook endpoint.
Card refused when adding an add-onAdd-ons charge the card already on file for the Pro subscription. Update the card in the billing portal and try again.
409 CAPABILITY_IN_USE when lowering Custom Domain quantityYou have more domains connected than the new quantity. Disconnect domains in the Domains tab first.
Removed an add-on and its domains show PausedRemoval takes the capability away immediately, and on a deployment that enforces entitlements the domains stop being served. Add the add-on back to resume delivery, or disconnect the domains. Where billing.enforcement is off — as on hub.ci.computer today — this state never appears.
Cancelled in the portal but the plan still says ActiveCorrect — Pro stays active until the end of the period you paid for. The Cancelling badge confirms the cancellation took.
Paired a second device and it was refusedThe plan’s device limit was reached (1 on Free, 2 on Pro). Remove a device, upgrade to Pro, or add Extra Device units.
503 BILLING_NOT_CONFIGURED from the APITerminal, not transient — an operator has to fix the deployment. From a purchase route it means there is no Stripe key; from the billing portal route it can also mean Stripe refused the portal session (portal configuration not saved, or a restricted key without the portal permission).
404 from a billing endpointYou are not a member of that organization, or the deployment’s orgSettings.billing flag is off.

See also: Organizations, Custom Domains.

Last updated on