A Plan is the on-chain record describing what a service charges. A provider creates one and publishes it to the HoodLayer Plan Registry, a public catalog that lives on Robinhood Chain mainnet. From that point on, any agent or client can find the plan and use it to start a subscription or authorize a payment.

Plan structure

interface Plan {
  id: string;                // On-chain plan id
  provider: Address;         // 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: Address;            // Token contract 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 hoodlayer.createPlan({
  name: "Inference Pro",
  amount: 49_000_000,    // 49 USDC
  interval: "MONTHLY",
  trialPeriodDays: 7,
});

console.log(plan.id);    // store this as your plan id

Calling createPlan writes a plan record into the HoodLayer Plan Registry on Robinhood Chain mainnet. Your provider wallet signs the transaction. Once it confirms, agents can discover the plan right away.

Billing intervals

Interval Description
MONTHLY A 30-day billing cycle
WEEKLY A 7-day billing cycle
DAILY A 24-hour billing cycle
PER_REQUEST No recurring cycle; for one-time or metered access

Plan immutability

Once created, a plan can’t be edited. The price, interval, token, and trial period of an existing plan are all fixed.

That’s deliberate. Subscribing to a plan means authorizing billing at particular terms, and rewriting those terms afterward would be a one-sided change to an on-chain contract. It would also break any hope of auditing subscriptions transparently.

Need different pricing? Publish a new plan. Anyone already subscribed stays on the original until they cancel or get migrated, and whether (and when) to move existing subscribers over is entirely your call.

Metered overage

If a plan bills for usage beyond a fixed quota, include a meteredOverage block:

const plan = await hoodlayer.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 charges flow through an Allowance that the service draws against as usage adds up. The agent authorizes a total spend cap when it subscribes.

Plan discovery

There are two ways for agents and clients to find plans:

  1. From a 402 response. A service that returns 402 Payment Required includes the plan ID and its terms in the response body. An agent can look at those terms and decide whether subscribing is worth it.
  2. From the on-chain registry. The Plan Registry is queryable by any Robinhood Chain client, so a provider’s published plans can be enumerated directly.

See Payment Flows for what discovery looks like in practice.

Deprecating a plan

Plans can’t be deleted, but marking one as deprecated stops new subscribers from joining. Anyone already subscribed to a deprecated plan keeps renewing until they cancel.

await hoodlayer.deprecatePlan({ planId: plan.id });

Once deprecated, the plan stops showing up in 402 responses from the payment gate middleware. Its on-chain record stays readable, though.