Atrium platform docs
Plans and entitlements
Declare explicit Free and paid plans, prices, feature access, and usage quotas in atrium.yaml.
Declare your catalog
Add billing.mode: atrium and a list of offerings to your manifest. Offering and price keys are stable
identifiers used by your application; names are customer-facing labels. This example defines a Free
subscription and a paid plan with monthly and annual prices:
billing:
mode: atrium
offerings:
- key: free
name: Free
type: subscription
prices:
- key: free-monthly
currency: usd
amount_cents: 0
interval: month
entitlements:
saved_profiles: 2
pdf_exports:
quantity: 3
period: month
priority_support: false
- key: pro
name: Pro
type: subscription
prices:
- key: monthly
currency: usd
amount_cents: 1200
interval: month
- key: annual
currency: usd
amount_cents: 9900
interval: year
entitlements:
saved_profiles: unlimited
pdf_exports:
quantity: 50
period: month
priority_support: true
Prices above are examples, not Atrium platform fees. amount_cents is an integer: 1200 represents
USD 12.00. Only an offering keyed free can declare zero-priced entries, and every price in that offering
must be zero. Other offerings require a positive amount.
Price and feature fields
| Field | Contract |
|---|---|
Offering key, price key |
Stable lowercase identifiers: letters, digits, hyphens, or underscores. |
Offering type |
subscription or one_time; see the one-time availability note below. |
prices[].currency |
Three-letter lowercase currency code. Confirm your intended currency before launch. |
prices[].interval |
Required for subscriptions: day, week, month, or year. Omit for one-time prices. |
prices[].interval_count |
Positive integer, default 1. month with 3 means every three months. |
trial_period_days |
Trial length on the offering; confirm the resulting checkout terms before publishing them. |
entitlements keys |
Lowercase names with underscores, such as pdf_exports. |
Use booleans for feature access. Use a non-negative integer for a monthly quota, or an object with
quantity and period: month|lifetime. Monthly usage resets at the beginning of the UTC calendar month,
not on each customer's billing anniversary. lifetime has no monthly reset.
Use the explicit string unlimited for an uncapped feature. Omitting an entitlement means it is absent
from the plan, not unlimited. Your application should display the plan's unlimited designation rather
than treating a large numeric balance as customer-facing plan copy.
Free still requires enrollment
Prefer an explicit zero-price subscription as above. Customers must install/enroll in that plan before subscription-protected routes or runtime entitlements become available.
Older manifests can contain a Free offering without prices for compatibility. That form does not create an enrollable billing catalog entry or automatically grant runtime entitlements. Do not use it for a new app that expects subscription access.
Catalog changes and deployment
A confirmed deployment synchronizes the billing catalog. Local validation and a deploy preview do not prove that catalog synchronization or customer enrollment succeeded. Check the deployment result and the public pricing page before announcing a pricing change.
Keep offering and price keys stable when changing labels. Changed prices can require new price records; removing an offering archives it for new purchases rather than canceling existing subscribers. Existing active subscriptions can continue to authorize access to archived offerings.
When choosing a default offering, synchronization prefers free, otherwise the first synchronized
offering. An offering without a default price starts with its first synchronized price. Do not assume
reordering prices migrates existing subscribers or changes an already-established default.
The public listing currently selects a plan's default price. Displaying another billing interval does not mean it is selectable there. Your application's checkout API request identifies an offering and price explicitly.
One-time offerings: limited availability
The manifest accepts type: one_time, with no price interval. The checkout API also recognizes this
type, but reliable one-time credit fulfillment and combined quota/credit consumption are not ready
for production use. Do not launch paid credit packs based on schema acceptance or a checkout URL alone.
Confirm readiness with Atrium before relying on this path.
Provider product/price IDs and resolved status are platform-managed. Do not put them or payment secrets
in atrium.yaml. Enforce features using the runtime billing APIs.