# Usage Based Billing Usage based billing in Credyt operates on a **real-time, prepaid model**. Customers maintain a wallet balance - funded through manual top-ups, automatic recharges, or credit entitlements bundled in a subscription - and each usage event immediately debits that balance as it occurs. Invoicing Credyt does not meter usage and bill in arrears (post-usage invoicing). All usage-based pricing operates on real-time wallet deductions. If your model requires post-period invoicing, see our [Pricing Guide](https://docs.credyt.ai/pricing-guide.md) to evaluate whether Credyt is the right fit. For payment collection, top-up flows, and managing customer wallet balances, see [Wallets and Topups](https://docs.credyt.ai/features/wallets-and-topups.md). ## How It Works[​](#how-it-works "Direct link to How It Works") Every customer in Credyt has a wallet. When a customer is subscribed to a usage-based product, Credyt automatically provisions the wallet accounts required by that product's pricing configuration. As your platform sends usage events, Credyt matches each event to the customer's active subscription, applies the correct pricing logic, and debits the balance in real time. Wallets can hold balances in standard currencies (USD, EUR) or in any custom asset you define — tokens, credits, compute minutes. Both approaches use the same product and event structure; the only difference is what asset the pricing is denominated in. For a detailed look at funding wallets, managing balances, and accepting payments, see [Wallets and Topups](https://docs.credyt.ai/features/wallets-and-topups.md). ## Billing in Fiat and Custom Units[​](#billing-in-fiat-and-custom-units "Direct link to Billing in Fiat and Custom Units") You can price usage in a standard currency or in a custom asset. The choice is made in the product's pricing configuration and determines which wallet account is debited when usage is reported. **Fiat pricing** — Usage is deducted directly in currency terms (e.g. $1.00 per video minute). Transparent and straightforward to reconcile. A good default for developer-facing products where customers expect to see dollar costs. **Custom units** — Usage is deducted in abstract units like tokens, credits, or minutes (e.g. 10 credits per video generated). You define the asset and its exchange rate against fiat; Credyt applies the rate automatically when customers top up. Custom units give you flexibility to abstract away infrastructure costs and create consumer-friendly pricing experiences. A single customer wallet can hold accounts in multiple assets simultaneously. See [Assets](https://docs.credyt.ai/features/assets.md) for more details on asset configuration. ## Usage Calculation Modes[​](#usage-calculation-modes "Direct link to Usage Calculation Modes") The `usage_calculation` configuration on a product price determines how Credyt interprets each incoming event. Three modes are supported: | Mode | How it bills | Typical use cases | | ----------------- | ----------------------------------------------------------------------- | ------------------------------------------------- | | `unit` | Charges a fixed amount per event occurrence | Video promotions, API calls, verifications | | `volume` | Charges based on a numeric quantity included in the event payload | Video minutes generated, tokens, storage | | `unit_and_volume` | Charges both a per-event fee and a quantity-based fee in the same event | Per-message fee + tokens consumed in that message | ### Unit[​](#unit "Direct link to Unit") A flat fee is applied each time a matching event is received. No quantity field is required in the event payload. ```json "usage_calculation": { "event_type": "video_promoted", "usage_type": "unit", "source_reference_field": "video_id" } ``` ### Volume[​](#volume "Direct link to Volume") The fee is calculated from a numeric field in the event's `data` object. You specify which field to read using `volume_field`. ```json "usage_calculation": { "event_type": "video_generated", "usage_type": "volume", "volume_field": "minutes", "source_reference_field": "video_id" } ``` The corresponding event payload must include the `volume_field` value in `data`. In this example Credyt reads `minutes` to calculate the fee: ```json { "event_type": "video_generated", "data": { "minutes": 4, "video_id": "vid_9a3c7f1b2e84" } } ``` ### Unit and Volume[​](#unit-and-volume "Direct link to Unit and Volume") Combines both: a flat per-event fee plus a volume-based fee derived from the payload. Useful for pricing models that have both a call fee and a consumption fee. ```json "usage_calculation": { "event_type": "message_completed", "usage_type": "unit_and_volume", "volume_field": "tokens", "source_reference_field": "chat_id" } ``` The event payload must include the `volume_field` value in `data`. Credyt applies the per-event fee once and the volume fee against `tokens`: ```json { "event_type": "message_completed", "data": { "tokens": 1840, "chat_id": "chat_3e91b7f042ac" } } ``` ### Dimensional pricing[​](#dimensional-pricing "Direct link to Dimensional pricing") If your rates vary based on attributes of the usage — such as processing speed or output quality — you can define `billable_dimensions` to apply different rates to different variants without creating separate products. For example, charging $1.00/minute for fast video generation and $0.40/minute for standard. See [Dimensional Pricing](https://docs.credyt.ai/features/product-catalog/dimensional-pricing.md) for details. ## Setup Flow[​](#setup-flow "Direct link to Setup Flow") ### Step 1: Create a usage-based product[​](#step-1-create-a-usage-based-product "Direct link to Step 1: Create a usage-based product") [API Reference](https://docs.credyt.ai/api/products-create.md) Define your product and its pricing configuration. Set `type: usage_based` and `billing_model.type: real_time`. Products are created in draft mode by default. Set `publish: true` to make the product immediately available for subscriptions, or omit it to review and test first. The example below creates a Glitch Video product that charges $1.00 per minute of video generated: * REST API * TypeScript SDK * Python SDK POST https\://api.credyt.ai/products ```json { "name": "Glitch Video", "code": "glitch_video_std", "prices": [ { "name": "Video Generation", "type": "usage_based", "billing_model": { "type": "real_time" }, "usage_calculation": { "event_type": "video_generated", "usage_type": "volume", "volume_field": "minutes", "source_reference_field": "video_id" }, "pricing": [ { "asset": "USD", "values": [ { "volume_rate": 1 } ] } ] } ], "publish": true } ``` **Response** ```json { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": 1, "status": "published", "is_default": true } ``` ```typescript await client.products.create({ name: "Glitch Video", code: "glitch_video_std", prices: [ { name: "Video Generation", type: "usage_based", billingModel: { type: "real_time", }, usageCalculation: { eventType: "video_generated", usageType: "volume", volumeField: "minutes", sourceReferenceField: "video_id", }, pricing: [ { asset: "USD", values: [ { volumeRate: 1, }, ], }, ], }, ], publish: true, }); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/productsCreateSample.ts#L99) **SDK response object** ```typescript const response = { id: "prp_4e28n8kk41931f5yt5em49ecw7", code: "glitch_video_std", version: 1, status: "published", isDefault: true, }; ``` ```python response = client.products.create( body={ "name": "Glitch Video", "code": "glitch_video_std", "prices": [ { "name": "Video Generation", "type": "usage_based", "billing_model": { "type": "real_time", }, "usage_calculation": { "event_type": "video_generated", "usage_type": "volume", "volume_field": "minutes", "source_reference_field": "video_id", }, "pricing": [ { "asset": "USD", "values": [ { "volume_rate": 1, }, ], }, ], }, ], "publish": True, }, ) ``` [View full sample on GitHub](https://github.com/credyt/sdk-python/blob/main/samples/products_create_glitch_video.py#L20) **SDK response object** ```python response = { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": 1, "status": "published", "is_default": True, } ``` A product can contain multiple prices to cover different billable aspects. For example, Glitch Video could add a second price with `event_type: video_promoted` to charge separately for video promotions, within the same subscription and without requiring customers to subscribe to an additional product. Simulating usage You can validate your product configuration before going live by [simulating usage events](https://docs.credyt.ai/api/products-simulate-usage.md). Simulated events run through the full billing engine and return calculated fees without modifying any wallet balances. See [Simulating Usage](#simulating-usage) below. ### Step 2: Subscribe your customers[​](#step-2-subscribe-your-customers "Direct link to Step 2: Subscribe your customers") [API Reference](https://docs.credyt.ai/api/customers-create.md) Register the customer in Credyt and subscribe them to your product. You can provide your own identifier using `external_id`, which can then be used in place of Credyt's customer ID when submitting usage events — avoiding the need to maintain ID mappings in your system. * REST API * TypeScript SDK * Python SDK POST https\://api.credyt.ai/customers ```json { "name": "John Doe", "external_id": "18991", "subscriptions": [ { "products": [ { "code": "glitch_video_std" } ] } ] } ``` **Response** ```json { "id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "subscriptions": [ { "id": "sub_411xhg4kqakf3d8ybezbzta558", "started_at": "2025-08-24T14:15:22Z", "status": "active", "products": [ { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": "default" } ] } ] } ``` ```typescript await client.customers.create({ name: "John Doe", externalId: "18991", subscriptions: [ { products: [ { code: "glitch_video_std", }, ], }, ], }); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/customersCreateSample.ts#L112) **SDK response object** ```typescript const response = { id: "cust_473cr1y0ghbyc3m1yfbwvn3nxx", subscriptions: [ { id: "sub_411xhg4kqakf3d8ybezbzta558", startedAt: "2025-08-24T14:15:22Z", status: "active", products: [ { id: "prp_4e28n8kk41931f5yt5em49ecw7", code: "glitch_video_std", version: "default", }, ], }, ], }; ``` ```python response = client.customers.create( body={ "name": "John Doe", "external_id": "18991", "subscriptions": [ { "products": [ { "code": "glitch_video_std", }, ], }, ], }, ) ``` [View full sample on GitHub](https://github.com/credyt/sdk-python/blob/main/samples/customers_create_subscribe_to_glitch_video.py#L20) **SDK response object** ```python response = { "id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "subscriptions": [ { "id": "sub_411xhg4kqakf3d8ybezbzta558", "started_at": "2025-08-24T14:15:22Z", "status": "active", "products": [ { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": "default", }, ], }, ], } ``` When the subscription is created, Credyt automatically provisions the wallet accounts required by the product's pricing — in this case a USD account. No additional setup is needed. Unmatched usage Make sure to subscribe a customer to all products they use. Usage events that arrive before a subscription is active, or that reference a product the customer is not subscribed to, will be accepted but will not be billed or deducted from the wallet. ### Step 3: Fund the wallet[​](#step-3-fund-the-wallet "Direct link to Step 3: Fund the wallet") [API Reference TopUp](https://docs.credyt.ai/api/top-ups-initiate.md) [API Reference Adjustment](https://docs.credyt.ai/api/customer-wallet-ops-create-adjustment.md) Before usage can be billed, the customer's wallet must hold a sufficient balance. Credyt provides a hosted [Billing Portal](https://docs.credyt.ai/features/billing-portal.md) and a Top-up API to accept customer payments via Stripe. You can also reuse your existing billing setup that leverages an external provider. See [Wallets and Topups](https://docs.credyt.ai/features/wallets-and-topups.md) for the full payment and top-up setup. ### Step 4: Send usage events[​](#step-4-send-usage-events "Direct link to Step 4: Send usage events") [API Reference](https://docs.credyt.ai/api/events-send-usage.md) As your platform processes customer activity, send usage events to Credyt. Events are matched to the customer's subscription by `customer_id` (or `external_id`) and to the correct price by `event_type`. Matched events are processed and the customer's wallet is debited immediately. * REST API * TypeScript SDK * Python SDK POST https\://api.credyt.ai/events ```json { "customer_id": "cust_4td6grpw680sgewcaz5p89pf40", "events": [ { "id": "ba15987a-7b68-4a9d-b2e6-eadeff29e657", "event_type": "video_generated", "occurred_at": "2025-11-04T21:53:21.392Z", "subject": "video_defc8524", "description": "Video Generated", "data": { "minutes": 10, "speed": "fast" } } ] } ``` ```typescript await client.events.sendUsage({ customerId: "cust_4td6grpw680sgewcaz5p89pf40", events: [ { id: "ba15987a-7b68-4a9d-b2e6-eadeff29e657", eventType: "video_generated", occurredAt: "2025-11-04T21:53:21.392Z", subject: "video_defc8524", description: "Video Generated", data: { minutes: 10, speed: "fast", }, }, ], }); ``` [View full sample on GitHub](https://github.com/credyt/sdk-ts/blob/main/samples/eventsSendUsageSample.ts#L35) ```python response = client.events.send_usage( body={ "customer_id": "cust_4td6grpw680sgewcaz5p89pf40", "events": [ { "id": "ba15987a-7b68-4a9d-b2e6-eadeff29e657", "event_type": "video_generated", "occurred_at": "2025-11-04T21:53:21.392Z", "subject": "video_defc8524", "description": "Video Generated", "data": { "minutes": 10, "speed": "fast", }, }, ], }, ) ``` [View full sample on GitHub](https://github.com/credyt/sdk-python/blob/main/samples/events_send_usage_video_generated.py#L20) Each event's `id` acts as an idempotency key. If the same event is submitted more than once — due to a retry or network error — Credyt will process it only once, preventing accidental double billing. You can submit multiple events in a single request by adding entries to the `events` array. ## Correlating Usage[​](#correlating-usage "Direct link to Correlating Usage") Including the `subject` field on every event is strongly recommended. It links each billable event to a specific activity in your system — a video, a chat session, a job — and is used by the Billing Portal to present customers with an itemised view of their usage. It also feeds into [Profitability](https://docs.credyt.ai/features/profitability.md) analysis, where you can track both revenue and infrastructure costs against the same activity. For finer-grained traceability at the product level, configure a `source_reference_field` in the product's `usage_calculation`. This maps a field from the event's `data` object (e.g. `video_id` or `chat_id`) to each generated fee, making it easier to reconcile billing records with your own logs. ## Simulating Usage[​](#simulating-usage "Direct link to Simulating Usage") [API Reference](https://docs.credyt.ai/api/products-simulate-usage.md) Before going live, you can simulate usage events against any product version to validate your pricing configuration. Simulated events run through the same billing logic and return the fees that would be generated, without debiting any wallet or registering the usage in the system. This is particularly useful when introducing a new product version or testing a pricing change before publishing it. ## See Also[​](#see-also "Direct link to See Also") * [Wallets and Topups](https://docs.credyt.ai/features/wallets-and-topups.md) — top-up options and wallet management * [Dimensional Pricing](https://docs.credyt.ai/features/product-catalog/dimensional-pricing.md) — variable rates based on usage attributes like processing speed or output quality * [Hybrid Billing with Entitlements](https://docs.credyt.ai/features/product-catalog/entitlements.md) — combining subscriptions with usage-based overages * [Pricing Guide](https://docs.credyt.ai/pricing-guide.md) — choosing the right billing model for your product