Skip to main content
This tutorial uses a document generation tool as an example to demonstrate how to implement per-use billing through Profy’s PER_USE billing model.

What You’ll Build

A document generation SaaS — every time a user performs a paid action, Profy automatically deducts the corresponding credits from their account:
  • Generate report (generate_report) → deducts 10 credits
  • Export PDF (export_pdf) → deducts 5 credits
  • Generate summary (generate_summary) → deducts 3 credits
The entire billing flow is handled by your application calling the SDK, with Profy guaranteeing idempotency and atomicity.

Prerequisites

Step 1: Configure Billing Events in Studio

Go to Profy Studio → Your App → Billing Events and add the following Meters:
Event names cannot be changed once created — use snake_case naming. Unit prices can be adjusted at any time and take effect immediately.

Step 2: Install and Initialize the SDK

Step 3: Implement Billing Reporting

When a user triggers a paid action, call reportEvent to report the billing event.
idempotencyKey is a required parameter (max 128 characters). The API returns a 400 error if it’s missing.
Response structure:

Step 4: Pre-Check Balance

Before performing expensive operations, check if the user has sufficient balance to avoid completing an operation only to discover the charge fails:
Pre-checking is only a UX optimization — the actual charge can still fail due to concurrent operations. Always handle InsufficientBalance errors.

Step 5: Handle Charge Failures

Error handling strategy:

Step 6: Idempotency Best Practices

idempotencyKey ensures the same business operation is never charged twice. When requests time out or encounter network issues, you can safely retry.

Idempotency Key Design Principles

Safe Retry Pattern

You must reuse the same idempotencyKey when retrying. Generating a new key for each retry will result in duplicate charges.

Complete Example

A complete implementation of a document generation service:

Billing Event Design Guide

Single Event vs Multiple Events

Naming Conventions

  • Use snake_case
  • Start with a verb: generate_, export_, analyze_
  • Avoid generic names (e.g., action, event)
  • Recommended length ≤ 32 characters

Granularity Decisions

A rule of thumb: if users perceive two operations as “one thing,” they should be a single event. If users would ask “why was I charged this much,” the granularity needs to be finer.

FAQ

Q: What happens if an idempotency key is reused? The API returns { idempotent_replay: true } and doesn’t charge again. The charged value reflects the original charge amount. Q: What if the balance runs out between pre-check and actual charge? reportEvent will return an InsufficientBalance error. Pre-checking is only a UX optimization and cannot replace proper error handling. Q: Which price applies when the unit price is changed after a request is sent? The latest unit price at the time the request arrives is used. Changes take effect immediately with no transition period. Q: Do idempotency keys expire? Yes. The same key is valid for 24 hours. After that, it’s treated as a new request. Q: What if one operation needs to charge multiple events? Call reportEvent sequentially. Use an independent idempotencyKey for each event. If one fails, previously charged events are not automatically refunded — it’s best to design a single event per user action whenever possible.

Next Steps

SDK Quick Start

OAuth authorization and basic event reporting

AI Metered Billing

Token-based billing for AI application integration

Invoke Platform Expert

Embed AI Expert capabilities in your App

API Reference

Complete Events API endpoint documentation