flowglad-usage-tracking
Adds metered billing and usage tracking to monitor API calls and consumption-based costs.
Install
mkdir -p .claude/skills/flowglad-usage-tracking && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/6850" && unzip -o skill.zip -d .claude/skills/flowglad-usage-tracking && rm skill.zipInstalls to .claude/skills/flowglad-usage-tracking
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Implement usage-based billing with Flowglad including recording usage events, checking balances, and displaying usage information. Use this skill when adding metered billing, tracking API calls, or implementing consumption-based pricing.Key capabilities
- →Record metered usage events for billing
- →Perform pre-check balance validation
- →Manage transaction idempotency
- →Display real-time consumption progress bars
How it works
Hooks into usage meters via the Flowglad SDK to track consumption and verify available credit balances before authorizing resource-intensive operations.
Inputs & outputs
When to use flowglad-usage-tracking
- →Tracking API usage for billing
- →Implementing consumption-based pricing
- →Checking user credit balances
- →Preventing double-charging usage
About this skill
Usage Tracking
Abstract
This skill covers implementing usage-based billing with Flowglad, including recording usage events for metered billing, checking usage balances, and displaying usage information to users. Proper implementation ensures accurate billing and prevents users from bypassing usage charges.
Table of Contents
- Recording Usage Events — CRITICAL
- Usage Meter Resolution — HIGH
- Idempotency with transactionId — HIGH
- Pre-Check Balance Before Expensive Operations — MEDIUM
- Display Patterns for Usage — MEDIUM
- Handling Exhausted Balance — MEDIUM
- 6.1 Graceful Degradation
- 6.2 Upgrade Prompts
1. Recording Usage Events
Impact: CRITICAL
Flowglad supports recording usage events from both client-side and server-side code. Each approach has different APIs and trade-offs.
1.1 Client-Side Recording
Impact: CRITICAL (simplest approach for many use cases)
Use useBilling().createUsageEvent for client-side usage tracking. The client SDK provides smart defaults that simplify implementation.
Client-side smart defaults:
amountdefaults to1transactionIdis auto-generated for idempotencysubscriptionIdis auto-inferred from current subscription
Basic client-side usage:
'use client'
import { useBilling } from '@flowglad/nextjs'
function RecordUsageButton({ usageMeterSlug }: { usageMeterSlug: string }) {
const billing = useBilling()
const handleClick = async () => {
if (!billing.createUsageEvent) return
const result = await billing.createUsageEvent({
usageMeterSlug,
// amount defaults to 1
// transactionId auto-generated
// subscriptionId auto-inferred
})
if ('error' in result) {
console.error('Failed to record usage:', result.error)
return
}
console.log('Usage recorded:', result.usageEvent.id)
}
return <button onClick={handleClick}>Use Feature</button>
}
With explicit values:
const result = await billing.createUsageEvent({
usageMeterSlug: 'api-calls',
amount: 5, // Override default of 1
// transactionId and subscriptionId still auto-handled
})
Important: Client-side usage events do not automatically refresh billing data. Call billing.reload() after recording if you need to update displayed balances.
await billing.createUsageEvent({ usageMeterSlug: 'generations' })
await billing.reload() // Refresh to show updated balance
1.2 Server-Side Recording
Impact: CRITICAL (required for atomic operations)
Use flowglad(userId).createUsageEvent for server-side usage tracking. Server-side requires explicit values for all parameters.
Server-side required parameters:
subscriptionId- must be provided explicitlytransactionId- must be provided explicitlyamount- must be provided explicitly
Basic server-side usage:
// API route - app/api/generate/route.ts
import { flowglad } from '@/lib/flowglad'
import { auth } from '@/lib/auth'
export async function POST(req: Request) {
const session = await auth()
if (!session?.user?.id) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
// Get billing to find subscriptionId
const billing = await flowglad(session.user.id).getBilling()
const subscriptionId = billing.currentSubscription?.id
if (!subscriptionId) {
return Response.json({ error: 'No active subscription' }, { status: 402 })
}
// Perform the operation
const result = await generateContent()
// Record usage with explicit parameters
await flowglad(session.user.id).createUsageEvent({
usageMeterSlug: 'generations',
amount: 1,
subscriptionId,
transactionId: `gen_${result.id}`,
})
return Response.json(result)
}
1.3 Choosing Client vs Server
Impact: CRITICAL (architectural decision)
Both approaches are valid. Choose based on your needs:
| Use Case | Recommended Approach | Why |
|---|---|---|
| Simple button click tracking | Client-side | Smart defaults make it easy |
| Feature usage counters | Client-side | No server round-trip needed |
| AI generation / expensive operations | Server-side | Track atomically with operation |
| API endpoint metering | Server-side | Already on server |
| Operations that cost you money | Server-side | Ensure tracking happens |
| Quick prototyping | Client-side | Fewer files to create |
Pattern: Atomic server-side tracking
When an operation costs you money (e.g., calling OpenAI), track usage atomically with the operation:
export async function POST(req: Request) {
const session = await auth()
const billing = await flowglad(session.user.id).getBilling()
// 1. Check balance first
const balance = billing.checkUsageBalance('generations')
if (!balance || balance.availableBalance <= 0) {
return Response.json({ error: 'No credits' }, { status: 402 })
}
// 2. Perform expensive operation
const result = await openai.images.generate({ prompt })
// 3. Record usage (atomic with operation)
await flowglad(session.user.id).createUsageEvent({
usageMeterSlug: 'generations',
amount: 1,
subscriptionId: billing.currentSubscription!.id,
transactionId: `gen_${result.data[0].url}`,
})
return Response.json(result)
}
Pattern: Simple client-side tracking
For tracking feature usage where bypassing isn't a concern:
function FeatureButton() {
const billing = useBilling()
const handleUse = async () => {
// Track usage - smart defaults handle the rest
await billing.createUsageEvent({ usageMeterSlug: 'feature-uses' })
await billing.reload()
// Do the feature thing
}
return <button onClick={handleUse}>Use Feature</button>
}
2. Usage Meter Resolution
Impact: HIGH
When creating usage events, you can identify the usage price by slug or ID. Understanding how these resolve helps you structure your billing correctly.
2.1 Using usageMeterSlug vs priceSlug
Impact: HIGH (determines which price is charged)
You can identify usage with exactly one of:
priceSlugorpriceId- targets a specific price directlyusageMeterSlugorusageMeterId- resolves to the meter's default price
Using priceSlug (explicit):
await createUsageEvent({
priceSlug: 'api-calls-standard', // Specific price
amount: 1,
// ...
})
Using usageMeterSlug (resolves to default):
await createUsageEvent({
usageMeterSlug: 'api-calls', // Resolves to meter's default price
amount: 1,
// ...
})
When using usageMeterSlug, the system uses the meter's configured default price. If no custom default is set, it uses the auto-generated no-charge price.
2.2 Default No-Charge Prices
Impact: HIGH (understanding automatic pricing)
Every usage meter automatically has a no-charge price with:
- Slug pattern:
{usagemeterslug}_no_charge - Unit price:
$0.00(always free) - Cannot be archived or deleted
This means you can start tracking usage immediately without creating a price first:
// Works even if no custom price exists for 'api-calls' meter
await createUsageEvent({
usageMeterSlug: 'api-calls',
amount: 1,
// Resolves to 'api-calls_no_charge' if no other default is set
})
When you need paid usage:
- Create a usage price in your Flowglad dashboard (e.g.,
api-calls-standardat $0.001/call) - Set it as the default price for the meter, OR
- Reference it directly with
priceSlug: 'api-calls-standard'
Checking which price was used:
The response from createUsageEvent always includes the resolved priceId:
const result = await createUsageEvent({ usageMeterSlug: 'api-calls', amount: 1 })
if (!('error' in result)) {
console.log('Charged to price:', result.usageEvent.priceId)
}
3. Idempotency with transactionId
Impact: HIGH
Network failures and retries can cause duplicate usage events. Always include a transactionId to ensure each logical operation is only billed once.
3.1 Preventing Double-Charging
Impact: HIGH (prevents billing disputes and customer trust issues)
Without idempotency, a network timeout followed by a retry could charge the user twice for the same operation.
Incorrect: no idempotency key
// API route
export async function POST(req: Request) {
const session = await auth()
const result = await generateImage(prompt)
// If this request times out and retries, user gets double-charged!
await flowglad(session.user.id).createUsageEvent({
usageMeterSlug: 'image-generations',
amount: 1,
})
return Response.json(result)
}
**Correct: always include transacti
Content truncated.
When not to use it
- →Managing fixed-cost recurring subscriptions
- →Storing sensitive user payment details
Prerequisites
Limitations
- →Requires reliable transaction IDs
- →Limited to predefined usage meters defined in Flowglad
How it compares
It automates consumption-based billing logic that handles idempotency to prevent overcharging.
Compared to similar skills
flowglad-usage-tracking side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| flowglad-usage-tracking (this skill) | 1 | 6mo | No flags | Intermediate |
| billing-automation | 10 | 2mo | No flags | Intermediate |
| plaid-fintech | 3 | 6mo | No flags | Advanced |
| payment-integration | 1 | 6mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by flowglad
View all by flowglad →You might also like
billing-automation
wshobson
Build automated billing systems for recurring payments, invoicing, subscription lifecycle, and dunning management. Use when implementing subscription billing, automating invoicing, or managing recurring payment systems.
plaid-fintech
davila7
Expert patterns for Plaid API integration including Link token flows, transactions sync, identity verification, Auth for ACH, balance checks, webhook handling, and fintech compliance best practices. Use when: plaid, bank account linking, bank connection, ach, account aggregation.
payment-integration
mrgoonie
Integrate payments with SePay (VietQR), Polar, Stripe, Paddle (MoR subscriptions), Creem.io (licensing). Checkout, webhooks, subscriptions, QR codes, multi-provider orders.
pi-payments
aaaa47080
Pi Network payment integration - three-phase payment flow, createPayment, server-side approve/complete, PaymentDTO. Use when implementing or debugging Pi payments.
payment-integration
wegonbeok45
Integrate Stripe, PayPal, and payment processors. Handles checkout flows, subscriptions, webhooks, and PCI compliance. Use PROACTIVELY when implementing payments, billing, or subscription features.
kisautotrade-kis-api
CountJung
Korea Investment Securities KIS Open API bridge for Codex in the repository-owned trading app. Use for authentication, TR-ID, REST/WebSocket endpoints, order, balance, execution, overseas stock, paper trading, API errors, and official sample verification.