Skip to main content
Report custom billing events for App per-use (PER_USE) billing scenarios. Each event report deducts the corresponding credit amount from the authorized user’s account based on the Meter configuration.

Authentication

This endpoint only supports OAuth Bearer Tokens. API Key authentication will return a 401 error.Custom billing events deduct credits from the user’s account and must go through OAuth to ensure the user’s informed consent.

Request Body

string
required
Event name, must exactly match a Meter event name configured in the App. Maximum 100 characters.
string
required
Idempotency key to prevent duplicate charges. The same idempotency_key will not be charged twice. Maximum 128 characters.
object
Additional metadata as key-value pairs. Used to record extra business information without affecting billing.

Request Examples

Response

Normal Charge

Idempotent Replay

When the same idempotency_key is submitted again, no duplicate charge occurs:
idempotent_replay: true indicates this was an idempotent replay and credits were not deducted again.

Idempotency Guarantees

Always use meaningful idempotency keys. Recommended format: {entity}_{id}_{operation}, for example order_12345_gen_1.
  • Prevents duplicate charges from network retries — when clients retry on timeout, the same idempotency key ensures only one charge
  • Prevents duplicate charges from business logic — multiple calls for the same business operation will only charge once
  • Idempotency window — the same (app_uuid, idempotency_key) combination is permanently valid

How It Works

  1. Your App obtains user authorization through OAuth
  2. When the user uses a paid feature, call the Events API to report the event
  3. Profy looks up the corresponding credit price from the App’s Meter configuration
  4. Deducts the corresponding amount from the authorized user’s credits
  5. Returns the charge result and remaining balance

Daily Spending Cap

The platform enforces a daily spending cap per App × end user, defaulting to 500 credits/day (the app_daily_cap.daily_limit column default, adjustable per user). Once reached, subsequent event reports are rejected with HTTP 429, and the response carries a daily_limit field.
Two details that commonly trip people up:
  1. The reset boundary is UTC midnight, not local midnight. The comparison uses the date string from new Date().toISOString(), so for users in China the allowance resets at 08:00 Beijing time.
  2. The cap is isolated per end user, not a total across your App. One end user burning through their allowance does not affect your other users — and conversely, you cannot bypass a given user’s cap on the grounds that the App has headroom overall.

Error Codes

Next Steps

Meter Configuration

Query App Meter configurations

Build a Profy App

Complete App development guide