Plans
How service providers define and publish pricing on the Recur Plan Registry.
A Plan is the on-chain record that defines what a service costs. Service providers create plans and publish them to the Recur Plan Registry — a public, on-chain catalog on Solana mainnet. Once created, a plan can be discovered by any agent or client and used to initiate a subscription or authorize a payment.
Plan structure
interface Plan {
id: PublicKey; // On-chain plan address
provider: PublicKey; // Service provider wallet
name: string; // Display name, e.g. "Pro API — 10k calls/month"
amount: number; // Price in token base units (e.g. 49_000_000 = 49 USDC)
token: PublicKey; // SPL token mint address (USDC during beta)
interval: BillingInterval; // MONTHLY | WEEKLY | DAILY | PER_REQUEST
trialPeriodDays?: number; // Optional free trial length
meteredOverage?: {
unit: string; // e.g. "1000 tokens"
price: number; // Price per unit above the plan limit
};
}
Creating a plan
const plan = await recur.createPlan({
name: "Inference Pro",
amount: 49_000_000, // 49 USDC
interval: "MONTHLY",
trialPeriodDays: 7,
});
console.log(plan.id); // PublicKey — store this as your plan address
createPlan writes a Plan account to the Recur Plan Registry on Solana mainnet. The transaction is signed by your provider wallet. After confirmation, the plan is immediately discoverable by agents.
Billing intervals
| Interval | Description |
|---|---|
MONTHLY |
Billing cycle of 30 days |
WEEKLY |
Billing cycle of 7 days |
DAILY |
Billing cycle of 24 hours |
PER_REQUEST |
No recurring cycle; used for one-time or metered access |
Plan immutability
Plans are immutable once created. You cannot change the price, interval, token, or trial period of an existing plan.
This is intentional. When an agent or user subscribes to a plan, they authorize billing at specific terms. Mutating those terms after the fact would be a unilateral change to an on-chain contract. It would also make subscriptions impossible to audit transparently.
If you need to change pricing, create a new plan. Existing subscribers continue on the original plan until they cancel or are migrated. You control whether and when to migrate existing subscribers to a new plan.
Metered overage
For plans that include usage-based billing above a fixed quota, add a meteredOverage block:
const plan = await recur.createPlan({
name: "Compute Standard",
amount: 20_000_000, // 20 USDC base fee
interval: "MONTHLY",
meteredOverage: {
unit: "1000 tokens",
price: 2_000, // 0.002 USDC per 1k tokens above quota
},
});
Overage is billed through an Allowance that the service draws down as usage accumulates. The agent authorizes a total spend cap at subscription time.
Plan discovery
Agents and clients can find plans in two ways:
- From a
402response. When a service returns402 Payment Required, the response body includes the plan ID and terms. Agents can read these terms and decide whether to subscribe. - From the on-chain registry. Any Solana client can query the Plan Registry directly to enumerate a provider’s published plans.
See Payment Flows for how discovery works in practice.
Deprecating a plan
You cannot delete a plan, but you can mark it as deprecated to prevent new subscribers. Existing subscriptions on a deprecated plan continue to renew until cancelled.
await recur.deprecatePlan({ planId: plan.id });
After deprecation, the plan no longer appears in 402 responses from the payment gate middleware, but its on-chain account remains readable.