Metered Billing

    Learn how to record usage and bill for it at the end of a subscription period.

    Metered billing is useful in cases where you want to charge your customers a granular amount based on their consumption of your service during the billing cycle instead of explicitly setting quantities. If you are running an email service SaaS business, for example, you can track your customers’ API calls and bill them for the total number used at the end of each month.

    Creating a metered billing plan

    To use metered billing, create a new plan, configure it with metered as the usage_type, and attach it to an existing product. Specify the desired amount, interval, and currency. With a metered plan, the amount is billed per unit of consumption. Note that we also support tiered pricing, which means we can dynamically adjust the price per unit depending on the total amount of units sold within a period.

    curl https://api.stripe.com/v1/plans \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=3000 \
       -d interval=month \
       -d product=prod_BljM5US9aCw4AY \
       -d currency=usd \
       -d usage_type=metered
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    plan = Stripe::Plan.create({
        currency: 'usd',
        interval: 'month',
        product: 'prod_CHxGUqw1dyKsDM',
        nickname: 'Pro Plan',
        amount: 3000,
        usage_type: 'metered',
    })
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    plan = stripe.Plan.create(
      currency='usd',
      interval='month',
      product='prod_CHxGUqw1dyKsDM',
      nickname='Pro Plan',
      amount=3000,
      usage_type='metered',
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    $plan = \Stripe\Plan::create([
        'currency' => 'usd',
        'interval' => 'month',
        'product' => 'prod_CHxGUqw1dyKsDM',
        'nickname' => 'Pro Plan',
        'amount' => 3000,
        'usage_type' => 'metered',
    ]);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> params = new HashMap<>();
    params.put("currency", "usd");
    params.put("interval", "month");
    params.put("product", "prod_CHxGUqw1dyKsDM");
    params.put("nickname", "Pro Plan");
    params.put("amount", 3000);
    params.put("usage_type", "metered");
    Plan plan = Plan.create(params);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    const plan = stripe.plans.create({
      currency: 'usd',
      interval: 'month',
      product: 'prod_CHxGUqw1dyKsDM',
      nickname: 'Pro Plan',
      amount: 3000,
      usage_type: 'metered',
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    params := &stripe.PlanParams{
        Currency: "usd",
        Interval: "month",
        Product: "prod_CHxGUqw1dyKsDM",
        Nickname: "Pro Plan",
        Amount: 3000,
        UsageType: "metered",
    }
    pro, _ := plan.New(params)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    var options = new StripePlanCreateOptions {
        Currency = "usd",
        Interval = "month",
        Nickname = "Pro Plan",
        Amount = 3000,
        Product = "prod_CHxGUqw1dyKsDM",
        UsageType = "metered",
    };
    var service = new StripePlanService();
    StripePlan plan = service.Create(options);
    

    To subscribe a customer to the plan, create or update a subscription via the API endpoint and do not specify a quantity—metered billing doesn’t use the subscription item quantity attribute. When you create the subscription, Stripe returns the subscription item record, which includes an ID. You should save this ID and associate it with the user, because it is used for usage reporting.

    Reporting usage

    In order for Stripe to compute the number of units consumed during the billing cycle, you must report the customer’s usage by creating usage records on the subscription item, with the ID that you saved in the previous step.

    The Usage API call includes a timestamp, quantity, and action. The increment action adds the quantity to the usage total for the specified timestamp. The set action overwrites the usage for the specified timestamp. Stripe recommends reporting usage for the current timestamp using the increment action, even if you aggregate usage yourself and report usage once a day. Reserve the set action for the unusual case where you need to make a usage adjustment. Note that reporting usage outside of the current billing interval results in an error. Stripe leaves a five minute window around the period end to allow for clock drift.

    curl https://api.stripe.com/v1/subscription_items/{{SUBSCRIPTION_ITEM_ID}}/usage_records \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -X POST \
       -d quantity=100 \
       -d timestamp=1522893428 \
       -d action=increment
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    Stripe::UsageRecord.create(
      quantity: 100,
      timestamp: 1522893428,
      subscription_item: '{{SUBSCRIPTION_ITEM_ID}}',
      action: 'increment'
    )
    
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    stripe.UsageRecord.create(
      quantity=100,
      timestamp=1522893428,
      subscription_item='{{SUBSCRIPTION_ITEM_ID}}',
      action='increment'
    )
    
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    StripeUsageRecord::create(array(
      "quantity" => 100,
      "timestamp" => 1522893428,
      "subscription_item" => "{{SUBSCRIPTION_ITEM_ID}}",
      "action" => "increment"
    ));>
    
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> usageRecordParams = new HashMap<String, Object>();
    usageRecordParams.put("quantity", 100);
    usageRecordParams.put("timestamp", 1522893428);
    usageRecordParams.put("subscription_item", "{{SUBSCRIPTION_ITEM_ID}}");
    usageRecordParams.put("action", "increment");
    
    UsageRecord.create(usageRecordParams);
    
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    stripe.usageRecords.create({
      quantity: 100,
      timestamp: 1522893428,
      subscription_item: "{{SUBSCRIPTION_ITEM_ID}}",
      action: "increment"
    });
    
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    endpoint, err := usagerecord.New(&stripe.UsageRecordParams{
      Quantity: 100,
      Timestamp: 1522893428,
      SubscriptionItem: "{{SUBSCRIPTION_ITEM_ID}}",
      action: "increment"
    })
    
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    StripeConfiguration.SetApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    var usageRecordOptions = new StripeUsageRecordCreateOptions() {
      Quantity = 100,
      Timestamp = 1522893428,
      SubscriptionItem = "{{SUBSCRIPTION_ITEM_ID}}",
      Action = "increment"
    };
    var usageRecordService = new StripeUsageRecordService();
    StripeUsageRecord usageRecord = usageRecordService.Create(usageRecordOptions)
    
    

    Note: Using an idempotency key lets you safely re-report usage in the event of intermittent API errors.

    At the end of a subscription period, Stripe automatically totals and invoices for all usage for the billing period. Note that once the invoice is submitted, it cannot be changed. The usage reporting endpoint is rate-limited, so you might need to exercise caution and avoid making too many separate usage records.

    When canceling a subscription at the end of the period, any usage reported before the subscription ends is billed in a final invoice at the end of the period. Canceling a subscription immediately does not bill for any usage accrued during the final billing cycle.

    Retrieving current usage

    To retrieve total usage for the current period you can retrieve the upcoming invoice for the subscription. The usage is reflected as the quantity of the invoice item for a subscription_item.

    Questions?

    We're always happy to help with code or other questions you might have! Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.