options[] list. What a plan “is” — recurring, usage-based, hybrid, or one-time — is a derived label, not a field you send.
Console templates (Recurring, Usage-based, One-time, Hybrid, Blank) only seed that list. They are not persisted types.
Money on options is integer minor units of the option’s currency (cents for USD). Usage rates in the console are money per meter noun ($0.02 / request). Credits are only the prepaid wallet — see Plans and billing glossary.
How a plan is stored
type discriminator, and no subtype fields such as setupFee, creditsPerUnit, basePrice, or freeUnits.
planType on some responses is a back-compat label for analytics and UI. Do not send type when you create or update a plan.
Option catalog
Each option is discriminated onkind. Optional label is allowed on every kind.
charge
A price. per is flat, unit, or seat. Per-unit charges require meter.
A plan offers several currencies by holding multiple charges of the same role that differ only by
currency. Amounts are set per currency, not FX-converted.
billingCycle
Makes the plan recurring. Omit it for one-time or pay-as-you-go usage.
tier
Volume or graduated rates for a meter. The embedded charge is per-unit. One
option per band — see Tiered for a worked
example and for how the two modes differ.
limit
Included cap for a meter. Copy says included. cap: 0 means unlimited.
A limit needs a
billingCycle. Pay-as-you-go (no cycle) cannot carry included usage. A missing limit means every counted item is paid from prepaid credits. It is not unlimited.
onExceed is what happens after the included count:
blockstops access. The denial offers the product’s other plans, and checkout opens on the plan the customer picksdraw_creditsdraws prepaid credits for usage past the cap, and refuses the next request when the balance cannot cover one unit
onExceed: "top_up" and "charge" and stores both as draw_credits.
entitlement
A feature flag or numeric benefit on the plan. The console label is Benefit. The wire kind stays entitlement.
trial
convert moves the customer onto the plan’s paid terms. cancel ends access. A reverse trial is cancel plus an auto-assigned free plan on the product, so the customer stays on the free tier when the trial ends.
discount
Markers
Markers are catalog metadata. They do not change pricing math.
Common compositions
These labels are derived. Send the options, not"type": "…".
Recurring — flat charge + billing cycle
autoAssigned is a free recurring fallback.
Usage-based — per-unit charge, no billing cycle
amountMinor: 2 is $0.02 per request. This plan has no billing cycle and no included cap. Do not send creditsPerUnit as a plan field.
Minimum top-up is a provider setting (minTopUpMinor in SolvaPay Console settings), not a plan option. See Auto-recharge.
Tiered — banded rates for one meter
Atier option is one band. Send one per band, contiguous and covering the whole
range: each band’s from is the previous band’s to, the first starts at 0,
and exactly one band — the last — sets to: null for everything above it.
mode, and the two modes price the same usage
differently. For 1,500 requests against the plan above:
Group bands by meter. A plan can tier two meters by sending two groups, each
contiguous in its own
charge.meter. Bands are grouped by that meter, never by
their position in options[].
A meter is priced by bands or by a charge with per: "unit" — not both.
Both are per-request prices on the same requests, so sending both is rejected.
Bands and limit compose: the cap is the included count, and the bands price
the overage above it. A plan with "cap": 1000 and the bands above includes the
first 1,000 requests and prices request 1,001 onward from the band it lands in.
Set onExceed: "draw_credits" so usage past the included count is paid from prepaid
credits rather than blocked.
Tiered usage is paid from the credit balance as each request is served, on a
recurring plan and on a plan with no billing cycle alike.
Hybrid — recurring fee plus metered usage
hybrid when a billing cycle and a meter are both present.
One-time — flat charge, no cycle
Identity fields
These sit on the plan next tooptions[]:
Hidden and auto-assigned plans
Add{ "kind": "hidden" } to keep a plan off checkout, the SDK catalog, and MCP. Customers cannot self-select it. Assign it from the SolvaPay Console customer page. Direct assignment stamps the purchase with admin_assignment.
Add { "kind": "autoAssigned" } to make the plan the product fallback (MCP tool access when no tool-specific plan is set, and new-customer pre-selection). Setting a new auto-assigned plan clears the marker on the previous one.
Plans are embedded in products
A product owns its plans. Create, update, and delete them through the product. Plan references are globally unique.Plan API
All plan endpoints are scoped to a product. Sendoptions[]. Do not send type, creditsPerUnit, basePrice, setupFee, or freeUnits.
PUT replaces the full options[] when you send it.
Plans and MCP servers
- Server default plan —
defaultPlanRefon an MCP server uses the product’s auto-assigned plan when no tool-specific plan is set - Per-tool plan assignments — tools can reference plans via
planIds
Purchase snapshots
A purchase freezes the plan’soptions[] at buy time. Changing the live plan does not change existing purchases.
price and planType on the snapshot are derived from those options.
Next steps
- Billing — cycles, usage, trials, and renewals
- Plans and billing glossary — credits, meter noun, included vs wallet remaining
- Usage events — record usage from the TypeScript SDK