Skip to main content
This area covers what a company pays, what it has used and how cost is attributed. A company is on a plan with a monthly subscription paid through Stripe, holds a prepaid credit wallet (monthly included credit, purchased credit, platform comps), and sees its LLM spend and execution hours broken down by agent, workflow, Slack user, actor and cost tag. Three sidebar entries own it in the client app: Main -> Usage (/usage), Settings -> Billing (/settings/billing) and Settings -> Cost Tags (/settings/cost-tags). Agent, sandbox, integration and dashboard pages show their own usage summaries from the same queries. The plan catalog and account controls live in the admin app (/billing, /billing/:companyId) and are a platform-admin prerequisite.

What it does

Plans. A plan is a versioned catalog row (plan_key free, pro, team, enterprise or custom-<slug>; status draft, active, grandfathered, retired; billing_interval month). Each plan carries a base_price_usd, a monthly_granted_credit_usd and structural entitlements (max_agents, max_seats, max_concurrent_dispatches, allow_oho_attach, allow_byoc, allowed_size_classes). The plan chooser (availablePlans) lists only is_public plans in active status, in the order free, pro, team, enterprise; the seeded Enterprise plan is not public. The seeded version-1 catalog is: Platform admins can publish new versions, so a deployment’s live catalog may differ. Subscription state. Every company gets a FREE_ACTIVE subscription when it is created (payment_mode free). state is one of FREE_ACTIVE, PAID_ACTIVE, PAST_DUE, SUSPENDED, DEACTIVATED. Stripe webhooks move it: a completed checkout goes to PAID_ACTIVE, a failed invoice to PAST_DUE with a 14-day grace timer, a paid invoice back to PAID_ACTIVE, and a deleted subscription after cancel-at-period-end back to FREE_ACTIVE. Entering SUSPENDED starts a 60-day deactivation timer. A platform admin can force any state with a reason. Changing plan. createUpgradeCheckout(planKey) returns a URL the browser follows. A first paid purchase opens a Stripe Checkout page. An existing subscriber moving to a higher tier is upgraded in place and pays the prorated difference now. A move to a lower tier keeps the current plan until current_period_end with no refund and shows a pending change banner; a downgrade to Free is a cancellation at period end. Picking the current plan while a change is pending cancels the pending change. Wallet. The wallet has three credit classes (granted, comp, purchased), consumed in that order. Each period’s included credit is a grant that expires at the period end; the unspent rest is written off with an expiry entry when the next grant lands. Free companies have no Stripe object, so a daily sweep advances their period (anchored on the creation day, clamped to the 28th) and applies the grant. Purchased credit has no expiry. The append-only ledger (walletLedger) records each entry with credit_class, amount_usd, entry_type (grant, purchase, comp_grant, debit, expiry, refund, adjustment), reason and the class balance after it. Top-ups. createTopupCheckout(amountUsd) opens a Stripe Checkout for a one-off credit purchase; the client offers $25, $50, $100 and $250. Credit lands only when the checkout.session.completed webhook arrives, never on return from the page. Paid plans only: the Free plan has no purchase button. Auto top-up. setAutoTopup(enabled, thresholdUsd, amountUsd, monthlyCapUsd) stores a policy: when the balance falls below the threshold after a debit, buy the amount off-session, at most the monthly cap per calendar month and at most one attempt per 24 hours. Three consecutive card declines turn it off and email the billing contacts. The change is written to the audit log. Payments and receipts. billingPayments lists subscription charges (from stored invoice.paid events, with the Stripe hosted invoice link as receipt) and top-ups (from purchase ledger rows), newest first. createPortalSession opens the Stripe customer portal for payment method, invoices and cancellation. What is charged today. Only the subscription fee and top-up purchases move money. Every LLM call runs on the company’s own provider key: resolve_llm_key_source returns byo unconditionally, and the five-minute debit job only debits olyros_provided interactions, so no LLM usage is debited from the wallet today. Execution time is metered but priced at zero; the Usage page says “Not billed today — quantities only”. The billing gates. Five enforcement points read the subscription and wallet before work runs. Each has its own mode, off, dark (record a would-block, allow) or live (refuse), set per deployment in the platform settings; the code default is off. The wallet floor is $0.50 by default. Under it, a Free company reads “You’ve used this month’s included credit. Upgrade to keep your agents running.” and a paid company “Out of credits — top up or enable auto-top-up to keep your agents running.” PAST_DUE keeps full service through its grace window. Over-cap resources are never removed; only net-new creation is refused. Usage page. /usage has an LLM section and an execution section, a time window (presets Today, 7 Days, 30 Days, This Month, Last Month, or a custom range) and filter chips for actor, agent, tag and workflow. Chips of one kind are OR-ed, kinds are AND-ed, and the window and chips live in the URL so a link reproduces the view. detailedUsageStats returns interactions, tokens, cost, active agents, a trend against the previous equal period, a time series (UsageGranularity HOUR for windows up to 36 hours, else DAY) and breakdowns by agent, integration, environment, model, workflow, Slack user, actor and tag. executionUsage returns execution hours and invocations by environment backend and by actor, split into surface classes billable_cloud (Olyros-operated cloud), customer_hosted (the company’s OHO hosts), tenant_cloud (the company’s own cloud project, shown at $0) and build (image builds). Export CSV (usageExport) writes one row per model interaction, newest first, with time, agent, environment, provider, model, tokens in and out, cost, actor and tags, restricted to the active filters. The old drill-down routes /usage/actor/:actorType/:actorId and /usage/tag/:tagName redirect to the filtered main page. Cost tags. A cost tag is a company-wide label with an optional color and description. Tags are assigned to agents (agent and sandbox overview pages), to workflows, and to Slack users (see Slack). When a run starts, the names of its workflow’s or agent’s tags, plus the Slack user’s tags when the actor is a Slack user, are copied onto the run and its interactions. Usage history therefore keeps the tags that applied at the time; renaming or deleting a tag does not rewrite past usage.

Who can use it

  • Any company member may read everything here: billingSummary, walletLedger, billingPayments, availablePlans, every usage query (membership only), and the cost tag list and per-agent or per-workflow tags.
  • Company admin (ability billing.manage, minimum role admin) is needed to change plan, buy credit, open the customer portal or set auto top-up: createUpgradeCheckout, createTopupCheckout, createPortalSession, setAutoTopup. Other members see the Billing page with these buttons disabled and the tooltip “Only workspace admins can change billing.”
  • Any company member may create, edit and delete cost tags and set an agent’s or a workflow’s tags (createCostTag, updateCostTag, deleteCostTag, setAgentTags, setWorkflowTags all check membership only).
  • Company admin (ability slack.manage) is needed to read or set a Slack user’s tags (slackUserCostTags, setSlackUserTags).
  • Platform admin (admin app) publishes plan versions, migrates cohorts, assigns plans, forces states, grants comps, adjusts wallets, extends grace and triggers reconciliation. Billing emails go to every active company admin, or to the company’s creator when there is none.
  • Plans limit counts (agents, seats, OHO attach); no other feature is gated by plan.
The roles and their abilities are listed on Company settings.

How to configure it

  1. Choose or change a plan. Settings -> Billing (/settings/billing) -> Upgrade or Change plan -> pick a plan -> confirm: createUpgradeCheckout(planKey). A first purchase redirects to Stripe Checkout and returns to /settings/billing with checkout=success or checkout=cancelled. Cancel a scheduled downgrade with “Cancel scheduled change”, which re-picks the current plan. The plan must be synced to a Stripe price, otherwise the call fails with “Payments are temporarily unavailable”.
  2. Buy credit. Settings -> Billing -> Wallet -> purchase -> pick an amount -> continue: createTopupCheckout(amountUsd). The amount must be greater than zero.
  3. Turn on auto top-up. Settings -> Billing -> Automatic credit purchases -> enable and fill “When balance falls below”, “Charge me” and “Up to (per month)”: setAutoTopup. All three are required to enable; the threshold may be zero, amount and cap must be greater than zero. Disabling clears all three.
  4. Manage the card and invoices. Settings -> Billing -> Billing & invoices: createPortalSession.
  5. Review spend. Settings -> Billing shows the plan, the period’s included credit consumed, wallet balances by class, the statement (walletLedger, page size up to 200, default 50) and payments (billingPayments).
  6. Create cost tags. Settings -> Cost Tags (/settings/cost-tags) -> Create Tag: createCostTag(name, color, description). Names are 1 to 100 characters of letters, digits, hyphens, underscores and spaces, unique per company ignoring case. Edit with updateCostTag, delete with deleteCostTag (assignments are removed with it).
  7. Tag agents and workflows. Agents -> an agent -> Overview -> tag picker: setAgentTags(agentId, tagIds), which replaces the agent’s set. Workflows -> a workflow -> canvas inspector (workflow settings) -> Cost Tags -> tag picker: setWorkflowTags(workflowId, tagIds), same replace semantics. At most 10 tags per agent or workflow.
  8. Tag Slack users. Settings -> Slack Users -> tag picker: setSlackUserTags; see Slack.
  9. Read usage. Main -> Usage (/usage) -> pick a window, add chips, switch breakdown tabs, Export CSV: detailedUsageStats, executionUsage, usageExport.

Limits and defaults

What it emits

  • Wallet ledger rows for every grant, expiry, purchase, comp, debit, refund and adjustment, each with an audit event.
  • Audit events billing.subscription.state_changed and billing.autotopup.updated.
  • A BillingEnforcementEvent for every would-block in dark mode (gate, reason such as state_suspended, wallet_floor, max_agents, and detail).
  • task.billing_refused events on refused cloud tasks and a rejected_billing rejection frame on refused sandbox invocations.
  • Billing emails: auto top-up disabled, and advance notice of a plan price migration.
  • Cost tag names stamped on workflow executions and agent interactions, which the Usage page, the CSV export and the per-agent usage summaries read.

Known gaps

  • No LLM usage is charged from the wallet: all keys are the company’s own, so the debit job writes nothing and auto top-up, which runs after a debit, never fires today.
  • Execution hours are metered and shown but not priced.
  • allow_byoc, allowed_size_classes and max_concurrent_dispatches are stored on plans and shown in the chooser but nothing enforces them.
  • Nothing moves a company from PAST_DUE to SUSPENDED when the 14-day grace timer runs out, or from SUSPENDED to DEACTIVATED after 60 days; only the Stripe subscription-deleted webhook and admin force-state change these states.
  • The refusals EmailUnverified and FreeCompanyLimit are defined but never raised.
  • costByActor and costByTag have no client caller; the Usage page uses detailedUsageStats breakdowns instead.
  • Top-ups in the payments list have no receipt link, and subscription charges from before 2026-07-07 are missing.
  • A mid-period plan change does not recalculate the included credit grant.
  • The Usage page has no drill-down listing the agents, workflows and Slack users that carry a given cost tag.
  • The CSV export stops at 10,000 interactions without telling the user.
  • Enforcement events are documented as kept for 6 months, but no job prunes them.
  • There are no budgets, spend alerts or scheduled usage reports.

Customer-safe summary

Every workspace starts on the Free plan and can move to a paid plan from the Billing settings page. Upgrades take effect immediately and downgrades at the end of the current period. Each plan includes a monthly credit allowance, and paid plans can buy extra credit or have it bought automatically under a monthly cap you set. Plans set how many agents and team members you can have and whether you can connect your own orchestrator. Today your agents use your own AI provider keys, so model usage is not charged by us, and execution time is shown for information only. The Usage page breaks your spend down by agent, workflow, person and cost tag, and you can export it as a spreadsheet. Only workspace admins can change billing; everyone in the workspace can see it.