Credits

Transactional credit ledger for Convex apps: grant, reserve, complete, release, refund, and transfer credits with idempotent retries and auditable history.

Installation

npm install @clipin/convex-credits

About Credits

Convex Credits manages credit balances and charges for Convex apps. Grant gifts and rewards, reserve credits before work starts, and complete or release charges when work ends. The component also supports refunds, atomic transfers, safe retries with stable operation keys, and an auditable history of balance changes. Maintained by CLIPIN.

Benefits

Use cases

how to implement a credit system in Convex for AI usage billing

The @clipin/convex-credits component provides a Credits client you mount in your Convex app and call from host mutations to grant, reserve, and charge credits. Amounts are enforced as positive safe integers and balances cannot go negative, making it suitable for metering AI API usage. The reserve-then-complete pattern lets you hold credits before async work starts and settle the charge only on success.

idempotent credit deduction Convex background jobs

convex-credits requires a stable operation key for every write. If the same key is submitted again, the component returns the original result instead of applying a second debit, making it safe to retry failed Convex mutations or scheduled functions. Supplying the same key with different arguments is rejected to prevent accidental misuse.

how to reserve and release credits before background job completes Convex

convex-credits supports a reserve-complete-release lifecycle: call reserve before the job starts to hold credits, call complete on success to finalize the charge without an additional debit, or call release on failure to return the reserved amount. All three operations accept idempotent keys so retries from Convex scheduled functions are safe.

migrate or import credit balances into Convex with history preserved

convex-credits includes import helpers that preserve source timestamps and pending charges when loading a snapshot, then verify balances and counts before activating accounts. This lets you migrate an existing credit ledger into a Convex deployment without losing historical data or creating balance discrepancies.

Frequently asked questions

How do I install and mount convex-credits in a Convex project?

Run `npm install @clipin/convex-credits convex` to add the package. In `convex/convex.config.ts`, import the component config and call `app.use(credits)` to mount it. Then instantiate `new Credits(components.credits)` in your host backend and call its methods from inside authorized Convex mutations.

What happens if a credit operation is retried with the same key?

convex-credits uses a stable operation key for every write. Submitting the same key a second time returns the original result without applying the operation again, so retries from failed or re-executed Convex mutations are safe. Submitting the same key with different arguments throws an error to catch accidental key collisions.

Can credit balances go negative in convex-credits?

No. convex-credits enforces that available balances cannot become negative. Any operation that would overdraw an account is rejected, which makes it safe to use for metered billing where users must have sufficient credits before work is performed.

Does convex-credits handle concurrent mutations safely?

Yes. Because convex-credits is called from host Convex mutations, both the component writes and the host writes are committed in the same Convex transaction. This ensures atomicity for operations like transfers between accounts and prevents race conditions from concurrent mutations.

How do I query credit history in convex-credits?

convex-credits stores history as nonzero balance movements and supports cursor pagination through convex-helpers, which is compatible with Convex component queries. Completion operations update charge state but do not add a history entry, keeping the history log focused on actual balance changes.

Links