PAYG and monthly compute
Hobby, Pro and Scale remain credit subscriptions: they add funds to the existing wallet and set the account’s owned, running and per-workspace limits. Spend those funds on payg usage or purchase a monthly resource pool upfront. A namespace is optional: supply its exact slug to purchase a separate pool for it. Stripe and wallet funds are payment sources, not additional compute modes. Both modes use the same ownership checks, resource admission, usage ledger, payment reconciliation and signed events.
Read GET /billing/capacity/catalog before offering these products. A successful response advertises the deployed rates and supported modes. If purchases are unavailable, do not substitute a locally calculated price. Existing contracts remain enforceable when new sales are paused. The earlier workspace-2026-09-29 preview card is a separate proposal; this capacity catalog does not activate it or reprice existing subscriptions.
Existing subscriptions and adoption
Existing account subscriptions, namespace credit offers, wallet funds and purchased top-ups retain their saved terms. Upgrading the API, dashboard or SDK does not convert them automatically. Typed compute methods are available in SDK 2.8.0; optional personal-scope arguments require 2.8.1. REST clients can use the deployed routes directly.
Read billing.capacity(namespace) first. A null capacity means the selected scope has not adopted the capacity contract. For an existing hosted reseller subscription, use the saved subscription's plan-change preview and confirmation to move to a monthly capacity offer; billing-mode changes take effect at renewal. A namespace without an active contract can start with the quote flow below. Never run a second checkout or overwrite quotas to simulate conversion.
The existing Mode A and Mode B terms describe who collects a customer's payment. The payg and monthly fields describe compute coverage. Keep those choices separate in your integration.
What each mode buys
Plans and billing choices
GET /credits/plans is the account-tier catalog. It returns subscription prices, cycle credits, wallet_usd_per_cycle, yearly_wallet_usd_per_cycle and resource limits from the backend. Keep these as the main plan cards. Paying the credit subscription refills the wallet; it does not separately prepay all resources up to those limits.
Micro, Small, Medium and Large in the capacity catalog are sizing examples, not another tier subscription. Choose a pool size within the account plan and select PAYG or monthly spending. An authenticated GET /billing/capacity also returns accountPlan, wallet balances in USD and sizing examples with available flags. Pool prices use the saved backend tariff. No account tier or payment price is accepted from browser metadata.
Show included plan credits and one-time credit pack amounts in credits, alongside their purchase prices in dollars. Use credits_per_cycle and yearly_credits_per_cycle from the plan catalog; optional wallet USD equivalents do not replace these amounts. Compute prices, spending and savings can be shown in dollars. Credits use the existing ledger and API accounting unit. One-time credit packages add credits; account credit subscriptions also set the resource tier. Their saved prices and credit grants are unchanged. Monthly pool coverage and meter records track how those credits are spent; they do not introduce another spendable balance.
| Pay as you go | Prepaid monthly | |
|---|---|---|
| Compute payment | Recorded usage, debited from the owner wallet | Account credits spent before activation; saved direct-card and reseller contracts remain supported |
| CPU | Active vCPU-hours at the saved rate | Included within the purchased shared CPU pool |
| RAM | Reserved GiB-hours while the VM holds memory, including pause | Included within the purchased RAM pool |
| Storage | Retained provisioned GiB-hours, including stopped machines | Included within the purchased disk pool for the paid period |
| Spending cap | Bounds resource usage charges in a billing month; reaching it with unpaid debt does not grant free access | The prepaid price covers the period; no second compute-credit allowance |
| Managed proxy transfer | Optional; purchased only when using Oblien's managed proxy | Optional; purchased only when using Oblien's managed proxy |
| Expiry | The spending lease requires funded usage or a paid cap | Compute authorization ends at the paid-through date unless renewal settles |
CPU is shared capacity, not exclusive physical cores. A pool covers personal workspaces or one exact namespace, and is shared across its workspaces. A workload cannot exceed the pool, a stricter configured namespace policy, or the platform’s 12-vCPU per-workspace ceiling. A count such as “16 workspaces” does not multiply the purchased RAM or CPU. Four workspaces allocated 0.25 vCPU each consume one vCPU of that pool.
Monthly CPU, RAM and included storage do not debit the owner’s compute wallet again. A zero wallet or an exhausted old compute allowance cannot interrupt a confirmed paid period. Manual suspension still applies. An uncapped legacy namespace quota does not buy monthly capacity.
The published tariff owns prices, conversions and terms. The dashboard and SDK do not calculate their own resource prices. Every quote saves a tariff version; successful renewals use saved terms. Editing the public tariff does not rewrite a paid contract.
A monthly purchase belongs to a pool
A monthly purchase does not belong to a VM ID. The same pool can host one larger VM or several smaller VMs, within its CPU, RAM, disk and workspace-count limits. For example, a 4-vCPU / 8-GiB RAM pool can fit four running 1-vCPU / 2-GiB VMs when the account tier, retained disks and workspace count also allow them. A single larger VM must additionally fit the account’s per-workspace ceiling. Both PAYG and monthly use the same admission flow.
New contracts return allocationBasis: "running": confirmed stopped or hibernated VMs release their running CPU/RAM for other VMs. Their configured resources remain in the account’s owned pool; retained disks and owned workspace slots still count. Paused VMs and unresolved starts, resizes or automatic restarts retain their running reservation. Deleting a VM does not cancel or renew the pool. Confirmed removal frees its owned allocation with the same paid-through date. A disk kept after deletion continues to consume storage; a timeout is not proof that either the VM or its disk was removed. Delete all VMs to stop their PAYG compute usage, or cancel monthly renewal to stop the next subscription charge. Retained disks remain billable under the saved terms.
There is one current capacity contract per owner and scope: personal workspaces, or one namespace. The whole scope uses its selected compute mode. Independently billed pools can use separate namespaces; they do not borrow each other's capacity. There is no per-VM monthly binding or automatic PAYG overflow beyond a paid pool. The account wallet may fund multiple scopes, while their allocation limits remain isolated. New monthly reservations across all scopes share the account tier’s capacity budget; separate namespaces cannot multiply it. PAYG scopes also share the account’s actual running budget. Declared namespace max_total_* fields continue to cap allocated resources and may be stricter.
Already-sold contracts without the new policy return allocationBasis: "allocated" and retain their original allocation rules and saved prices. They are not silently converted or clamped to Free limits. Existing paid monthly rights remain valid through their paid period if the credit subscription changes. For new contracts using the running policy, wallet purchases and renewals recheck the current account tier before charging; already-sold independent contracts keep their original boundary.
PAYG funding and the monthly ceiling
PAYG uses the existing owner wallet. Use the balance already available or make an ordinary one-time deposit through POST /credits/purchase, with a server-published packageId or an amount in USD dollars. GET /credits/pricing-info supplies package prices, conversion and deposit limits. The capacity catalog also exposes walletFunding.minimumDepositAmount and maximumDepositAmount in USD cents. A wallet deposit is not a subscription or a purchase of additional CPU/RAM capacity.
Send an idempotencyKey for each wallet purchase (8–128 letters, numbers, dots, colons, underscores or hyphens). Retry that purchase with the same key and unchanged input after a timeout. A subsequent deposit uses a new key, even for the same package. Keys are bound to the authenticated owner and payment environment. The dashboard keeps a failed attempt's key across reloads; a browser return never grants balance. Older clients without a key retain a short duplicate-prevention window.
Selecting a PAYG pool has no upfront pool fee. Workspace usage still requires funding: the cap limits recorded CPU, RAM and retained-disk charges during the billing period, but does not make an empty wallet spendable. Paying the cap through actual usage covers the rest of that period at the saved pool size. A later upgrade has its own saved quote and cap. Managed-proxy purchases and other separately priced services remain outside this compute cap.
Each catalog preset may include paygEstimate.computeHourAmount and paygEstimate.storageMonthAmount, both in USD cents, with fractional cents preserved. The hourly example uses the entire CPU pool at full activity and all its RAM reserved; the storage example provisions the entire disk pool for the tariff's storage month. These estimates use the billing meter's saved rates. They are examples before the cap, not flat charges or guaranteed minimum spend. The dashboard displays actual recorded spending and cap savings separately.
The Add funds action preserves the selected pool, mode and optional namespace through Stripe checkout. A successful browser return only prompts a balance refresh; verified provider settlement credits the wallet. The customer still reviews the pool quote before enabling it. Cancellation, a forged return URL or an unpaid checkout cannot activate monthly coverage.
Choose and pay
The dashboard route is /dashboard/billing/capacity. Get Hobby/Pro/Scale opens the existing credit-subscription Stripe checkout. Review this size opens a monthly/PAYG sizing example without starting another subscription. Personal workspaces are the default, so no namespace selection or creation is required. The billing overview also links to Manage compute billing.
Use Use a namespace (optional), or open /dashboard/billing/capacity?namespace=<slug>, for a separate namespace pool. Review the price, available credit balance and effective date before confirming the purchase. Fund the wallet with the existing subscription or deposit flow when needed.
For /billing/capacity/*, omit namespace (or send JSON null) for personal workspaces. Responses use namespace: null. SDK reads can omit the argument (billing.capacity()); mutation methods use null as their first argument. A literal slug default or null always selects that named namespace. Never serialize JavaScript null into the query string.
A personal pool covers only workspaces created without a namespace. It does not replace the owner's account-tier subscription, alter named namespace plans, or grant reseller eligibility. Named pools do not cover personal or sibling workspaces. Resellers must always derive and send their customer's namespace from their authenticated server record; omitting it selects their own personal pool.
These endpoints require the owner’s admin or billing credentials. Namespace and workspace tokens cannot spend funds or manage billing. The existing reseller /billing/checkout still requires an Enterprise owner. Direct capacity purchases do not grant reseller privileges or change the account tier.
| Operation | Endpoint | SDK |
|---|---|---|
| Public prices and presets | GET /billing/capacity/catalog | billing.capacityCatalog() |
| Current contract and saved-tariff presets | GET /billing/capacity (optional namespace) | billing.capacity(namespace) |
| Quote a pool or wallet-funded change | POST /billing/capacity/preview | billing.previewCapacity(namespace, input) |
| Redeem a saved wallet quote | POST /billing/capacity/confirm | billing.confirmCapacity(namespace, input) |
| Open a saved monthly Stripe quote | POST /billing/capacity/checkout | billing.capacityCheckout(namespace, input) |
| Cancel a pending wallet change or unfinished capacity checkout | POST /billing/capacity/change/cancel | billing.cancelCapacityChange(namespace, input) |
| Opt in/out of wallet renewal | POST /billing/capacity/renewal | billing.setCapacityAutoRenew(namespace, input) |
| Quote a proxy-transfer pack | POST /billing/capacity/network/preview | billing.previewNetworkTopup(namespace, input) |
| Recorded cap savings | GET /billing/savings | billing.savings(input) |
const namespace = null; // Personal workspaces; use an exact slug for a named pool.
const catalog = await client.billing.capacityCatalog();
const current = await client.billing.capacity(namespace);
const selected = current.catalog!.presets.find(p => p.id === 'small' && p.available !== false)!;
const { quote } = await client.billing.previewCapacity(namespace, {
capacity: selected.capacity,
billingMode: 'monthly', // Or 'payg', which uses the wallet.
paymentSource: 'wallet', // Spend the existing paid credit balance.
autoRenew: false, // Wallet monthly renewal is opt-in.
idempotencyKey: savedOrder.previewKey,
});
// Display quote.amountDueNow, unusedTimeCredit, effectiveAt and expiresAt.
const result = await client.billing.confirmCapacity(namespace, {
quoteId: quote.id,
idempotencyKey: savedOrder.confirmKey,
});Monetary quote fields, including amountDueNow, are USD cents. walletCreditsRequired is the exact wallet amount. Savings are USD dollars. PAYG usage, monthly pools and transfer purchases spend the same account credit balance, including subscription credits, top-ups, introductory credits and admin/promotional grants. No separate funding approval or paid-only credit balance is required. A namespace allowance is a limit, not additional spendable account credits. wallet.balance reports the balance in USD; wallet.monthlyAvailable is a compatibility field for the same balance, floored at zero. Confirmation locks and debits the authoritative credit balance together with the paid period and event outbox. Uncredited or unverified payment receipts cannot fund a purchase.
Direct Stripe capacity purchases remain an explicit API compatibility option and are also used by hosted reseller offers. They are not the default dashboard funding path. For such a Stripe quote, call capacityCheckout instead of confirmCapacity. Checkout defaults to Stripe-hosted checkout with native promotion-code entry; checkoutMode and allowPromotionCodes retain their existing meanings. The browser return is not payment proof. Read capacity.computeCovered, periodEnd and the signed event after settlement.
Persist each preview key, quote ID and confirmation key with the application order. Retry an interrupted operation unchanged. Request a new quote after expiry or a conflicting contract change. Never submit prices, paid-through timestamps or coverage flags as entitlement instructions.
billing.capacity(namespace) also returns pendingCheckout. Its url resumes the existing checkout; its quote.id can be passed to cancelCapacityChange. Cancellation releases the reservation only after Stripe confirms that checkout cannot be paid. If payment or cancellation has an unknown outcome, keep showing the pending operation and retry. Do not create a competing checkout.
Renewal and changes
Wallet monthly renewal is off by default. Enabling it authorizes each subsequent saved-price debit from available credits. Insufficient funds leave the next month unpaid; they do not create unlimited debt. The worker retries after funding while that renewal period is still current. A long outage does not silently buy months entirely in the past.
An active wallet-funded period keeps wallet payment when changing its pool or compute mode. A card deposit can fund that wallet. Switching the payment source to a recurring card subscription requires the current wallet period to end; it must not create overlapping contracts.
Stripe monthly subscriptions recur until canceled. Use the existing subscription, cancelSubscription, resumeSubscription and portal methods with the same scope. Omit the namespace for a personal subscription (billing.subscription(), billing.portal()), or pass the customer namespace for reseller management. Canceling renewal keeps the current paid period. A hosted subscription must be changed through the plan-change APIs, using previewPlanChange and changePlan; do not open a competing checkout or redeem a second wallet contract for the same period.
To switch a hosted monthly pool to PAYG, use previewCapacity with billingMode: 'payg', then confirmCapacity. Confirmation schedules Stripe cancellation and retains the current paid month. The new PAYG period starts only after the boundary and provider confirmation that the old subscription ended. cancelCapacityChange cancels this pending switch before the boundary and restores the previous renewal preference. It neither charges a second subscription nor grants an unpaid monthly entitlement.
An immediate upgrade reserves physical capacity before charging the prorated increase, and preserves usage and purchased top-ups. The larger entitlement applies only after confirmed funding. Failed payment retains the prior plan; cancellation restores its reservation. Resource reductions and mode changes wait for a billing boundary. Existing allocations must fit a smaller pool before scheduling, and new allocations must keep fitting that upcoming pool. The contract or subscription response exposes the pending change and its effective date; cancellation uses the returned change ID.
Capacity admission verifies real, compatible host inventory before reserving a pool. A hardware quota alone is not a reservation. Account access rules, namespace policies, VMM overhead, pending resizes and retained disks remain part of admission. The owner tier sets owned/running/per-workspace ceilings; the purchased pool adds its running CPU/RAM, retained-storage and workspace-count boundaries. Physical monthly holds are counted across account scopes before money is spent. Stale or missing node observations never free resources. A rejected purchase must not leave spendable funding, a half-applied entitlement or an unrecorded wallet debit.
Refunds
Monthly purchases are upfront spends. Stopping, deleting or replacing VMs, and canceling renewal, do not automatically return those funds. With PAYG, unspent wallet credits remain available; already-metered usage is not undone.
Support can review an exception. A billing administrator uses Account → Billing → Resource pool purchases, selects the original paid period and reviews the exact refundable amount. The existing admin operation requires a billing role, fresh MFA, a reason, typed contract confirmation and a stable idempotency key. There is no customer refund endpoint.
An approved wallet refund reverses that period’s original wallet payments, including paid upgrades, and revokes that period’s coverage in the same financial transaction as the ledger and event outbox. Refunding the current period also disables its automatic renewal. Refunding an older period cannot revoke a newer paid period. Purchased transfer and unrelated top-ups are preserved. Failed commits make no partial refund; retries cannot refund twice. Card refunds stay in the verified payment-provider refund flow.
Expiry, retained storage and restarting
Compute stops when its paid authorization expires. The initial tariff retains disks for at least 30 days, with no automatic deletion. Administrators can publish a tariff with a different terms.retainedAfterExpiryDays; saved contracts keep their agreed terms. The review date does not delete data or end storage charges.
After compute coverage ends, retained provisioned storage is billed at that contract’s saved per-GiB storage rate until the disk is actually deleted. A full refund that revokes coverage starts this storage period at revocation. Changing a quota is not a storage purchase: charges follow confirmed disk sizes, including resize and deletion history.
capacity.retention exposes minimumDays, reviewAt, automaticDeletion, storagePerGiBMonth and amountDue. Its monetary values are USD dollars. quote.retainedStorageAmountDue is USD cents, like other quote amounts, and is separate from compute renewal.
Available wallet funds pay retained-storage charges through the existing ledger. If the wallet is empty, the selected pool records a storage balance due. It does not receive free compute and its purchased proxy-transfer bytes are preserved. Fund the owner wallet to clear this balance, then renew or purchase compute before restarting. A late confirmed renewal that covers an already billed storage interval reverses the overlapping storage charge in the same payment transaction.
The worker releases expired compute reservations only against the current contract and confirmed node state. It keeps disk claims and preserves reservations whose Stripe payment outcome remains unresolved. An unreachable host is not evidence that resources were deleted.
Managed proxy transfer
Transfer through Oblien’s paid internet proxy is an extra in both compute modes. Read the saved per-GiB rate and minimum purchase from the capacity catalog. Public route traffic and traffic using a customer-supplied proxy must not be relabeled as this paid proxy service.
const { quote } = await client.billing.previewNetworkTopup(namespace, {
unitAmount: catalog.tariff.network.minimumTopupCents,
idempotencyKey: savedOrder.previewKey,
});
await client.billing.confirmCapacity(namespace, {
quoteId: quote.id, idempotencyKey: savedOrder.confirmKey,
});Fund the owner wallet through the ordinary wallet-deposit flow when needed. The pack converts available credits to bytes, independently of compute coverage. Unused purchased bytes carry forward. The response distinguishes purchased, consumed, reserved and available bytes. Exhaustion blocks managed proxy access, not a paid month of CPU and RAM.
Compatible nodes use durable, expiring byte grants, counting completed reads and writes to the managed proxy. Unused grants remain reserved until the node acknowledges their return, so a restart or lost response cannot spend the same transfer twice. Existing TCP buffers can drain when a grant expires; this is bounded transfer accounting, not an instantaneous cross-system cutoff. These contracts require node billing capability version 3 (the reserved-memory usage record remains version 2).
Truthful savings
capacity.savings compares this paid period’s recorded usage at its saved PAYG rates:
usageBeforeCap: recorded usage before the cap.capDiscount: the automatic reduction from that baseline.usageCharged: metered compute actually debited.prepaidAmount: capacity fees paid for the period, including upgrades.monthlyDifference: capped PAYG equivalent minus metered charges and prepaid fees. It can be negative for an idle monthly pool.
billing.savings({ month: '2026-10', namespace }) aggregates the saved usage ledger for a UTC calendar month. Its monthlyCoveredUsage excludes subscription fees and is not a cash saving. A partial historical comparison has complete: false; do not invent missing savings. Transfer purchases, taxes and refunds are outside these comparisons.
Events and isolation
Register capacity.changed, capacity.renewed, capacity.expired, capacity.payment_required, capacity.revoked, network.topup_applied, network.allowance.low, network.allowance.depleted, storage.retention.payment_required and storage.retention.paid with the existing signed billing webhook flow. They require owner billing credentials. Events use namespace: null for personal billing and the exact slug for named billing. Storage events include the namespace and balance due in USD; they can drive a reseller’s reminder and wallet-funding link. Store event IDs to deduplicate deliveries and reconcile current state after a delayed event.
Only verified provider receipts or an account credit debit can establish coverage. Wallet movement, capacity entitlement and the delivery outbox commit in the same financial transaction. Stripe, the database and VM hosts are separate systems: durable retries and versioned runtime authorization reconcile them. A timeout does not prove failure; no browser callback, quota edit, TTL setting or stale worker response can mint another paid period.