Topups Only Model
Some AI platforms avoid subscriptions altogether and charge customers only when they add funds upfront. This model is straightforward, reduces credit risk, and works well for usage-heavy products where customers prefer a pay-as-you-go approach.
This model is popular with consumer AI apps and prosumer tools (e.g., image, video, or avatar apps), as well as with infrastructure and API platforms that aim to limit credit risk and simplify billing with prepaid balances.
With Credyt, you can implement top-ups in two ways:
- External top-ups - process payments through your own PSP, then notify Credyt of the balance change via the Adjustments API.
- Credyt-powered top-ups - use the Billing Portal (self-service UI) or Top-up API (platform UI + backend) to let customers add funds through Stripe Checkout.
In both cases, usage events consume the wallet balance in real time.
Implementation Guide
Initialise Wallet Balance with a Top-up
Using Credyt's payment rails
If you use Credyt’s payment rails, initiate the flow via Billing Portal or the Top-up API. For example, via Top-up API:
- REST API
- TypeScript SDK
- Python SDK
{
"customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
"amount": 50,
"currency": "USD",
"description": "Image generation credits",
"destination": {
"account_name": "default",
"asset": "USD",
"exchange_rate": 1000000
},
"credit_expires_at": "2024-07-29T15:51:28.071Z",
"return_url": "https://glitch.ai/account",
"failure_url": "https://glitch.ai/callbacks/credyt-failure",
"metadata": {
"order_id": "order_12345"
}
}
Response
{
"id": "top_473cr1y0ghbyc3m1yfbwvn3nxx",
"status": "initiated",
"redirect_url": "https://billing.credyt.ai/api/sign-in?token=xyz",
"created_at": "2024-07-29T15:51:28.071Z",
"expires_at": "2024-07-29T15:51:28.071Z"
}
await client.topUps.initiate({
customerId: "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
amount: 50,
currency: "USD",
description: "Image generation credits",
destination: {
accountName: "default",
asset: "USD",
exchangeRate: 1000000,
},
creditExpiresAt: "2024-07-29T15:51:28.071Z",
returnUrl: "https://glitch.ai/account",
failureUrl: "https://glitch.ai/callbacks/credyt-failure",
metadata: {
orderId: "order_12345",
},
});
SDK response object
const response = {
id: "top_473cr1y0ghbyc3m1yfbwvn3nxx",
status: "initiated",
redirectUrl: "https://billing.credyt.ai/api/sign-in?token=xyz",
createdAt: "2024-07-29T15:51:28.071Z",
expiresAt: "2024-07-29T15:51:28.071Z",
};
response = client.top_ups.initiate(
body={
"customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
"amount": 50,
"currency": "USD",
"description": "Image generation credits",
"destination": {
"account_name": "default",
"asset": "USD",
"exchange_rate": 1000000,
},
"credit_expires_at": "2024-07-29T15:51:28.071Z",
"return_url": "https://glitch.ai/account",
"failure_url": "https://glitch.ai/callbacks/credyt-failure",
"metadata": {
"order_id": "order_12345",
},
},
)
SDK response object
response = {
"id": "top_473cr1y0ghbyc3m1yfbwvn3nxx",
"status": "initiated",
"redirect_url": "https://billing.credyt.ai/api/sign-in?token=xyz",
"created_at": "2024-07-29T15:51:28.071Z",
"expires_at": "2024-07-29T15:51:28.071Z",
}
Response includes a redirect_url to Stripe Checkout. Redirect the customer to complete payment.
Using an external PSP
If you handle payments externally, reflect the top-up in Credyt via Adjustments API:
- REST API
- TypeScript SDK
- Python SDK
{
"transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"account_name": "default",
"asset": "USD",
"amount": 25,
"description": "Ad-hoc usage",
"reason": "external_topup",
"expires_at": "2024-07-29T15:51:28.071Z",
"metadata": {
"psp": "stripe",
"payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0"
}
}
Response
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2024-07-29T15:51:28.071Z"
}
await client.customerWalletOps.createAdjustment("cust_473cr1y0ghbyc3m1yfbwvn3nxx", {
transactionId: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
accountName: "default",
asset: "USD",
amount: 25,
description: "Ad-hoc usage",
reason: "external_topup",
expiresAt: "2024-07-29T15:51:28.071Z",
metadata: {
psp: "stripe",
paymentIntent: "pi_3RjbbNJNSIruR1rb0GwMGpH0",
},
});
SDK response object
const response = {
id: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
createdAt: "2024-07-29T15:51:28.071Z",
};
response = client.customer_wallet_ops.create_adjustment(
customer_id="cust_473cr1y0ghbyc3m1yfbwvn3nxx",
body={
"transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"account_name": "default",
"asset": "USD",
"amount": 25,
"description": "Ad-hoc usage",
"reason": "external_topup",
"expires_at": "2024-07-29T15:51:28.071Z",
"metadata": {
"psp": "stripe",
"payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0",
},
},
)
SDK response object
response = {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2024-07-29T15:51:28.071Z",
}
This adds $25 to the balance.
Deduct Usage from the Wallet
Once a wallet has funds, usage is billed in real time. Each event reduces the available balance.
- REST API
- TypeScript SDK
- Python SDK
{
"customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
"events": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"event_type": "message_completed",
"occurred_at": "2024-07-29T15:51:28.071Z",
"subject": "chat_5f53d23a4958",
"description": "Chat message completed",
"data": {
"model": "gpt-4-1",
"input_tokens": 2353,
"output_tokens": 34697
}
}
]
}
await client.events.sendUsage({
customerId: "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
events: [
{
id: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
eventType: "message_completed",
occurredAt: "2024-07-29T15:51:28.071Z",
subject: "chat_5f53d23a4958",
description: "Chat message completed",
data: {
model: "gpt-4-1",
inputTokens: 2353,
outputTokens: 34697,
},
},
],
});
response = client.events.send_usage(
body={
"customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx",
"events": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"event_type": "message_completed",
"occurred_at": "2024-07-29T15:51:28.071Z",
"subject": "chat_5f53d23a4958",
"description": "Chat message completed",
"data": {
"model": "gpt-4-1",
"input_tokens": 2353,
"output_tokens": 34697,
},
},
],
},
)
Check Wallet Balance
At any time, the platform can query balances:
- REST API
- TypeScript SDK
- Python SDK
Response
{
"accounts": [
{
"id": "default:USD",
"name": "default",
"asset": "USD",
"available": 14.566678
},
{
"id": "default:TOK",
"name": "default",
"asset": "TOK",
"available": 993450234
}
]
}
await client.customerWalletOps.getCustomerWallet("cust_473cr1y0ghbyc3m1yfbwvn3nxx");
SDK response object
const response = {
accounts: [
{
id: "default:USD",
name: "default",
asset: "USD",
available: 14.566678,
},
{
id: "default:TOK",
name: "default",
asset: "TOK",
available: 993450234,
},
],
};
response = client.customer_wallet_ops.get_customer_wallet(
customer_id="cust_473cr1y0ghbyc3m1yfbwvn3nxx",
)
SDK response object
response = {
"accounts": [
{
"id": "default:USD",
"name": "default",
"asset": "USD",
"available": 14.566678,
},
{
"id": "default:TOK",
"name": "default",
"asset": "TOK",
"available": 993450234,
},
],
}