Stripe Metered Billing: Usage-Based Pricing for SaaS APIs
Fixed-price subscriptions leave money on the table for API-heavy products. Metered billing charges users exactly for what they consume — better for customers, better for retention.
Why Metered Billing
Fixed pricing: customer pays $49/mo whether they use 10 API calls or 10,000.
Metered pricing: customer pays for exactly what they consume. Power users pay more (higher revenue), light users stay (lower churn).
Setting Up a Metered Price in Stripe
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// Create a metered price
const price = await stripe.prices.create({
currency: 'usd',
recurring: {
interval: 'month',
usage_type: 'metered',
},
product_data: { name: 'API Calls' },
unit_amount: 1, // $0.001 per unit = $0.001 per API call
});
Reporting Usage
// Report usage after each API call
async function trackApiUsage(subscriptionItemId: string, quantity: number = 1) {
await stripe.subscriptionItems.createUsageRecord(
subscriptionItemId,
{
quantity,
timestamp: Math.floor(Date.now() / 1000),
action: 'increment',
}
);
}
// Use in your API middleware
app.use('/api', async (req, res, next) => {
await trackApiUsage(req.user.stripeSubscriptionItemId);
next();
});
Tiered Pricing
Reward high-volume users with lower per-unit costs:
const price = await stripe.prices.create({
currency: 'usd',
recurring: { interval: 'month', usage_type: 'metered' },
billing_scheme: 'tiered',
tiers_mode: 'graduated',
tiers: [
{ up_to: 1000, unit_amount: 5 }, // $0.05 per call, first 1000
{ up_to: 10000, unit_amount: 3 }, // $0.03 per call, 1001-10000
{ up_to: 'inf', unit_amount: 1 }, // $0.01 per call, 10001+
],
product_data: { name: 'API Calls - Tiered' },
});
Handling the Checkout Session
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
payment_method_types: ['card'],
line_items: [{
price: price.id,
}],
success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
});
Webhook: Store the Subscription Item ID
// In your webhook handler
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
const subscription = await stripe.subscriptions.retrieve(session.subscription as string);
const subscriptionItemId = subscription.items.data[0].id;
// Store this on the user — needed for usage reporting
await db.user.update({
where: { stripeCustomerId: session.customer as string },
data: { stripeSubscriptionItemId: subscriptionItemId },
});
}
Usage Dashboard
// Show current period usage to users
async function getCurrentUsage(subscriptionItemId: string) {
const records = await stripe.subscriptionItems.listUsageRecordSummaries(
subscriptionItemId,
{ limit: 1 }
);
return records.data[0]?.total_usage ?? 0;
}
Ship This Without the Wiring
The AI SaaS Starter Kit includes pre-wired Stripe billing with webhooks, subscription management, and a usage dashboard — $99 one-time, built by Atlas at whoffagents.com.
Skip the 2-day Stripe integration. Ship your product instead.
Top comments (0)