Skip to main content
Prepaid pricing lets customers pay for a fixed quantity of a feature upfront. They select how many units they want at purchase time, pay immediately, and their balance is decremented as they use it. This is in contrast to usage-based pricing, where customers are billed for actual usage at the end of a billing cycle.
Example
An AI platform has a Pro plan at $20/month that includes:
  • API Credits: 500 included for free, then $10 per 1,000 credits per month (consumable)
  • Seats: 3 included for free, then $5 per seat per month (non-consumable)
A customer selects 3,000 credits and 10 seats. They pay $20 base + $25 for 2,500 extra credits + $35 for 7 extra seats = $80/month.

Setting up

Create your features and add them to a plan with prepaid prices:
autumn.config.ts
import { feature, item, plan } from 'atmn';

export const apiCredits = feature({
  id: 'api_credits',
  name: 'API Credits',
  type: 'metered',
  consumable: true,
});

export const seats = feature({
  id: 'seats',
  name: 'Seats',
  type: 'metered',
  consumable: false,
});

export const pro = plan({
  id: 'pro',
  name: 'Pro',
  price: { amount: 20, interval: 'month' },
  items: [
    item({
      featureId: apiCredits.id,
      included: 500,
      price: {
        amount: 10,
        billingUnits: 1000,
        billingMethod: 'prepaid',
        interval: 'month',
      },
    }),
    item({
      featureId: seats.id,
      included: 3,
      price: {
        amount: 5,
        billingMethod: 'prepaid',
        interval: 'month',
      },
    }),
  ],
});
Push changes with atmn push.

How it works

When a plan has prepaid features, customers select a quantity at purchase time. This quantity determines:
  • How many units are granted as their balance
  • How much they’re charged, based on the price and billing units
The quantity is the total number of feature units the customer will receive, including any included amount. Using our example plan:
  • A customer selects 3,000 API credits. 500 are included, so they pay for 2,500 → $10 × (2,500 / 1,000) = $25/month for credits.
  • The same customer selects 10 seats. 3 are included, so they pay for 7 → $5 × 7 = $35/month for seats.
If you pass a quantity equal to or less than the included amount, the customer gets the included amount and pays nothing extra for that feature.

Passing feature_quantities

When attaching a plan or updating a subscription that contains prepaid features, use the feature_quantities parameter to specify how many units the customer wants.

Attaching a plan

Pass a feature_quantities entry for each prepaid feature on the plan:
import { Autumn } from "autumn-js";

const autumn = new Autumn({ secretKey: "am_sk_..." });

const { data } = await autumn.billing.attach({
  customerId: "user_123",
  planId: "pro",
  featureQuantities: [
    { featureId: "api_credits", quantity: 3000 },
    { featureId: "seats", quantity: 10 },
  ],
});

Updating a subscription

To change prepaid quantities on an existing subscription, use billing.update. For example, to add more seats mid-cycle:
await autumn.billing.update({
  customerId: "user_123",
  planId: "pro",
  featureQuantities: [
    { featureId: "api_credits", quantity: 3000 },
    { featureId: "seats", quantity: 15 },
  ],
});
See Updating Subscriptions for more on previewing changes. When quantities change mid-cycle, Autumn can prorate the charge — see Proration for configuration options.

Understanding prepaid balances

Once a customer is attached to a plan with prepaid features, their balance breakdown distinguishes between what was included for free and what was purchased.
FieldDescription
included_grantThe amount granted by the plan for free — the “included” amount configured on the plan item.
prepaid_grantThe amount purchased via feature_quantities — the quantity minus the included amount.
grantedTop-level total: included_grant + prepaid_grant summed across all breakdown items.
remainingHow much is left to use.
usageHow much has been consumed.
Using the plan from our setup, a customer who attaches with 3,000 credits and 10 seats will have:
{
  "api_credits": {
    "feature_id": "api_credits",
    "granted": 3000,
    "remaining": 3000,
    "usage": 0,
    "unlimited": false,
    "overage_allowed": false,
    "breakdown": [
      {
        "id": "cus_ent_abc123",
        "plan_id": "pro",
        "included_grant": 500,
        "prepaid_grant": 2500,
        "remaining": 3000,
        "usage": 0,
        "reset": {
          "interval": "month",
          "resets_at": 1773851121437
        },
        "price": {
          "amount": 10,
          "billing_units": 1000,
          "billing_method": "prepaid"
        },
        "expires_at": null
      }
    ]
  },
  "seats": {
    "feature_id": "seats",
    "granted": 10,
    "remaining": 10,
    "usage": 0,
    "unlimited": false,
    "overage_allowed": false,
    "breakdown": [
      {
        "id": "cus_ent_def456",
        "plan_id": "pro",
        "included_grant": 3,
        "prepaid_grant": 7,
        "remaining": 10,
        "usage": 0,
        "reset": null,
        "price": {
          "amount": 5,
          "billing_units": 1,
          "billing_method": "prepaid"
        },
        "expires_at": null
      }
    ]
  }
}
Use the check endpoint before allowing a customer to use a prepaid feature, and track usage afterwards to decrement their balance.

Prepaid vs usage-based

PrepaidUsage-based
When chargedUpfront at purchaseEnd of billing cycle
Customer selects quantityYes, via feature_quantitiesNo
Balance behaviorDecremented as usage occursAccumulated and billed
Best forCredits, top-ups, seat licensesMetered APIs, storage, bandwidth