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:

  1. From a 402 response. When a service returns 402 Payment Required, the response body includes the plan ID and terms. Agents can read these terms and decide whether to subscribe.
  2. 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.