Usage-Based Billing Quick Start

Usage-based billing ties cost to consumption, charging customers only for what they actually use. Salable handles the Stripe webhook lifecycle for you, scopes usage to the right owner across multiple organisations, and prevents accidental duplicate subscriptions to the same meter. Salable also lets you combine metered and per-seat line items on a single subscription, meaning every member in the team contributes to the same meter.

Introduction

Usage-based billing means charging based on consumption. £0.01 per API call, £0.10 per GB of storage, and £0.05 per message sent are all examples of this billing model.

1. Create and configure your product

Before you can start implementing Salable into your codebase, you need to sign up for an account and create a product in the Salable dashboard.

You will need to create a product, the plans that you want the users to be able to subscribe to, and any entitlements your users should be able to access depending on their subscription.

As an example, if your application was an AI image generation tool, you may offer "Starter" and "Pro" plans, with high_resolution_exports, commercial_rights, and priority_processing as your entitlements.

To charge for usage on your "Pro" plan, set up a Line Item with a Pricing Type of "Metered". Create a Meter (like image_generations) and set your per-unit price.

To accept payment from a user, you will need to generate a checkout link.

import { Salable } from '@salable/sdk';
const salable = new Salable('secret-api-key');
 
const { data } = await salable.api.checkout.post({
    planId: 'plan_01KJWF3VM5HNQ3YRS27K06J64T',
    owner: 'user_123',
    grantee: 'user_123',
    interval: 'month',
    intervalCount: 1,
    currency: 'USD',
    successUrl: 'https://your-app.com/success',
    cancelUrl: 'https://your-app.com/cancel'
});
 
// Redirect user to data.url

Once the customer completes checkout, Salable automatically creates a Usage Record to track their consumption.

3. Record usage in your application

As users consume your service, record their usage to the appropriate meter. Usage recording returns immediately and processes in the background.

import { Salable } from '@salable/sdk';
const salable = new Salable('your-secret-key');
 
await salable.api.usage.record.post({
    owner: 'user_123',
    meterSlug: 'image_generations',
    increment: 1
});

Passing owner scopes consumption to a specific tenant. All users belonging to that owner contribute to the same meter, this is useful for plans that combine metered with per-seat line items. It also handles users who belong to multiple tenants: pass the right owner, and Salable applies the usage to the right meter.

4. Add entitlement checks to your application

In your application, you will only want to allow the grantee to perform certain actions if they have an active subscription.

We can check for a grantee's active entitlements as follows:

import { Salable } from '@salable/sdk';
const salable = new Salable('your-secret-key');
 
const { data } = await salable.api.entitlements.check.get({
    queryParameters: {
        granteeId: 'user_123'
    }
});
 
const granteeHasEntitlement = data.entitlements.find(e => e.value === 'image_generations');
 
if (granteeHasEntitlement) {
    // Allow the user to perform the action in your system.
}

Setting up Entitlements allows you to easily create tailored plans for your customers requirements. Copy any existing Plan, adjust its Entitlements and cost based on the agreed terms with the customer, and they immediately get the exact feature set you agreed without any code change. Now everything flows through Entitlements, sales can be instant.

5. Display usage to customers

You can retrieve current usage data to display in your application's dashboard.

import { Salable } from '@salable/sdk';
const salable = new Salable('your-secret-key');
 
const { data } = await salable.api.usageRecords.get({
    queryParameters: {
        owner: 'user_123',
        meterSlug: 'image_generations',
        status: ['current']
    }
});
 
const currentUsage = data[0]?.count || 0;

6. Next steps

Now that you have usage-based payment processing and entitlement checking set up in your application, there are some further things you should set up to enable full subscription handling: