Skip to main content
A plan is pricing you attach to a product. It is a single type with an ordered 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

Plans live on the product. There is no separate plans collection, no plan 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 on kind. 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 missing limit is pay-as-you-go (every counted item is billed). It is not unlimited.

entitlement

A feature flag or numeric benefit on the plan. The console label is Benefit. The wire kind stays entitlement.

trial

discount

rollover

What happens to unused included usage at period end.

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

A $0 flat charge plus autoAssigned is a free recurring fallback.

Usage-based — per-unit charge, no billing cycle

amountMinor: 2 is $0.02 per request. 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

A tier 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.
Every band in a group shares one 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: "charge" so exceeding the included count bills rather than blocks. Tiered usage on a recurring plan bills at the end of each billing period. On a plan with no billing cycle it is charged in real time against the credit balance.

Hybrid — recurring fee plus metered usage

Bands replace the flat per-unit charge rather than joining it — a meter is priced one way or the other. The derived label is still 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 to options[]:

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. Send options[]. Do not send type, creditsPerUnit, basePrice, setupFee, or freeUnits. PUT replaces the full options[] when you send it.

Plans and MCP servers

  • Server default plandefaultPlanRef on 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
When plans change, MCP server configurations sync automatically.

Purchase snapshots

A purchase freezes the plan’s options[] 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