# Credyt Documentation for AI Tools > Documentation for Credyt, the real-time billing infrastructure for AI products. Explore guides, API references, and more to integrate Credyt into your AI applications. ## Ai Integration ### Credyt integration guide for AI assistants and tools This guide helps AI assistants (like ChatGPT, Claude, Lovable, and other AI and vibe coding tools) walk developers through integrating Credyt into their applications. Credyt is real-time billing infrastructure built for AI products. It handles usage-based billing, prepaid wallets, and revenue recognition, so you don't have to build it yourself. #### ⚠️ CRITICAL: READ THIS FIRST ⚠️[​](#️-critical-read-this-first-️ "Direct link to ⚠️ CRITICAL: READ THIS FIRST ⚠️") **STOP. Do not write any code yet.** When a user asks you to integrate Credyt, your response must follow this order: 1. ❌ DO NOT write code 2. ❌ DO NOT create files 3. ❌ DO NOT assume a billing model 4. ✅ DO ask discovery questions (one at a time) 5. ✅ DO explain billing models with examples from their domain 6. ✅ DO help them define products in Credyt 7. ✅ ONLY THEN write integration code **If you write code before understanding their business model, you are doing it wrong.** This is not optional. Discovery must come first. #### Required integration workflow[​](#required-integration-workflow "Direct link to Required integration workflow") Follow these steps in order. Do not skip ahead. **Phase 1: Discovery (REQUIRED FIRST)** Ask questions one at a time. Listen to answers. Explain concepts with concrete examples. Goals: * Understand their business model * Choose billing model (usage-based, subscription, or hybrid) * Decide fiat currency vs custom assets * Identify billable events * Define pricing dimensions Do not proceed until you understand their monetization strategy. **Phase 2: Product definition (REQUIRED SECOND)** Help them create product configuration in Credyt. This happens via API calls OR the Credyt dashboard. Either way, products must be defined before you write integration code. Goals: * Create custom assets (if needed) * Create products with pricing * Configure event types * Set up dimensional pricing (if needed) **Phase 3: Code integration (ONLY AFTER PHASES 1-2)** Now you can write code. Create backend integration, implement wallet checks, send usage events, handle top-ups. ##### Common mistakes to avoid[​](#common-mistakes-to-avoid "Direct link to Common mistakes to avoid") ❌ **WRONG**: ```text User: "Integrate Credyt into my image generation app" AI: *immediately writes code with $0.50 per image hardcoded* ``` ✅ **RIGHT**: ```text User: "Integrate Credyt into my image generation app" AI: "Before I write any code, I need to understand your business model. How do you want to charge for image generation?" ``` ❌ **WRONG**: Asking 10 questions at once in a massive list ✅ **RIGHT**: Ask questions sequentially, adapting based on previous answers ❌ **WRONG**: Assuming they want usage-based pricing ✅ **RIGHT**: Explaining all three models with examples from their domain #### Pre-code checklist[​](#pre-code-checklist "Direct link to Pre-code checklist") Complete ALL of these before writing any code: * Asked about billable activities (what costs them money) * Asked about pricing preferences (how they want to charge) * Asked about ability to front costs (can they absorb usage before payment) * Explained all three billing models with domain-specific examples * User has chosen a billing model * Decided fiat vs custom assets (with clear reasoning) * Identified all billable event types * Defined pricing dimensions (if applicable) * Helped create products in Credyt (API or dashboard) * Confirmed product configuration is complete **Only proceed to code when ALL boxes are checked.** #### Before you start[​](#before-you-start "Direct link to Before you start") When a user asks to integrate Credyt, you MUST start by understanding their business model. Do not proceed to code without completing discovery. This is not optional. Don't write code yet. Start with questions. Ask them sequentially, one at a time, adapting based on their answers. **Read these first**: * [Core concepts](https://docs.dev.credyt.ai/concepts.md) * [Pricing models](https://docs.dev.credyt.ai/pricing-guide.md) * [Full documentation](https://docs.dev.credyt.ai/llms-full.txt) * [OpenAPI specification](https://docs.dev.credyt.ai/assets/files/openapi.1.0-48d98d953ab5d7edfcec5775ab971f87.yaml) > **Note**: If HTML docs don't load, append `.md` to the URL (e.g., `https://docs.dev.credyt.ai/advanced-topics/refunds.md`) to get the markdown version. #### Discovery: Understand their monetization[​](#discovery-understand-their-monetization "Direct link to Discovery: Understand their monetization") Before you write code, understand how they make money. ##### How to ask questions:[​](#how-to-ask-questions "Direct link to How to ask questions:") * Ask questions ONE AT A TIME * Listen to their answer before asking the next question * Adapt follow-up questions based on what they tell you * Never dump 5+ questions on them at once **Question order matters**: 1. Start with billing model (affects everything else) 2. Then fiat vs custom assets (if needed) 3. Then specific billable events 4. Then pricing dimensions 5. Finally account setup Each answer informs the next question. This is a conversation, not a form. ##### 1. Choose a billing model[​](#1-choose-a-billing-model "Direct link to 1. Choose a billing model") Help them pick between three models. Each solves different problems. Start by explaining what these models actually mean with concrete examples from their domain. ###### Real-time usage-based billing (prepaid)[​](#real-time-usage-based-billing-prepaid "Direct link to Real-time usage-based billing (prepaid)") Customers add funds upfront. Usage draws down the balance in real time. When the balance hits zero, service stops or triggers automatic refill. **What this means in practice**: * Charge users for activities they perform in your app * Examples: $0.03 per API call, $2.50 per video generated, $0.001 per token * Like a prepaid phone: add $20, make calls, balance decreases with each call **How others do it**: * OpenAI: charges per token consumed (e.g., $0.002 per 1K tokens for GPT-4) * Replicate: charges per second of model compute time * ElevenLabs: charges per character of audio generated This works when: * Infrastructure costs are variable and unpredictable * You can't afford to front costs for customers * Your customers expect pay-as-you-go pricing * You need cash flow protection **Example question for user**: "If you charge $0.10 per image your app generates, would customers prepay (like adding $10 for 100 images) or get billed monthly for what they used?" ###### Fixed recurring fees (aka traditional SaaS subscriptions)[​](#fixed-recurring-fees-aka-traditional-saas-subscriptions "Direct link to Fixed recurring fees (aka traditional SaaS subscriptions)") Customers pay a fixed amount per billing cycle. This provides baseline revenue while you figure out usage pricing. **What this means in practice**: * Charge a flat monthly or annual fee * Examples: $20/month for Pro access, $99/year for Premium features * Like Netflix: pay $15/month regardless of how much you watch **How others do it**: * Most traditional SaaS: Slack, Notion, Figma charge per seat per month * GitHub: $4/user/month for team features This works when: * You need revenue now but aren't ready to price usage * You want to understand cost structure before charging for usage * You're planning to transition to usage-based pricing later * Enterprise customers require predictable billing cycles Start here if you're still validating product-market fit. Track usage and costs without charging for them yet. Use profitability data to inform your eventual usage pricing. **Example question for user**: "Do you want to charge users a fixed monthly fee for access to your app, regardless of how much they use it?" ###### Hybrid (subscriptions + entitlements + top-ups)[​](#hybrid-subscriptions--entitlements--top-ups "Direct link to Hybrid (subscriptions + entitlements + top-ups)") Base subscription includes usage allowances. Additional usage is purchased through top-ups or charged as overages. **What this means in practice**: * Monthly subscription that includes a credit allowance * Examples: $20/month includes 1,000 credits, extra credits are $0.05 each * Like a phone plan: $30/month includes 5GB data, pay $10/GB for overages **How others do it**: * Clay: monthly subscription includes credit allocation for data enrichment * Cursor: different tiers include different amounts of AI completions * GitHub Copilot: subscription with usage caps, then throttling or upgrades This works when: * You need baseline recurring revenue plus usage-based growth * Some features are seat-based, others consumption-based * Customers want predictability with flexibility for overages * Different customer segments expect different billing approaches **Example question for user**: "Would you want to give users 1,000 free credits per month with their $20 subscription, then charge them $0.05 per credit when they run out?" **Start with this question**: "How do you want to charge for \[their specific activity]?" Then adapt based on their answer. If they say "per image" → usage-based. If they say "monthly fee" → subscription. If they say "both" → hybrid. **Follow-up questions (ask based on context)**: * "What activities in your app should be billable?" (be specific: API calls, images generated, minutes of video, tokens processed) * "How do you want to charge for those activities?" (give pricing examples: $0.10 per image, $2.50 per video, $0.001 per token) * "Can you afford to front infrastructure costs?" (explain: if a user generates a $5 video but hasn't paid yet, can you absorb that cost?) * "How predictable is customer usage?" (explain: some customers might use 10x more than others in the same month) * "What do similar products charge?" (help them research: look at OpenAI, Anthropic, Replicate, etc.) ##### 2. Fiat currency vs custom assets (critical decision)[​](#2-fiat-currency-vs-custom-assets-critical-decision "Direct link to 2. Fiat currency vs custom assets (critical decision)") One of the most important decisions: price in dollars or custom units? This choice affects how customers perceive value, how you handle pricing changes, and whether you can offer earning mechanisms. **Price in fiat currency (USD, EUR) when**: Your costs are deterministic per unit. Customers are technical users who understand infrastructure metrics. The unit-to-value relationship is already clear. **Examples**: * OpenAI and Anthropic price in tokens but show dollar balances. Technical users understand that 10M tokens through GPT-4 has a clear cost. * Replicate charges per second of compute time, billed in dollars. **Advantages**: * Transparent pricing (customers see exactly what they pay) * No conversion confusion * Simpler accounting * Enterprise-friendly (matches procurement expectations) **Price in custom units (credits, tokens, minutes) when**: Infrastructure costs vary but customer-facing pricing should stay predictable. Non-technical users need product-native units. You expect pricing to evolve as you learn unit economics. **What this means**: * Video platforms: Bill in "video minutes" not dollars * Translation apps: Bill in "words" or "document credits" not tokens * Voice platforms: Bill in "characters" or "conversation minutes" * Gaming: Bill in "coins" or "gems" that can be earned and spent **Why Midjourney uses GPU hours**: Midjourney allocates GPU time to subscribers (3.3 hours Basic, 15 hours Standard, 30 hours Pro). The actual GPU cost per image varies by model, resolution, and settings. Customers see consistent GPU time deductions. Infrastructure complexity is abstracted. Different models: Gen-4 costs more compute than Gen-4 Turbo. Customers pay in GPU time, not variable per-image costs. When infrastructure costs change, the GPU hour price can adjust without confusing customers. **Why Runway uses credits**: Runway bills video generation in credits. Gen-4 costs 12 credits/second, Gen-4 Turbo costs 5 credits/second. Different quality tiers have different computational requirements. Customers see predictable credit deductions. The relationship between credits and value stays stable even as underlying costs shift. ###### Three problems custom assets solve:[​](#three-problems-custom-assets-solve "Direct link to Three problems custom assets solve:") **1. Infrastructure costs vary, pricing shouldn't** AI platforms face unpredictable compute costs. Quality settings, duration, complexity all affect cost. If you bill directly for infrastructure, pricing becomes unpredictable. If you average costs, margins erode on expensive requests. Custom units decouple infrastructure variance from customer-facing pricing. A standard job costs 1 credit, high-quality costs 2 credits, priority costs 3 credits. Infrastructure scales invisibly. **2. Product-native units make sense** When you bill in dollars, customers see "$1.47" without understanding what they purchased. When you bill in video minutes, they see "Generated 4-second clip: -2 minutes." Usage history shows exactly what was consumed in units that map to behavior. Translation apps: A non-technical user being billed in LLM tokens has no reference. But "words" or document credits (small, medium, large) make immediate sense. **3. Value can be earned, not just purchased** Credits become powerful when customers can earn them outside purchases. Lovable lets users earn credits through referrals: 10 credits when someone signs up through your link, 10 more when they publish their first app. These credits work identically to purchased credits. Gaming platforms use gems, coins, tokens. Players purchase bundles but also earn currency through gameplay, achievements, daily bonuses. This enables hybrid monetization: some users pay, others earn, most do both. When credits can be earned through product engagement, they stop being purely transactional and become part of the product experience. **Start by asking**: "Do you want customers to see prices in dollars (like $2.50 per video) or in credits/tokens (like 10 credits per video)?" Listen to their answer. Then ask follow-up questions based on what they need help with: **If they're unsure, ask one of these**: * "Do your infrastructure costs vary significantly based on usage complexity?" * "Are your users technical (understand tokens/API calls) or non-technical (need simpler units)?" * "Do you want customers to earn credits through referrals or engagement?" * "Will your pricing likely change as you learn unit economics?" * "Would customers benefit from seeing 'video minutes' vs '$0.15 per generation'?" **If choosing custom assets**, they'll need to create these first (before products). See Step 2 in Implementation for the technical setup. ##### 3. Identify billable events[​](#3-identify-billable-events "Direct link to 3. Identify billable events") Help them identify what consumes resources or delivers value. **Start with**: "What activities in your app cost you money to provide?" Listen to their answer. Then dig deeper with specific follow-ups: **Follow-up questions (based on their answer)**: * "What actions cost you money?" * "What outcomes can you measure?" * "What events are expensive to process?" **Common event types**: * API calls * AI model completions (chat, images, video) * Processing time (minutes, seconds) * Volume consumed (tokens, data, storage) * Quality tiers (standard, premium) * Speed tiers (fast, regular) > **Best practice**: Send usage events for all meaningful activities initially. Review them in Credyt. Decide pricing later. ##### 4. Pricing dimensions[​](#4-pricing-dimensions "Direct link to 4. Pricing dimensions") Does pricing vary based on attributes? This is dimensional pricing. **Ask**: "Do you charge different amounts based on quality, speed, or model type?" If yes, ask for specifics: "What are the different tiers and how should they be priced?" **Common dimensions**: * "Do different AI models cost different amounts?" * "Do you charge more for faster processing?" * "Are there quality tiers with different prices?" These attributes become billable dimensions in Credyt. ##### 5. Account setup[​](#5-account-setup "Direct link to 5. Account setup") **Ask**: "Do you have a Credyt account set up already?" **If no**: * Sign up at * Accounts start in test mode (perfect for integration) * Get API keys from (Developers section) **If yes**: * Confirm they have their test API key * Remind them: server-side only, never in client code * Ask: "Do you have your API key handy?" *** #### Discovery checkpoint[​](#discovery-checkpoint "Direct link to Discovery checkpoint") Before moving to implementation, confirm you have: ✅ Clear billing model chosen (usage-based, subscription, or hybrid)
✅ Fiat or custom assets decision made
✅ All billable events identified
✅ Pricing structure defined (including dimensions if applicable)
✅ Credyt account set up with API keys If any of these are unclear, go back and ask more questions. **Only proceed to Implementation once discovery is complete.** *** #### Implementation[​](#implementation "Direct link to Implementation") Once you understand their model, walk them through these steps. > **Important**: If they want to use custom assets (tokens, credits, coins), create those FIRST before creating products or processing transactions. Custom assets must exist before they can be referenced in product pricing or wallet adjustments. ##### Step 1: Set up authentication[​](#step-1-set-up-authentication "Direct link to Step 1: Set up authentication") All API requests require the `X-CREDYT-API-KEY` header. **Security rules**: * Store API keys server-side only * Never expose keys in client code * Use environment variables ```javascript // .env file CREDYT_API_KEY = your_test_api_key_here; // API client const headers = { "Content-Type": "application/json", "X-CREDYT-API-KEY": process.env.CREDYT_API_KEY, }; ``` **Test your connection**: Verify your API key works by listing customers: ```javascript const response = await fetch("https://api.credyt.ai/customers", { headers }); if (response.ok) { console.log("✓ Connected to Credyt successfully"); } else { console.error("✗ Authentication failed - check your API key"); } ``` This endpoint always succeeds if you're authenticated correctly. ##### Step 2: Define products and pricing[​](#step-2-define-products-and-pricing "Direct link to Step 2: Define products and pricing") Products define what you bill for and how. You typically create these once during setup—not in your application code. **Workflow order** (important): 1. Create custom assets first (if using tokens, credits, etc.) 2. Then create products that reference those assets 3. Subscribe customers to products **Core concepts**: * **Product**: What the customer consumes (e.g., "Video Generation") * **Price**: One product can have multiple prices for different events * **Event type**: The billable action (e.g., `video_generated`, `message_completed`) * **Usage type**: * `unit` - charge per occurrence * `volume` - charge based on quantity in payload * `unit_and_volume` - both **Publishing products**: Products must be published before customers can subscribe to them. Set `publish: true` when creating the product, or publish it later using `PATCH /products/:productId/:version`. **If using custom assets (tokens, credits, coins)** Create these BEFORE creating products. Custom assets must exist before they can be referenced. ```javascript // Step 1: Create the custom asset const asset = { code: "CREDIT", name: "Credits", precision: 0, symbol: "⭐", label: "CR", rates: [ { source: "USD", rate: 0.05, // $0.05 per credit (or $1 = 20 credits) }, ], }; await fetch("https://api.credyt.ai/assets", { method: "POST", headers, body: JSON.stringify(asset), }); // Step 2: Now create products that use this asset const product = { name: "AI Image Generation", code: "image_gen_std", prices: [ { name: "Image Generation", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "image_generated", usage_type: "unit", }, pricing: [ { asset: "CREDIT", // References the asset we just created values: [{ unit_price: 10 }], // 10 credits per image }, ], }, ], publish: true, // Publish immediately so customers can subscribe }; await fetch("https://api.credyt.ai/products", { method: "POST", headers, body: JSON.stringify(product), }); ``` **If using fiat currency (USD, EUR)** You can skip asset creation and create products directly. **Unit-based pricing** Charge per occurrence. Here we charge $2.50 per video generation: ```javascript const product = { name: "AI Video Generation", code: "video_gen_std", prices: [ { name: "Video Generation", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "video_generated", usage_type: "unit", source_reference_field: "video_id", }, pricing: [ { asset: "USD", values: [{ unit_price: 2.5 }], }, ], }, ], publish: true, }; const response = await fetch("https://api.credyt.ai/products", { method: "POST", headers, body: JSON.stringify(product), }); ``` **Volume-based pricing** Charge based on quantity consumed. Here we charge $0.001 per token: ```javascript const product = { name: "AI Chat Service", code: "chat_service_std", prices: [ { name: "Token Usage", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "message_completed", usage_type: "volume", volume_field: "total_tokens", source_reference_field: "chat_id", }, pricing: [ { asset: "USD", values: [{ volume_rate: 0.001 }], }, ], }, ], publish: true, }; await fetch("https://api.credyt.ai/products", { method: "POST", headers, body: JSON.stringify(product), }); ``` **Dimensional pricing** Different rates based on attributes. Here we charge different rates per model: ```javascript const product = { name: "Multi-Model Chat", code: "chat_multimodel", prices: [ { name: "Token Usage", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "message_completed", usage_type: "volume", volume_field: "total_tokens", billable_dimensions: ["model"], // This is the key for dimensional pricing }, pricing: [ { asset: "USD", values: [ { name: "GPT-4 Tokens", dimensions: { model: "gpt-4" }, values: [{ volume_rate: 0.03 }], }, { name: "GPT-3.5 Tokens", dimensions: { model: "gpt-3.5" }, values: [{ volume_rate: 0.001 }], }, ], }, ], }, ], publish: true, }; ``` ##### Step 3: Create customers[​](#step-3-create-customers "Direct link to Step 3: Create customers") Register customers before billing them. Subscribe them to the products they use. **Key points**: * Use `external_id` to link the Credyt customer to your system's user ID or auth identity * Subscribe customers to products they'll use * Wallets are created automatically * Handle the case where customer already exists (422 error) ```javascript const customer = { name: "Jane Developer", external_id: "user_12345", // Your database user ID or auth provider ID (e.g., Auth0, Clerk) subscriptions: [ { products: [ { code: "video_gen_std", // Product code from Step 2 version: "default", // or specific version number }, ], }, ], }; const response = await fetch("https://api.credyt.ai/customers", { method: "POST", headers, body: JSON.stringify(customer), }); if (response.ok) { const { id: credytCustomerId } = await response.json(); // Store this ID in your database alongside your user record console.log("Customer created:", credytCustomerId); } else if (response.status === 422) { // Customer with this external_id already exists const error = await response.json(); if (error.errors?.external_id) { console.log("Customer already exists, looking up by external_id..."); // Look up existing customer const lookup = await fetch( `https://api.credyt.ai/customers?external_id=user_12345`, { headers }, ); const existingCustomer = await lookup.json(); console.log("Found existing customer:", existingCustomer.id); } } else { console.error("Failed to create customer:", await response.text()); } ``` **Using external IDs in API calls**: You can use your external ID directly when sending usage events, by specifying the `customer_external_id` instead: ```javascript const usageEvent = { customer_external_id: "user_12345", // Your ID for the customer events: [ /* ... */ ], }; await fetch("https://api.credyt.ai/events", { method: "POST", headers, body: JSON.stringify(usageEvent), }); ``` For other API calls, you need the Credyt customer ID. You can look it up by external ID: ```javascript // Look up Credyt ID from your external ID const response = await fetch( "https://api.credyt.ai/customers?external_id=user_12345", { headers }, ); const customer = await response.json(); const credytCustomerId = customer.id; // Now use Credyt ID for wallet operations, etc. await fetch(`https://api.credyt.ai/customers/${credytCustomerId}/wallet`, { headers, }); ``` **Best practice**: Store the Credyt customer ID in your database alongside your user record. This avoids the lookup call on every request. ##### Step 4: Fund customer wallets[​](#step-4-fund-customer-wallets "Direct link to Step 4: Fund customer wallets") Customers need balance before usage can be billed. You have four options. **Option A: Billing portal (self-service)** Easiest option. Customers manage their own top-ups through Credyt's hosted portal. What customers can do: * View balances and usage * Add funds via Stripe * Configure auto top-up * See transaction history No sign-up required. ```javascript // Generate a billing portal session const session = { customer_id: credytCustomerId, return_url: "https://yourapp.com/account", failure_url: "https://yourapp.com/billing-error", }; const response = await fetch(`https://api.credyt.ai/billing-portal/sessions`, { method: "POST", headers, body: JSON.stringify(session), }); const { redirect_url } = await response.json(); // Redirect customer to redirect_url // Link expires in 10 minutes ``` **Option B: Top-up API (your UI + Credyt payments)** Use when you want top-ups in your own UI but use Credyt's payment processing. ```javascript const topup = { customer_id: credytCustomerId, amount: 25.0, currency: "USD", description: "Account credit", return_url: "https://yourapp.com/account", failure_url: "https://yourapp.com/payment-failed", }; const response = await fetch(`https://api.credyt.ai/top-ups`, { method: "POST", headers, body: JSON.stringify(topup), }); const { redirect_url } = await response.json(); // Redirect to Stripe Checkout ``` **Option C: External PSP + Adjustments (your payment processing)** Use when you handle payments through your own payment provider. After successful payment in your PSP: ```javascript const adjustment = { transaction_id: "unique-uuid-or-payment-id", asset: "USD", amount: 25.0, reason: "external_topup", metadata: { psp: "stripe", payment_intent: "pi_abc123", }, }; await fetch( `https://api.credyt.ai/customers/${credytCustomerId}/wallet/adjustments`, { method: "POST", headers, body: JSON.stringify(adjustment), }, ); ``` **Option D: Pre-fund for testing (development only)** Quick way to add balance during development. No payment flows needed. ```javascript const adjustment = { transaction_id: crypto.randomUUID(), asset: "USD", amount: 100.0, reason: "external_topup", metadata: { note: "Test funding" }, }; await fetch( `https://api.credyt.ai/customers/${credytCustomerId}/wallet/adjustments`, { method: "POST", headers, body: JSON.stringify(adjustment), }, ); ``` ##### Step 5: Check balances[​](#step-5-check-balances "Direct link to Step 5: Check balances") Check wallet balances before allowing billable actions. This is the typical pattern. **Best practice**: Check balance first, then authorize the action, then send usage. **Get entire wallet**: ```javascript const response = await fetch( `https://api.credyt.ai/customers/${credytCustomerId}/wallet`, { headers }, ); const { accounts } = await response.json(); // accounts = [ // { id: "default:USD", asset: "USD", available: 14.56 }, // { id: "default:TOKENS", asset: "TOKENS", available: 5000 } // ] ``` **Get specific account**: ```javascript const response = await fetch( `https://api.credyt.ai/customers/${credytCustomerId}/wallet/default:USD`, { headers }, ); const account = await response.json(); // { // id: "default:USD", // asset: "USD", // available: 14.56, // pending_in: 0, // pending_out: 0.5 // } ``` **Implementation pattern**: ```javascript async function canPerformAction(customerId, estimatedCost) { const wallet = await fetch( `https://api.credyt.ai/customers/${customerId}/wallet`, { headers }, ); const { accounts } = await wallet.json(); const usdAccount = accounts.find((a) => a.asset === "USD"); if (!usdAccount || usdAccount.available < estimatedCost) { return { allowed: false, message: "Insufficient balance. Please top up your account.", currentBalance: usdAccount?.available || 0, }; } return { allowed: true }; } // Usage app.post("/api/generate-video", async (req, res) => { const customerId = req.user.credytCustomerId; const estimatedCost = 2.5; // $2.50 per video // 1. Check balance first const check = await canPerformAction(customerId, estimatedCost); if (!check.allowed) { return res.status(402).json({ error: check.message }); } // 2. Perform the action (generate video) const video = await generateVideo(req.body); // 3. Send usage event to bill await sendUsage(customerId, "video_generated", { video_id: video.id }); res.json({ videoId: video.id }); }); ``` ##### Step 6: Send usage events[​](#step-6-send-usage-events "Direct link to Step 6: Send usage events") After confirming balance, perform the action and send usage events. Billing happens in real time. **Requirements**: * Each event needs a unique `id` (idempotency key) * `event_type` must match a product's usage calculation * Include either the Credyt Customer ID (`customer_id`) or your external ID (`customer_external_id`) **Unit-based (charge per occurrence)** ```javascript const usageEvent = { customer_external_id: "user_12345", events: [ { id: crypto.randomUUID(), // Unique ID for idempotency event_type: "video_generated", occurred_at: new Date().toISOString(), subject: "video_abc123", // Reference to the generated video description: "AI video generation completed", data: { video_id: "video_abc123", // Matches source_reference_field }, }, ], }; await fetch("https://api.credyt.ai/events", { method: "POST", headers, body: JSON.stringify(usageEvent), }); ``` **Volume-based (charge based on quantity)** ```javascript const usageEvent = { customer_id: credytCustomerId, events: [ { id: crypto.randomUUID(), event_type: "message_completed", occurred_at: new Date().toISOString(), subject: "chat_session_456", description: "Chat completion", data: { chat_id: "chat_session_456", total_tokens: 1500, // Must match volume_field in product config input_tokens: 500, output_tokens: 1000, }, }, ], }; ``` **Dimensional (pricing varies by attribute)** ```javascript const usageEvent = { customer_id: credytCustomerId, events: [ { id: crypto.randomUUID(), event_type: "message_completed", occurred_at: new Date().toISOString(), subject: "chat_xyz", description: "GPT-4 chat", data: { chat_id: "chat_xyz", total_tokens: 2000, model: "gpt-4", // Billable dimension - matches product config }, }, ], }; ``` #### Advanced topics[​](#advanced-topics "Direct link to Advanced topics") ##### Custom assets implementation[​](#custom-assets-implementation "Direct link to Custom assets implementation") If you decided to use custom assets (see Discovery section 2), the implementation is covered in Step 2 of the Implementation guide above. Quick reminder of the workflow: 1. Create custom asset first (e.g., COINS, CREDITS, MINUTES) 2. Create products that price in that asset 3. Grant credits via Adjustments API or let customers purchase via top-ups ##### Auto top-up[​](#auto-top-up "Direct link to Auto top-up") Customers configure automatic refills via the Billing Portal. Set a threshold (e.g., when balance drops below $10) and a refill amount (e.g., add $50). Each asset can have its own configuration. Requires a saved payment card. ##### Testing payments[​](#testing-payments "Direct link to Testing payments") **Test mode**: * All new accounts start in test mode * Use Stripe test card: `4242 4242 4242 4242` * More test cards: **Going live**: * Switch account to live mode in Credyt Portal * Connect production Stripe account (if using Credyt payments) * Update API key to live key ##### Hybrid billing (subscriptions + entitlements)[​](#hybrid-billing-subscriptions--entitlements "Direct link to Hybrid billing (subscriptions + entitlements)") Credyt supports native hybrid billing that combines recurring subscriptions with bundled credit entitlements. **How it works**: Customers pay a monthly subscription fee and receive a credit allowance each billing cycle. When they exceed their included credits, they purchase additional credits or pay overage fees. Example: "$20/month includes 1,000 credits" **Create a custom asset for credits**: ```javascript const asset = { code: "CREDIT", name: "Credits", precision: 0, symbol: "⭐", label: "CR", rates: [ { source: "USD", rate: 0.05, // $0.05 per credit (or $1 = 20 credits) }, ], }; await fetch(`https://api.credyt.ai/assets`, { method: "POST", headers, body: JSON.stringify(asset), }); ``` **Create hybrid product with entitlements**: ```javascript const product = { name: "Premium Plan", code: "premium_monthly", entitlements: [ { name: "Monthly Credit Allowance", asset: "CREDIT", amount: 1000, // 1,000 credits included purpose: "bundled", refresh: { interval: "month", strategy: "expire_and_replace", // Unused credits don't roll over }, accounting: { revenue_basis: 0, // Revenue from subscription fee cost_basis: "auto", }, }, ], prices: [ { name: "Monthly Subscription Fee", type: "fixed", billing_model: { type: "recurring", recurring: { interval: "month" }, }, pricing: [ { asset: "USD", values: [{ unit_price: 20 }], }, ], }, { name: "Image Generation", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "image_generated", usage_type: "unit", }, pricing: [ { asset: "CREDIT", values: [{ unit_price: 10 }], // 10 credits per image }, ], }, ], publish: true, }; ``` **How consumption works**: 1. Customer pays $20/month 2. Receives 1,000 credits monthly 3. Each image costs 10 credits (can generate 100 images) 4. When credits run out, they purchase more at $0.05/credit 5. Credits expire each month (no rollover) **Subscribe customers**: ```javascript const customer = { name: "Jane Developer", external_id: "user_12345", email: "jane@example.com", subscriptions: [ { products: [{ code: "premium_monthly" }], }, ], }; const response = await fetch(`https://api.credyt.ai/customers`, { method: "POST", headers, body: JSON.stringify(customer), }); const data = await response.json(); // Check if payment is required if (data.subscriptions[0].status === "pending") { const redirectUrl = data.subscriptions[0].required_actions.find( (a) => a.type === "payment", ).redirect_url; // Redirect customer to complete payment } ``` Credyt handles billing cycles, credit grants, and consumption tracking automatically. **Using external PSP for subscriptions**: If you process subscriptions through your own payment provider, reflect payments in Credyt using Adjustments: ```javascript // When subscription payment succeeds in your PSP: const adjustment = { transaction_id: `sub_payment_${subscriptionId}`, asset: "USD", amount: 29.99, reason: "external_topup", description: "Monthly subscription", }; await fetch( `https://api.credyt.ai/customers/${customerId}/wallet/adjustments`, { method: "POST", headers, body: JSON.stringify(adjustment), }, ); ``` Then send usage events as normal. They deduct from the wallet balance. ##### Refunds[​](#refunds "Direct link to Refunds") Credyt doesn't handle refunds automatically. **Process**: 1. Process refund in your PSP (or Stripe if using Credyt payments) 2. Notify Credyt via Adjustments API ```javascript const refund = { transaction_id: `refund_${originalPaymentId}`, asset: "USD", amount: -20.0, // Negative amount reason: "external_refund", description: "Refund for technical issue", }; await fetch( `https://api.credyt.ai/customers/${customerId}/wallet/adjustments`, { method: "POST", headers, body: JSON.stringify(adjustment), }, ); ``` ##### Cost tracking (profitability)[​](#cost-tracking-profitability "Direct link to Cost tracking (profitability)") Track infrastructure costs alongside revenue. ```javascript const usageEvent = { customer_id: customerId, events: [ { id: crypto.randomUUID(), event_type: "video_generated", occurred_at: new Date().toISOString(), subject: "video_123", description: "Video generation", data: { minutes: 2, model: "sora-fast", }, costs: [ { // Optional cost tracking id: crypto.randomUUID(), vendor_external_id: "vnd_openai_123", description: "OpenAI Sora API", amount: 0.16, currency: "USD", metadata: { model: "sora-fast", resolution: "1080p", }, }, ], }, ], }; ``` Credyt will calculate profitability metrics (gross revenue, costs, net revenue, margin). [More information](https://docs.dev.credyt.ai/features/profitability.md) ##### Standalone wallets (in-app economies)[​](#standalone-wallets-in-app-economies "Direct link to Standalone wallets (in-app economies)") Credyt's wallet API works for in-app economies where users earn and spend points without traditional payments. **Common use cases**: * Game currencies where players earn coins through gameplay * Reward programs where users accumulate points * Community platforms with reputation or karma systems * Referral programs that grant credits > **Critical**: Create your custom asset (COINS, POINTS, etc.) BEFORE granting credits or creating products. See Step 2 for how to create assets. **Setup** (do this once): ```javascript // 1. Create the custom asset first const asset = { code: "COINS", name: "Game Coins", precision: 0, symbol: "🪙", label: "COINS", rates: [ { source: "USD", rate: 0.01, // Not used if you never collect payments, but required }, ], }; await fetch("https://api.credyt.ai/assets", { method: "POST", headers, body: JSON.stringify(asset), }); // 2. Create a product that prices items in coins const product = { name: "In-Game Items", code: "game_items", prices: [ { name: "Power-Up Purchase", type: "usage_based", billing_model: { type: "real_time" }, usage_calculation: { event_type: "item_purchased", usage_type: "unit", }, pricing: [ { asset: "COINS", values: [{ unit_price: 100 }], // 100 coins per item }, ], }, ], publish: true, }; await fetch("https://api.credyt.ai/products", { method: "POST", headers, body: JSON.stringify(product), }); ``` **When users earn coins** (grant credits): ```javascript // User completes a quest - grant 500 coins const adjustment = { transaction_id: `quest_completed_${questId}_${userId}`, asset: "COINS", // Must match the asset code you created amount: 500, reason: "gift", description: "Quest completion reward", }; await fetch( `https://api.credyt.ai/customers/${customerId}/wallet/adjustments`, { method: "POST", headers, body: JSON.stringify(adjustment), }, ); ``` **When users spend coins**: Send usage events that deduct from their balance. ```javascript const usageEvent = { customer_id: customerId, events: [ { id: crypto.randomUUID(), event_type: "item_purchased", occurred_at: new Date().toISOString(), subject: `purchase_${itemId}`, description: "Power-up purchased", data: { item_id: itemId, item_name: "Speed Boost", }, }, ], }; await fetch("https://api.credyt.ai/events", { method: "POST", headers, body: JSON.stringify(usageEvent), }); ``` This gives you a reliable balance system without building wallet infrastructure yourself. #### Code Examples and Resources[​](#code-examples-and-resources "Direct link to Code Examples and Resources") ##### Bruno API Collection[​](#bruno-api-collection "Direct link to Bruno API Collection") Interactive API examples available at: * GitHub: * Download and import into Bruno () ##### Sample Integration Patterns[​](#sample-integration-patterns "Direct link to Sample Integration Patterns") **Express.js Middleware Example:** ```javascript const credytClient = { apiKey: process.env.CREDYT_API_KEY, baseUrl: "https://api.credyt.ai", async checkBalance(customerId) { const response = await fetch( `${this.baseUrl}/customers/${customerId}/wallet`, { headers: { "X-CREDYT-API-KEY": this.apiKey } }, ); return response.json(); }, async sendUsage(customerId, eventType, data) { const event = { customer_id: customerId, events: [ { id: crypto.randomUUID(), event_type: eventType, occurred_at: new Date().toISOString(), subject: data.subject, description: data.description, data: data.payload, }, ], }; return fetch(`${this.baseUrl}/events`, { method: "POST", headers: { "Content-Type": "application/json", "X-CREDYT-API-KEY": this.apiKey, }, body: JSON.stringify(event), }); }, }; // Middleware to check balance before expensive operations async function requireSufficientBalance(req, res, next) { const customerId = req.user.credytCustomerId; const { accounts } = await credytClient.checkBalance(customerId); const usdAccount = accounts.find((a) => a.asset === "USD"); if (!usdAccount || usdAccount.available < 1.0) { return res.status(402).json({ error: "Insufficient balance", balance: usdAccount?.available || 0, topUpUrl: `/billing/top-up`, }); } next(); } // Usage app.post("/api/generate-video", requireSufficientBalance, async (req, res) => { // Generate video... // Bill for usage await credytClient.sendUsage(req.user.credytCustomerId, "video_generated", { subject: `video_${videoId}`, description: "Video generation", payload: { minutes: 2, quality: "hd" }, }); res.json({ videoId, status: "processing" }); }); ``` #### Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") ##### Customer not billed for usage[​](#customer-not-billed-for-usage "Direct link to Customer not billed for usage") **Check**: 1. Is customer subscribed to a product? (`GET /customers/:id`) 2. Does product have matching `event_type`? 3. For volume pricing: does `volume_field` match event data? 4. Is event ID unique? (Duplicates are ignored) 5. Does customer have wallet balance? **Test without affecting balances**: ```javascript const simulation = await fetch( `https://api.credyt.ai/products/:productId/simulate`, { method: "POST", headers, body: JSON.stringify({ events: [ /* your test event */ ], }), }, ); ``` ##### Negative balance[​](#negative-balance "Direct link to Negative balance") This is expected behavior. Credyt allows overdrafts by default so usage can complete without interruption. Check balance according to your business logic. The next top-up automatically corrects the negative balance. ##### No wallet or accounts[​](#no-wallet-or-accounts "Direct link to No wallet or accounts") Wallets are created automatically when: * Customer is subscribed to a product, OR * First top-up is initiated **Fix**: Ensure customer has at least one product subscription. ##### Billing portal link expired[​](#billing-portal-link-expired "Direct link to Billing portal link expired") Links expire after 10 minutes. When expired, the customer is redirected to your `return_url`. **Best practice**: Detect the redirect, generate a new session automatically, and redirect the customer back. #### Key reminders[​](#key-reminders "Direct link to Key reminders") ##### Security[​](#security "Direct link to Security") * API keys are server-side only * Never expose keys in client code * Use environment variables * Test mode and live mode use different keys ##### Testing[​](#testing "Direct link to Testing") * Start in test mode (default for new accounts) * Use Stripe test cards: * Pre-fund wallets with adjustments for quick testing * Test the full flow before going live ##### Product design[​](#product-design "Direct link to Product design") * Define products once as setup (not per-request) * Use `source_reference_field` for traceability * Include meaningful `subject` in usage events * Send usage for all activities initially, price later ##### Best practices[​](#best-practices "Direct link to Best practices") * Check balance before expensive operations * Use idempotent event IDs (UUIDs) * Store both Credyt customer ID and your external ID * Monitor wallet balances to prevent service interruption * Provide clear billing portal access for customers #### Next steps[​](#next-steps "Direct link to Next steps") **1. Connect Stripe** (if using Credyt payments) * Enables custom branding in checkout * Allows tax configuration * Required for production **2. Set up monitoring** * Track usage patterns * Monitor wallet balances * Review profitability metrics **3. Customize billing portal** * Add your branding * Configure return URLs * Test the customer experience **4. Plan for scale** * Consider auto top-up for power users * Design balance notification system * Plan for cost optimization #### Getting Help[​](#getting-help "Direct link to Getting Help") * **Documentation**: * **API Reference**: * **Support**: * **Examples**: #### Integration checklist[​](#integration-checklist "Direct link to Integration checklist") When guiding a user through Credyt integration: * Understand their monetization model (usage-based, subscription, hybrid) * Identify billable events and pricing dimensions * Confirm Credyt account setup and API key access * Define products and pricing configuration * Create customers and subscriptions * Implement wallet funding (portal, API, or external) * Send usage events from application * Check balances before billable actions * Test complete flow in test mode * Verify security (API keys server-side only) * Plan production deployment (Stripe connection, live mode) --- ## Category ### Advanced Topics #### [📄️ Refunds](https://docs.dev.credyt.ai/advanced-topics/refunds.md) [Credyt does not process refunds directly. Initiate them through your PSP or Stripe Dashboard, then notify Credyt via the Wallet Adjustments API using a negative amount.](https://docs.dev.credyt.ai/advanced-topics/refunds.md) --- ### Features #### [🗃️ Products and Pricing](https://docs.dev.credyt.ai/features/product-catalog.md) [3 items](https://docs.dev.credyt.ai/features/product-catalog.md) --- ### Partners #### [📄️ Credyt for Platforms](https://docs.dev.credyt.ai/partners/platforms-overview.md) [Credyt for Platforms lets you embed real-time billing inside your product via Connected Accounts. Isolated API access, webhooks, and quickstart guide included.](https://docs.dev.credyt.ai/partners/platforms-overview.md) --- ### Quickstart #### [📄️ Introduction](https://docs.dev.credyt.ai/quickstart.md) [Get started with Credyt. This guide walks you from creating your first customer to sending real-time usage events and checking wallet balances, step by step in minutes.](https://docs.dev.credyt.ai/quickstart.md) --- ### Use Cases #### [📄️ Fiat vs Custom Units](https://docs.dev.credyt.ai/use-cases/fiat-vs-custom-units.md) [Understand when to use fiat wallet accounts (USD/EUR) vs. custom unit accounts (tokens, minutes) and how a single customer wallet can hold and manage both simultaneously.](https://docs.dev.credyt.ai/use-cases/fiat-vs-custom-units.md) --- ## Concepts ### Concepts & Terminology A guide to the core primitives, resources, and terminology used throughout the Credyt product. #### Customers[​](#customers "Direct link to Customers") Customers represent your end users in Credyt. Before billing can occur, you must register customers and subscribe them to products. When creating a customer, you can provide your own unique identifier (`external_id`) which can then be used when submitting usage events. **Key points:** * Customers are created via the Customers API * They must be subscribed to products to be billed * Can use either Credyt's customer ID or your own external ID * No extensive personal data required - only what's needed for identification and billing #### Products and Pricing[​](#products-and-pricing "Direct link to Products and Pricing") Products define what you're billing for and how customers are charged. Each product has a unique code and contains one or more prices that determine billing behavior. ##### Prices[​](#prices "Direct link to Prices") Prices are the building blocks of your billing configuration. Each price defines what event type triggers billing, how usage is measured, and the rates charged. **Price Types:** A price can be either: * **Usage-based**: Charges based on actual consumption or events. Usage-based prices track and bill for customer activity as it happens - such as API calls, tokens consumed, minutes processed, or tasks completed. * **Fixed**: Flat fees that don't vary with usage (e.g., monthly platform fee, seat license). These are billed as a set amount regardless of consumption. ##### Billing Models[​](#billing-models "Direct link to Billing Models") Each price has a billing model that determines *when* charges are applied: * **Real-time**: Usage is billed immediately as events occur, deducting from the customer's wallet balance in real-time. This ensures customers always know their current balance and can't consume more than their available funds (plus any configured overdraft). * **Recurring**: Usage accumulates over a billing period (typically monthly) and is billed at the end of that period. This is common for post-paid or invoice-based billing scenarios. ##### Usage Calculation[​](#usage-calculation "Direct link to Usage Calculation") For usage-based prices, the usage calculation configuration determines how usage is measured: * **Unit-based**: Charges per occurrence of an event (e.g., $0.50 per video promoted, $2 per API call) * **Volume-based**: Charges based on quantity consumed in the event payload (e.g., $0.001 per token, $0.10 per minute) * **Unit and Volume**: Combines both approaches (e.g., $0.05 per chat + $0.0001 per token used in that chat) ##### Dimensional Pricing[​](#dimensional-pricing "Direct link to Dimensional Pricing") Prices can optionally vary based on attributes of the usage event, such as: * Speed tier (fast vs regular) * Quality level (standard vs premium) * Model type (GPT-4 vs GPT-3.5) This allows a single price to handle multiple variations without creating separate price configurations. #### Subscriptions[​](#subscriptions "Direct link to Subscriptions") Subscriptions link customers to products, determining which pricing applies to their usage. When you subscribe a customer to a product, Credyt automatically provisions wallet accounts in the billing currencies defined by the product's pricing. **Important:** Subscriptions in Credyt are distinct from traditional recurring subscription payments. They represent which products a customer has access to, not necessarily a recurring payment commitment. #### Wallets and Accounts[​](#wallets-and-accounts "Direct link to Wallets and Accounts") Every customer has one wallet that can contain multiple accounts, each tracking a specific asset. ##### Wallets[​](#wallets "Direct link to Wallets") A wallet is the container for all of a customer's balance accounts. It's created automatically when a customer is subscribed to a product or initiates their first top-up. ##### Accounts[​](#accounts "Direct link to Accounts") Accounts hold balances in specific assets (currencies or custom units). They are provisioned automatically based on the products a customer subscribes to. Each account tracks: * Available balance * Pending incoming funds * Pending outgoing charges Accounts support overdrafts by default to ensure usage can be billed even when balances are low. #### Assets[​](#assets "Direct link to Assets") Assets are the units of value used for billing. They can be: * **Fiat currencies** (USD, EUR, etc.) * **Custom units** you define (tokens, minutes, credits, etc.) For custom assets, you define exchange rates from fiat currencies. These rates determine how much of your custom asset customers receive when topping up. Exchange rates can be updated and scheduled for future effective dates. #### Top-ups and Auto Top-up[​](#top-ups-and-auto-top-up "Direct link to Top-ups and Auto Top-up") ##### Top-ups[​](#top-ups "Direct link to Top-ups") Top-ups are how customers add funds to their wallet accounts. They can be initiated: * Through the Billing Portal (self-service) * Via the Top-up API (integrated into your product) * Externally through your own PSP (reflected via Adjustments) When using Credyt's payment processing, top-ups are handled through Stripe Checkout. ##### Auto Top-up[​](#auto-top-up "Direct link to Auto Top-up") Auto top-up keeps wallets funded automatically by defining balance thresholds and recharge amounts per asset. When a balance drops below the threshold, Credyt initiates an off-session payment and credits the wallet. **Configuration:** * Set per asset in the Billing Portal * Requires saved payment card authorization * Prevents service interruption during variable usage #### Credit Grants[​](#credit-grants "Direct link to Credit Grants") Credit grants are the fundamental units of a prepaid balance. Rather than treating a wallet as one undifferentiated pool, Credyt tracks each discrete allocation of value separately. **Each grant defines:** * Effective and expiry dates * Amount of value * Purpose (paid, promotional, included) * How it should be treated for revenue recognition **Key characteristics:** * Created from top-ups, adjustments, or entitlements * Consumed according to platform-defined rules * Enable proper revenue recognition at consumption * Support time-limited promotional credits * Remain auditable even after expiry #### Entitlements[​](#entitlements "Direct link to Entitlements") Entitlements are "right-to-use" grants that represent bundled allocations included with a product subscription. Unlike direct credit purchases, entitlements decouple service access from payment and enable hybrid billing models that combine recurring fees with usage-based pricing. **How entitlements work:** When a customer subscribes to a product with entitlements, Credyt automatically: * Grants the specified credit amount to the customer's wallet * Refreshes this allowance according to your defined schedule (daily, monthly, etc.) * Tracks consumption against the entitlement balance * Charges overage fees when credits are exhausted **Entitlement types:** * **Bundled entitlements**: Credits included as a feature of a fixed-fee plan (e.g., "$20/month includes 1,000 credits"). The subscription fee is recognized ratably while the credit value typically has a revenue basis of $0. * **Promotional entitlements**: Free credits granted to incentivize signups, login streaks, or referrals. No revenue is recognized. These track a cost basis to record marketing expense when consumed. **Key characteristics:** * Can grant credits in fiat currency or custom assets * Support flexible refresh strategies (expire-and-replace, rollover) * Enable priority-based consumption rules (e.g., use promotional credits before bundled credits) * Integrate with revenue recognition for proper accounting * Enable hybrid billing models combining subscriptions with usage overages #### Payments[​](#payments "Direct link to Payments") Payments in Credyt are processed through Stripe. When using Credyt's built-in payment processing: * Customers complete checkout via Stripe's hosted interface * Payment confirmation automatically updates wallet balances * All payment data and PCI compliance is handled by Stripe * Platforms can connect their own Stripe account or use Credyt's for testing For platforms using external PSPs, payments are reflected in Credyt via the Adjustments API. #### Adjustments[​](#adjustments "Direct link to Adjustments") Adjustments allow direct manipulation of account balances outside normal usage processing. They're used for: * External PSP payments (subscriptions, top-ups) * Refunds * Promotional credits and gifts * Manual corrections Each adjustment requires: * A unique transaction ID (idempotency key) * A reason code (external\_topup, external\_refund, gift, other) * The asset and amount * Optional expiry date and metadata #### Fees[​](#fees "Direct link to Fees") Fees are charges generated when usage events are processed. They represent the actual billable amount deducted from a customer's wallet. **Fees include:** * Product and price references * Calculated amounts based on usage * Dimensional attributes (if applicable) * Usage type (unit, volume, or both) * Description of what was billed Fees are created automatically when usage events match product pricing configurations. #### Billing Portal[​](#billing-portal "Direct link to Billing Portal") The Billing Portal is a hosted, self-service interface where customers can: * View wallet balances across all assets * See usage history and charges * Review transaction history * Initiate top-ups * Configure auto top-up settings * Manage saved payment cards **Access:** * No customer sign-up required * Accessed via pre-authenticated session links * Sessions expire after 10 minutes if unused * Fully customizable with your branding #### Vendors[​](#vendors "Direct link to Vendors") Vendors represent external services or infrastructure that power your product (AI model providers, compute platforms, third-party APIs). They're used in profitability tracking to correlate costs with revenue. #### Costs[​](#costs "Direct link to Costs") Costs represent expenses incurred from vendors when serving usage. They're attached to usage events to enable profitability analysis. **Costs can be attributed at:** * Customer level * Event level * Subject level (task or outcome) When combined with revenue from fees, costs enable calculation of gross revenue, net revenue, and margin per event, customer, or product. --- ## Faqs ### Frequently asked questions #### Architecture and fit[​](#architecture-and-fit "Direct link to Architecture and fit") **What is Credyt and who is it built for?** Credyt is real-time billing infrastructure for AI products. It's built for teams that charge for usage in real time — tokens, API calls, compute time, GPU hours — and need customers to prepay and manage their own balances. If you're building a usage-heavy product and don't want to front infrastructure costs or build wallet logic from scratch, Credyt is designed for you. **How is Credyt different from tools like Stripe Billing or Lago?** Most billing platforms are invoice-native. Usage accumulates throughout a billing period and payment is collected at cycle end. Credyt is wallet-native: customers prepay, and usage is authorized and debited in real time as it happens. There's no invoice cycle, no end-of-period reconciliation, and no risk of fronting costs you haven't collected yet. **Why does real-time billing matter for AI products specifically?** AI workloads incur real infrastructure costs with every API call, token, or model inference. Those costs happen continuously and can spike without warning. If you're billing in arrears, you're absorbing those costs before you've collected payment. Real-time billing flips that: usage is authorized before it runs, and funds are deducted immediately. You stay in control of margins at the point of consumption, not after the fact. **What does wallet-native architecture actually mean?** In most billing systems, wallets or credit accounts are a feature layered on top of invoices. In Credyt, the wallet is the billing system. Every customer gets a wallet from day one. Credits, balances, grants, and entitlements are first-class concepts with lifecycle management, expiry, and consumption ordering. There's no invoice generation step. The wallet is where authorization, deduction, and balance tracking all happen. **Is Credyt suitable for B2C products, or is it only for B2B?** Credyt works for both. It's particularly well suited to self-serve models where end users purchase and manage usage directly, without finance department involvement. The self-service portal is built for individual users and small teams, not for accounts payable workflows. If you're building a consumer-facing AI product with prepaid credits, the architecture fits naturally. *** #### Pricing and billing models[​](#pricing-and-billing-models "Direct link to Pricing and billing models") **Can I bill customers in tokens, GPU hours, or other custom units instead of dollars?** Yes. Credyt supports native custom assets. You define pricing in any unit that maps to your product: tokens, GPU hours, video minutes, API credits. Customers hold and spend balances in those units. You're not forced to convert everything to a generic credit type behind the scenes. Different asset types can have independent pricing rules and live side by side in one customer wallet. **How does Credyt pricing work?** Credyt charges per Monthly Active Wallet (MAW) with no upfront fees and no fixed platform costs. The first 10 MAWs per month are free. For built-in payment processing, PSP fees are passed through directly with no markup. What you pay the processor is what you pay. **Can I track which customers are actually profitable, not just how much they're spending?** Yes. Credyt ingests both usage events and their associated infrastructure costs, so you can see margin at the event level. You can track profitability per customer, per feature, or per workload in real time. This matters when infrastructure costs vary significantly by model, task type, or customer behavior, and you need to make pricing decisions based on actual margins rather than estimates. **Does Credyt support credit grants and free trial credits?** Yes. You can issue grants with defined purposes, expiry dates, and spending rules. Grants are first-class primitives in the wallet — not just invoice line items. You can use them for onboarding credits, referral rewards, retention campaigns, or limited-time promotions. Consumption ordering is explicit and deterministic: you define how grants are applied, and it works the same way every time. **Can I give customers a hybrid model with a monthly subscription plus usage on top?** Yes. Credyt supports hybrid billing: a flat-fee subscription combined with wallet top-ups and usage-based charges. Subscription entitlements can be bundled into the wallet at the start of each period, and overage is drawn from the customer's prepaid balance. You don't have to choose between recurring revenue and usage-based billing. **What pricing models does Credyt support?** Credyt supports event-based pricing (per occurrence), volume-based pricing, dimensional pricing (different rates based on usage attributes like model type or output format), and hybrid models that combine flat fees with usage charges. You define pricing rules via API. Rates apply automatically when usage events arrive. No hardcoded pricing logic in your application. *** #### Balance control and customer experience[​](#balance-control-and-customer-experience "Direct link to Balance control and customer experience") **How do I stop customers from going into debt or running up costs I can't collect?** Credyt authorizes every usage event before costs are incurred. When a customer attempts an action, your product checks their wallet balance in real time and approves or denies the request. If the balance is insufficient, the request is blocked. You prevent negative balances at the point of consumption rather than discovering exposure after the fact. **What happens when a customer's balance runs out mid-session?** Customers can set up automatic top-ups that trigger when their balance drops below a threshold they define. They control the threshold amount, top-up amount, and payment method through the self-service portal. Top-ups are processed immediately, so service continues without interruption. If auto top-up isn't configured, the balance hits zero and your product denies further usage until the customer adds funds. **Can my customers manage their own balance and top-ups?** Yes. Credyt includes a drop-in branded billing portal that customers access directly. They can view real-time balances, see live usage, add funds, configure automatic top-ups with threshold triggers, and manage payment methods. No custom frontend work required on your side, and no support tickets to manage routine billing tasks. **Do I need to build my own customer-facing billing UI?** No. The Credyt billing portal is a drop-in component you embed in your product. It shows real-time balances, live usage, transaction history, top-up flows, and payment method management out of the box. No custom frontend work required on your side. *** #### Integration and implementation[​](#integration-and-implementation "Direct link to Integration and implementation") **Does Credyt work alongside my existing billing setup, or do I have to replace it?** Credyt is designed to extend your existing stack, not replace it. If you use Stripe for subscriptions, you keep using it. Credyt adds the real-time authorization and wallet layer that invoice-based systems weren't built to provide. Both systems run alongside each other without conflict. **How long does it take to integrate Credyt?** Most teams ship in days. Credyt's API-first design means you're sending usage events, defining pricing rules, and embedding the billing portal rather than rebuilding billing infrastructure. You get wallet management, payment processing, and the customer portal out of the box. **Can I run prepaid wallets for some customers and invoice-based billing for others?** Yes. The two models can coexist. Use your existing subscription and invoicing tools for customers who prefer monthly billing. Use Credyt's wallet-based authorization for customers who want prepaid, real-time control. Each system handles its own customers without interfering with the other. **What if some enterprise customers need invoices?** Credyt can issue receipts through Stripe for completed transactions, but it doesn't provide full invoice management workflows — payment terms, dunning, collection processes. For customers who require invoices before payment, you'd use a dedicated invoicing tool alongside Credyt. Credyt handles the prepaid, real-time side. Your invoicing tool handles the accounts payable side. **Can I test my pricing configuration before going live?** Yes. Credyt has a test environment that's fully isolated from production, with a separate set of API credentials. You can create test customers, send simulated usage events, and validate pricing rules without affecting real customer data. Work in test mode until you're confident in the configuration, then switch to live. --- ## Partners ### Credyt for Platforms Preview Feature Credyt for Platforms is currently in preview. Please contact our [support team](mailto:support@credyt.ai) for access. #### Overview[​](#overview "Direct link to Overview") Credyt for Platforms (C4P) enables software platforms to embed Credyt's capabilities into their own products. Typical use-cases include: * Traditional invoice-native billing platforms looking to introduce real-time, usage-based billing and credit accounts * Commerce platforms wishing to introduce reward programs and store credit capabilities * Fintech platforms who need flexible wallet infrastructure to store and move value * Marketplaces with advanced money flows or a need to unify both open and closed-loop payments With C4P, each of your customers (or merchants) has a fully partitioned Credyt account with access to the capabilities you enable. Your customers can then create their own products, register their customers and bill them for usage, or interact with customer wallets directly. #### Integration[​](#integration "Direct link to Integration") ##### Account Structure[​](#account-structure "Direct link to Account Structure") Your customers exist in C4P as a *Connected Account* under your main platform account. Connected Accounts are unique per environment, so you may safely test in isolation. Connected Accounts can optionally be configured with their own wallets under your platform's management account. This if often desirable if you wish to implement usage-based billing for your own customers. ##### Security[​](#security "Direct link to Security") Integration between partners and Credyt is API-based. API access is secured using your platform's API key. The target connected account is specified via the `X-CREDYT-ACCOUNT` header. note At this stage we do not support API access directly from a connected account. Credyt API requests should always be initiated from your environment. Additionally you can access the Credyt Portal as the connected account for easy access to their account state and activity. ##### Actors and their interaction[​](#actors-and-their-interaction "Direct link to Actors and their interaction") Activities that use Credyt typically involve the following actors: 1. Your Customer's Customer (referred to as the *End User* in this context) 2. Your Customer 3. Your Platform 4. Credyt Interaction between these actors is typically sequential making Credyt invisible to your customers and the end user. ##### Example[​](#example "Direct link to Example") The following sequence of interactions would take place when the end-user performs a billable activity. 1. End user performs billable activity e.g. "Generate image" 2. Customer submits usage events to your platform 3. Your platform validates and identifies the customer 4. Your platform forwards usage events to Credyt 5. Credyt calculates any usage fees and debits the end user's wallet 6. Credyt may additionally send key events (such as low balance thresholds) to your platform via Webhook The complexity of your integration with Credyt will vary on how embedded our capabilities are into your existing products. In many cases it may be as simple as building a lightweight mapping and proxy layer between the two systems. ##### Webhooks[​](#webhooks "Direct link to Webhooks") To receive notifications of key events and activities within your connected accounts, you can register a webhook endpoint that specifically receives C4P activity. The webhook payload will include the Connected Account's ID so that you can correlate to your customer and take the necessary action. This is the pattern typically used by billing providers to trigger automatic wallet top-ups in response to low threshold events: Balance Threshold webhook ```json { "id": "whe_48b9cet5d6h6vf2rwg4w3ezkw2", "account": "acc_4y7dxxqt8dzzpf4w58te001zxb", "event_type": "balance_threshold_hit", "occurred_at": "2026-01-07T13:19:18.265Z", "data": { "customer_id": "cust_4tqzchnwchbwf87m7g86pw0xmm", "account_id": "default:USD", "available": 9.24, "threshold": 10.0 } } ``` #### Quickstart[​](#quickstart "Direct link to Quickstart") ##### Create a webhook for C4P[​](#create-a-webhook-for-c4p "Direct link to Create a webhook for C4P") Create a new webhook endpoint to receive events from your connected accounts: POST https://api.credyt.ai/webhooks ```json { "url": "https://integrations.tradbill.com/credyt/c4p", "connect": true } ``` ##### Create a connected account[​](#create-a-connected-account "Direct link to Create a connected account") Before you customer can begin using Credyt's capabilities they must be set up as a connected account: POST https://api.credyt.ai/accounts ```json { "name": "BingoLingo", "external_id": "4bc6fbfc5493" } ``` **Response** ```json { "id": "acc_4tvras4k598tdb256atm8axemw" } ``` ##### Create a customer (the end user)[​](#create-a-customer-the-end-user "Direct link to Create a customer (the end user)") Each of your customer's customers (the end user) should be created as a `customer` object under the connected account, by specifying the `X-CREDYT-ACCOUNT` header: Create Customer on Connect Account ```bash curl --request POST \ --url https://api.credyt.ai/customers \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' \ -H 'X-CREDYT-ACCOUNT: acc_4tvras4k598tdb256atm8axemw' \ --data '{ "name": "Francis Gutmann DDS", "external_id": "b7bac50a20bf44aa893bfd614d7631ae" }' ``` *Response* ```json { "id": "cust_4s8epv6ej86aeep682pmcbhhm6" } ``` ##### Add credit to the end-user's wallet[​](#add-credit-to-the-end-users-wallet "Direct link to Add credit to the end-user's wallet") Suppose you're a billing platform and wish to credit the end-user's wallet each time a subscription payment is collected. This can be achieved by using the Wallet API: Credit Customer Balance ```bash curl --request POST \ --url https://api.credyt.ai/customers/:customerId/wallet/adjustments \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' \ -H 'X-CREDYT-ACCOUNT: acc_4tvras4k598tdb256atm8axemw' \ --data '{ "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "asset": "USD", "amount": 20, "reason": "external_topup", "metadata": { "payment_id": "4c81c0ff-d050-4e85-b111-13a7f3f251fa" } }' ``` #### Using other APIs[​](#using-other-apis "Direct link to Using other APIs") We invite you to explore the broader Credyt documentation for details on how to interact with Credyt on behalf of your customers. #### Restrictions[​](#restrictions "Direct link to Restrictions") The following capabilities are restricted or not yet supported. ##### Direct API Access[​](#direct-api-access "Direct link to Direct API Access") It is not possible to create API keys for connected accounts. API access is only granted via your platform's API Keys and the specified `X-CREDYT-ACCOUNT` header. ##### Webhooks[​](#webhooks-1 "Direct link to Webhooks") You can not create webhook endpoints for a specific connected account. You can however, create a webhook endpoint on your platform account that subscribes to connect account events, as described [here](#create-a-webhook-for-c4p). ##### Top-ups[​](#top-ups "Direct link to Top-ups") Currently top-ups via our built-in Stripe integration are not supported on connected accounts. Instead platforms using C4P must implement payment processing themselves. If you require this functionality please [contact support](mailto:support@credyt.ai). --- ## Pricing Guide ### Pricing Guide Real-time usage-based billing (UBB) works differently from traditional SaaS. While conventional billing meters usage and invoices monthly, AI-native products incur costs immediately - with every API call, token generated, or GPU second consumed. This fundamental difference shapes how you should approach pricing. Credyt supports three pricing models that align with how AI-native products actually deliver and consume value. Each model serves different product strategies and customer expectations. #### Supported Pricing Models[​](#supported-pricing-models "Direct link to Supported Pricing Models") ##### 1. Real-time usage-based billing from pre-paid balances[​](#1-real-time-usage-based-billing-from-pre-paid-balances "Direct link to 1. Real-time usage-based billing from pre-paid balances") Customers fund their wallet upfront with either fiat currency or custom assets (tokens, credits, minutes). Usage draws down from their balance in real time. When balance hits zero, service stops or triggers automatic top-up. **How it works in Credyt:** Customers top up their wallet through the [Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md) or via the [Top-up API](https://docs.dev.credyt.ai/features/wallets-and-topups.md). Balances can be held in standard currencies (USD, EUR) or [custom assets](https://docs.dev.credyt.ai/features/assets.md) you define. As usage occurs, their balance is debited immediately. Customers can enable [auto top-up](https://docs.dev.credyt.ai/features/auto-topup.md) to refill their balances automatically when they fall below a threshold. **Who uses this model:** OpenAI API, Anthropic Claude API, Replicate, ElevenLabs, and most LLM providers. Common with developer-focused products where customers understand marginal costs. **When to choose this:** * You sell tokens, API calls, or compute time * Infrastructure costs are variable and unpredictable * Cash flow protection is critical * You can't afford to front costs for customers * Your customer base includes developers who expect pay-as-you-go pricing **Implementation in Credyt:** Define products with `type: usage-based`and`billing_model.type: real_time` in your [product catalog](https://docs.dev.credyt.ai/features/product-catalog.md). Usage events immediately debit the customer's wallet. For more complex scenarios where pricing varies based on characteristics of the usage (like AI model type, speed, or quality), use [dimensional pricing](https://docs.dev.credyt.ai/features/product-catalog/dimensional-pricing.md) to define different rates for different usage attributes. See our [Topups Only Model guide](https://docs.dev.credyt.ai/use-cases/top-ups-only-model.md) for further details. ##### 2. Recurring fixed fee (subscriptions)[​](#2-recurring-fixed-fee-subscriptions "Direct link to 2. Recurring fixed fee (subscriptions)") Customers pay a fixed amount on a recurring cycle. This provides predictable baseline revenue while you figure out usage-based pricing. **How it works in Credyt:** Credyt supports [fixed fee pricing](https://docs.dev.credyt.ai/features/product-catalog/fixed-fee-pricing.md) natively, allowing you to charge recurring subscription fees directly. While Credyt was designed primarily for usage-based billing, recurring fees serve as an ideal starting point when you're still determining how to price usage. **Why start here:** Beginning with fixed subscriptions lets you generate immediate revenue while building understanding of your cost structure. You can send usage events and associated costs to Credyt without charging for them yet. Using [Profitability analysis](https://docs.dev.credyt.ai/features/profitability.md), you track revenue against actual infrastructure costs per customer, giving you the data needed to confidently transition to usage-based pricing when ready. **Who uses this model:** Traditional SaaS companies, products prioritizing predictable revenue, or platforms in the early stages of introducing usage-based pricing. **When to choose this:** * You need baseline revenue but aren't ready to price usage yet * You want to understand cost structures before charging for usage * You're planning to transition to usage-based pricing gradually * Enterprise customers require predictable billing cycles * You're still validating product-market fit **Implementation in Credyt:** Configure products with fixed fee pricing following the [fixed fee pricing guide](https://docs.dev.credyt.ai/features/product-catalog/fixed-fee-pricing.md). Send usage events to track consumption patterns and costs, then use profitability metrics to inform your eventual usage-based pricing model. ##### 3. Hybrid billing (subscriptions + entitlements + top-ups)[​](#3-hybrid-billing-subscriptions--entitlements--top-ups "Direct link to 3. Hybrid billing (subscriptions + entitlements + top-ups)") Base subscription provides predictable revenue and includes usage [entitlements](https://docs.dev.credyt.ai/features/product-catalog/entitlements.md). Additional usage beyond the entitlement can be purchased through top-ups or charged additionally. **How it works in Credyt:** Combine [fixed fee pricing](https://docs.dev.credyt.ai/features/product-catalog/fixed-fee-pricing.md) with usage-based charges. Subscriptions provide base access and bundled usage allowances through entitlements. When customers exceed their entitlement, they either top up for additional usage or are charged for overages. Both subscription entitlements and top-up credits can coexist in the same wallet. **Who uses this model:** Clay (seat-based access with credit allocations), Cursor (monthly credit pools per tier), GitHub Copilot (subscriptions with usage caps). Common when you want recurring revenue with usage-based expansion. **When to choose this:** * You need baseline recurring revenue plus usage-based growth * Some features are seat-based, others consumption-based * Customers want predictability with flexibility for overages * You're balancing stakeholder preferences for both models * Different customer segments expect different billing approaches **Implementation in Credyt:** Configure products with both fixed fees and usage-based pricing. Use [entitlements](https://docs.dev.credyt.ai/features/product-catalog/entitlements.md) to define included usage allocations. Enable top-ups through [Credyt's Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md) for additional usage. See our [Hybrid Pricing guide](https://docs.dev.credyt.ai/features/product-catalog/entitlements.md). #### Choosing Your Pricing Model[​](#choosing-your-pricing-model "Direct link to Choosing Your Pricing Model") Start with three questions: **1. Can you afford to front infrastructure costs?** If no: Real-time prepaid credits eliminate cash flow risk. Customers pay before they consume. If yes: Subscription or hybrid models give customers payment flexibility that enterprise buyers often prefer. **2. How predictable is customer usage?** Highly unpredictable: Prepaid credits protect you from runaway costs. Real-time authorization prevents negative balances. Relatively stable: Subscriptions or hybrid models work well, providing baseline revenue while supporting usage spikes. **3. What billing model do your customers expect?** Developers and prosumers: Often prefer pay-as-you-go with real-time visibility into spend. Enterprise customers: Frequently require invoice cycles and payment terms that align with procurement processes. #### Pricing in Fiat vs Custom Units[​](#pricing-in-fiat-vs-custom-units "Direct link to Pricing in Fiat vs Custom Units") Credyt supports pricing in both standard currencies (USD, EUR) and [custom assets](https://docs.dev.credyt.ai/features/assets.md) like tokens, minutes, or credits. **Fiat pricing:** Transparent and enterprise-friendly. Usage deducts directly in currency terms (e.g., $0.006 per API call). Straightforward for reconciliation and familiar to most customers. **Custom units:** Consumer-friendly for products where abstract units better represent value (e.g., 10 credits per video generation). You define [exchange rates](https://docs.dev.credyt.ai/features/assets.md) between fiat and your custom units. The Billing Portal automatically handles conversions during top-up. Both approaches can coexist in a single customer wallet. See our [Fiat vs Custom Units guide](https://docs.dev.credyt.ai/use-cases/fiat-vs-custom-units.md) for implementation details. #### Important Note: Invoice-based Usage Billing[​](#important-note-invoice-based-usage-billing "Direct link to Important Note: Invoice-based Usage Billing") Credyt does not currently support usage-based billing where usage is metered throughout a period and billed in arrears via invoices (similar to AWS Lambda or Twilio). All usage-based pricing in Credyt operates on a prepaid, real-time authorization model. If your business requires post-facto metering with invoicing after usage occurs, Credyt may not be the right fit for your billing infrastructure. #### Next Steps[​](#next-steps "Direct link to Next Steps") * Review [Products and Pricing](https://docs.dev.credyt.ai/features/product-catalog.md) to understand how to configure create products and configure pricing * Read about [Dimensional Pricing](https://docs.dev.credyt.ai/features/product-catalog/dimensional-pricing.md) if your pricing varies by attributes like speed, quality, or model type * Check our [Quickstart guide](https://docs.dev.credyt.ai/quickstart.md) to start integrating --- ## Quickstart ### Introduction The Quickstart Guide is the fastest way to get hands-on with Credyt and see how everything fits together. It walks you through the core concepts of the platform and gives you a clear, minimal path to start integrating; from creating your first customer to processing real-time usage and tracking wallet balances. We recommend working in test mode throughout this guide. The test environment is completely isolated from production and uses a separate set of API credentials, so you can safely experiment, send usage, and explore payment flows without impacting real customer data. Video Available Watch the video version of this quickstart guide on [YouTube](https://youtu.be/JFKvVFK_Wm4?si=OSG8-Dipl9M1Efqk). ##### Meet GlitchAI[​](#meet-glitchai "Direct link to Meet GlitchAI") Throughout our docs, we'll use examples from a fictitious AI media and content generation platform for marketers, GlitchAI. #### Prerequisites[​](#prerequisites "Direct link to Prerequisites") Sign up To complete this quickstart guide you'll need a Credyt account. You can sign up for free at To integrate with Credyt, you’ll need your API key, which must be included in the `X-CREDYT-API-KEY` header in all API requests. API keys are pre-generated for your account during sign-up and can be obtained from the [Credyt App](https://app.credyt.ai). If you’re part of an existing account, contact your account administrator to get access to the API key. When you’re ready to move beyond the basics, explore the [Features](https://docs.dev.credyt.ai/category/features.md) and [Advanced Topics](https://docs.dev.credyt.ai/category/advanced-topics.md) sections for a deeper dive into all of Credyt's capabilities. #### Follow along with Bruno[​](#follow-along-with-bruno "Direct link to Follow along with Bruno") With our [Bruno request collections](https://github.com/credyt/learn/tree/main/bruno/credyt-api) you can follow along with the docs interactively and make API requests against your own account. You can view the setup instructions and download the collections from [GitHub](https://github.com/credyt/learn/archive/refs/heads/main.zip) or click the button below to open them directly in [Bruno](https://usebruno.com). [![Fetch in Bruno](https://fetch.usebruno.com/button.svg)](https://fetch.usebruno.com/?url=https%3A%2F%2Fgithub.com%2Fcredyt%2Flearn.git) After opening the collection in Bruno: 1. In the top right of the Bruno app select the environments dropdown and select "Configure" 2. Obtain your API keys from the [Credyt Portal](https://app.credyt.ai) and add them under the `credytApiKey` variable for your desired environment (test or live). Make sure to "Save" the changes. 3. Select the target environment in Bruno --- ### Billing Portal [API Reference](https://docs.dev.credyt.ai/api/billing-portal-create-portal-session.md) The Billing Portal enables you to offer your customers a comprehensive billing experience, providing them with visibility into their balances, usage and top-up history. From here they can top up their accounts directly and manage their billing settings. More information on the billing portal can be found [here](https://docs.dev.credyt.ai/features/billing-portal.md). #### Start a billing portal session[​](#start-a-billing-portal-session "Direct link to Start a billing portal session") Your customers do not need to register for Credyt in order to use the billing portal. Instead, you manage their access by generating a billing portal *session*, once you have authenticated and validated the user within your service. Let's open up the billing portal for the customer we've been working with: POST https://api.credyt.ai/billing-portal/sessions ```json { "customer_id": "{{customerId}}", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt/failure" } ``` **Response** ```json { "redirect_url": "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwdXJwb3NlIjoicG9ydGFsLXNlc3Npb24tcmVkaXJlY3QiLCJpc3N1ZWQiOiIyMDI1LTEwLTE4VDA3OjEzOjQzLjg0MDU3NjlaIiwicGxhdGZvcm1faWQiOiJhY2NfNHk3ZHh4cXQ4ZHp6cGY0dzU4dGUwMDF6eGIiLCJjdXN0b21lcl9pZCI6ImN1c3RfNG44YzRwZ2VuaDM0dmNtbmdkNzE2cWd2ZDUiLCJsaXZlX21vZGUiOiJmYWxzZSIsInJldHVybl91cmwiOiJodHRwczovL2dsaXRjaC5haS9hY2NvdW50IiwiZmFpbHVyZV91cmwiOiJodHRwczovL2dsaXRjaC5haS9jYWxsYmFja3MvY3JlZHl0L2ZhaWx1cmUiLCJleHAiOjE3NjA3NzIyMjMsImlzcyI6IkNyZWR5dC5BcGkiLCJhdWQiOiJDdXN0b21lclBvcnRhbCJ9.HgSOGKlZCbO4XgNXxLVkAmz44crjIF1V_wg195VkWs4", "expires_at": "2025-10-18T07:23:43Z" } ``` The `redirect_url` is a pre-authenticated URL where you send your customer. This link is valid for 10 minutes. Return and Failure URLs When creating a billing portal session you specify both the URL the customer should return to when exiting the portal (`return_url`) and the failure URL (`failure_url`) we will redirect them to if their session expires or there are any issues. You can find more about failure handling [here](https://docs.dev.credyt.ai/features/billing-portal.md). If you navigate to this URL you should see their recently updated balance and usage. ![Credyt\'s Billing Portal](/assets/images/billing-portal-142a477a259a8d2d7aeefb93ae3880ca.png) --- ### Check Balance [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md) You can check a customer’s wallet balance at any time via the Customer Wallet API. A customer wallet may contain multiple accounts of different currencies or assets. In this guide we’ve placed this step last to show how the balance updates after usage events are sent. In practice, you'll typically want to check the balance before allowing the customer to perform the billable action. Overdrafts are enabled on wallet accounts by default, ensuring that usage can be billed in full. We recommend that you check balances according to your own business logic and overdraft tolerance. ##### Get Wallet Example[​](#get-wallet-example "Direct link to Get Wallet Example") ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** After submitting a few `video_promoted` events in the [previous section](https://docs.dev.credyt.ai/quickstart/send-usage.md) we can see our balance has been reduced accordingly. ```json { "accounts": [ { "id": "default:USD", "name": "default", "asset": "USD", "available": 998.5 } ] } ``` ##### Get Account Example[​](#get-account-example "Direct link to Get Account Example") If you know the address of the account you wish to check, you can use the [Wallet Account API](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-account.md). Typically this will be in the format `default:{currency}`. ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet/default:USD' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** ```json { "id": "default:USD", "name": "default", "asset": "USD", "available": 998.5, "pending_in": 0, "pending_out": 0 } ``` --- ### Create a Customer [API Reference](https://docs.dev.credyt.ai/api/customers-ops-create-customer.md) Before you can start billing your customers you need to register them in Credyt and create subscriptions to the products they use. #### Product Subscriptions[​](#product-subscriptions "Direct link to Product Subscriptions") When creating a customer you can subscribe them to products in your [Product Catalog](https://docs.dev.credyt.ai/quickstart/create-a-product.md). The product code and version you specify determines the pricing that will be used to bill the customer. When you subscribe a customer to a product, Credyt automatically creates their wallet and provisions accounts in the billing currencies defined by the product’s pricing configuration. These accounts are used to track balances, top-ups, and usage from the start of the subscription. ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/customers ```json { "name": "John Doe", "external_id": "18991", "subscriptions": [ { "products": [ { "code": "glitch_video_std" } ] } ] } ``` tip The `external_id` field allows you to use your own identifiers when sending usage data to Credyt **Response** ```json { "id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx" } ``` Make a note of the customer `id`. We'll use it in the subsequent exercises. --- ### Create a Product [API Reference](https://docs.dev.credyt.ai/api/product-ops-create-product.md) The product catalogue is a core concept in Credyt. Before sending usage, you’ll need to add your products, which can be priced in multiple ways: * **Event Type** - what product event or outcome are you billing for? * **Currency or asset** - do you want to price in fiat or a custom asset such as tokens or minutes? * **Usage type** - are you charging per occurrence (unit) or volume (e.g. workload size)? * **Billing Dimensions** - do you price differently based on characteristics of the usage such as the AI model used? To get familiar with Credyt you can create products directly using our [Create Product API](https://docs.dev.credyt.ai/api/product-ops-create-product.md). This lets you validate your integration and usage flow before building out your full product catalogue. Start by defining a basic product with a default rate plan. This product will serve as the reference for sending usage events and testing wallet deductions. ##### Unit-based pricing[​](#unit-based-pricing "Direct link to Unit-based pricing") Use unit-based pricing to charge per occurrence of a particular event or outcome. In this example, we charge $0.50 per video that is promoted via the Glitch Marketplace: POST https://api.credyt.ai/products ```json { "name": "Glitch Video", "code": "glitch_video_std", "prices": [ { "name": "Video Promotion", "type": "usage_based", "billing_model": { "type": "real_time" }, "usage_calculation": { "event_type": "video_promoted", "usage_type": "unit", "source_reference_field": "video_id" }, "pricing": [ { "asset": "USD", "values": [ { "unit_price": 0.5 } ] } ] } ], "publish": true } ``` **Response** ```json { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": 1, "status": "published", "is_default": true } ``` Versioning Products are automatically versioned so you can safely make changes to your pricing without impacting existing customers. --- ### Pre-fund Balance [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) To make testing easier, you can pre-fund your customer's balance without going through the full payment flow. This is the fastest way to see real-time billing in action! You can use the [Wallet Adjustment API](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) to pre-fund a customer’s wallet. For the full overview of how top-ups work in production, check out the [Top-ups and Wallets guide](https://docs.dev.credyt.ai/features/wallets-and-topups.md). You can use this API for any kind of balance adjustment including external PSP payments, refunds, and promotional credits. A detailed explanation of this functionality is available in our [Adjustments guide](https://docs.dev.credyt.ai/advanced-topics/adjustments-charges-gifts.md). ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "asset": "USD", "amount": 20, "reason": "external_topup", "metadata": { "psp": "stripe", "payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0" } } ``` Wallet Idempotency Wallet adjustments can be safely retried by specifying the same unique transaction identifier (UUID) **Response** ```json { "id": "61e15192-a156-4af4-a3cc-ec6c937795fa", "created_at": "2025-10-17T21:00:56.743379Z" } ``` --- ### Send Usage Events [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) Submit actual usage events such as API calls, AI workloads, or product outcomes. Billable events are processed in real time and immediately debit the customer’s wallet. Each event must have a unique ID to ensure idempotency, preventing double billing if the same event is submitted multiple times. Customers are billed based on their [product subscriptions](https://docs.dev.credyt.ai/quickstart/create-a-customer.md#product-subscriptions). Usage events are matched against the corresponding products' [usage calculation configuration](https://docs.dev.credyt.ai/quickstart/create-a-product.md). For example, if a product has a `video_promoted` event type configured, sending a usage event of that type will calculate and debit a usage fee from the customer's wallet. note The response from the [Usage API](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) does not include the updated wallet balance. To check the current balance after usage is processed, you can use the [Wallet API](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md). ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/events ```json { "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event_type": "video_promoted", "occurred_at": "2025-10-17T21:21:27.024729Z", "subject": "video_5f53d23a4958", "description": "Video Promoted", "data": { "promo_id": "pro_4tbftjwzxja1h71nzas1g0g1xm" } } ] } ``` #### Using external identifiers[​](#using-external-identifiers "Direct link to Using external identifiers") Alternatively you can specify the customer's external identifier in the `customer_external_id` field. This may be preferable if sending usage is in your application "hot path" and you want to avoid unnecessary lookups: ##### Example[​](#example-1 "Direct link to Example") POST https://api.credyt.ai/events ```json { "customer_external_id": "", "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event_type": "video_promoted", "occurred_at": "2025-10-17T21:21:27.024729Z", "subject": "video_5f53d23a4958", "description": "Video Promoted", "data": { "promo_id": "pro_4tbftjwzxja1h71nzas1g0g1xm" } } ] } ``` --- ### Troubleshooting This guide covers some of the most common issues developers encounter when integrating with Credyt and how to troubleshoot them effectively. ##### The customer is not billed for usage events[​](#the-customer-is-not-billed-for-usage-events "Direct link to The customer is not billed for usage events") If your customer isn't being billed after sending usage events, you should check the following: **1. Ensure you have subscribed your customer to the product** Credyt will accept any usage event for a customer, even if they are not subscribed to a corresponding product. This is to ensure your Credyt integration doesn't break as you generate new events from your system. To validate that the customer is subscribed to a product, [retrieve the customers details](https://docs.dev.credyt.ai/api/customers-ops-get-customer.md) and inspect their `subscriptions`, for example: GET https://api.credyt.ai/customers/:customerId ```json { "id": "cust_4qh0wajx2n9qtazh2tghzkyan2", "external_id": "951832085fee4033a2878f841a24149a", "name": "Joan Parker", "created_at": "2025-11-14T03:25:02.8857879Z", "external_accounts": [], "subscriptions": [ { "started_at": "2025-10-23T11:11:40.100904Z", "products": [ { "id": "prp_4t2fz8a57hje7fjazkrc08jg5n", "code": "glitch_video_std", "version": 1 } ] } ] } ``` If the customer is not subscribed to your desired product, a new subscription can be added via the Customers API. **2. Verify that the customer is subscribed to a product version that uses the same event\_type** Usage events don't directly reference a product or product version. Instead, billing is resolved based on the `event_type` field in the event payload. [Retrieve the customer's details](https://docs.dev.credyt.ai/api/customers-ops-get-customer.md) to confirm the customer's active subscriptions and which product versions they are subscribed to. Then check the `event_type` configuration of the subscribed product versions. If no active subscription matches the event's `event_type`, the event won't be billed. **3. Check that the usage event matches the product configuration** Billing depends on event fields aligning with the product's usage configuration. To help troubleshoot, you can [retrieve a list of usage events](https://docs.dev.credyt.ai/api/event-ops-list-events.md) and provide the `customer_id` query parameter. For detailed information about each event, including the applicable fees and the product configuration it was matched against, [retrieve the specific event's details](https://docs.dev.credyt.ai/api/event-ops-get-event.md). Make sure: * The event's `event_type` matches what's defined in the product version. * The `customer_id` belongs to a customer with a valid subscription. * For volume-based pricing, confirm that your `usage_calculation` setup matches: * `usage_type` * `volume_field` * `billable_dimension` (if applicable) * Each event must include a unique `id` — duplicate event IDs are ignored to prevent double billing. tip Use the [Simulate Usage](https://docs.dev.credyt.ai/api/product-ops-simulate-usage.md) endpoint to test your pricing configuration in isolation. It accepts draft product versions and doesn't require a `customer_id`, making it ideal for testing your setup and troubleshooting configuration issues step by step. ##### The customer balance is negative[​](#the-customer-balance-is-negative "Direct link to The customer balance is negative") A negative balance is an expected condition in Credyt. Credyt allows balances to go negative to ensure that ongoing or multi-step tasks aren't interrupted when end customer's funds are depleted mid-process. This approach prevents failed operations due to minor balance delays and provides a smoother end-user experience. You can check customer's balance at any time with `GET /customers/:customerId/wallet` Based on the balance information, you can decide whether to pause access to your product or prompt the customer to top up their wallet. Once the customer tops up their account, Credyt will automatically correct the negative balance by deducting the owed amount from the next deposit. ##### The customer does not have any balances/accounts[​](#the-customer-does-not-have-any-balancesaccounts "Direct link to The customer does not have any balances/accounts") Customer wallets are created automatically when the customer is subscribed to a product or when a top-up is initiated. To ensure wallets are correctly set up, it's important that customers are subscribed to the relevant products when they are created - this helps avoid any misconfigurations. ##### Billing Portal link has expired[​](#billing-portal-link-has-expired "Direct link to Billing Portal link has expired") When a Billing Portal link expires, Credyt automatically redirects the customer to the `return_url` you provided when generating the link. To keep the experience seamless, you can: 1. Listen for this redirect event at your `return_url`. 2. Automatically request a new Billing Portal link from Credyt using your backend logic. 3. Redirect the customer back to the refreshed link without manual intervention. This ensures that customers always have uninterrupted access to their Billing Portal, even when older links expire. ##### Stripe Tax is not calculated at Checkout[​](#stripe-tax-is-not-calculated-at-checkout "Direct link to Stripe Tax is not calculated at Checkout") If you don't see Stripe Tax applied during checkout, it's usually because Stripe Tax needs to be explicitly activated on the connected Stripe account used for processing payments. Additionally, for tax calculation to work correctly, the customer's country of residence submitted during checkout must be configured for tax collection in Stripe Tax. When testing with Credyt's built-in Stripe account, setting the customer's country to the **United Kingdom (UK)** allows you to observe how tax behaves during checkout and in the top-up history. If you'd like to connect and test with your own Stripe test account, please reach out to us at for assistance. --- ## Features ### Assets AI platforms may price their services in different ways. Some charge directly in fiat currencies; others rely on pre-funded credits and many introduce custom usage units (what we refer to as "Assets") like tokens, GPU hours, or video minutes, to align usage with product outcomes. info This guide talks about configuration of custom assets such as tokens.
If your pricing model is entirely fiat based, you may skip this section. In Credyt, Assets are custom usage units such as tokens, minutes or requests. Think of them like bespoke currencies that are aligned with your product outcomes. They are distinct from fiat currencies and enable platforms bill for usage in a way that is clear, flexible, and transparent for customers. Customers purchase assets with fiat at an exchange rate defined by the platform, enabling straightforward pricing and reporting. #### Defining and managing Assets[​](#defining-and-managing-assets "Direct link to Defining and managing Assets") [API Reference](https://docs.dev.credyt.ai/api/assets-ops-create-asset.md) Platforms can create and manage any custom asset they wish to offer. Each asset can have exchange rates defined for each fiat funding currency, giving platforms full control over how much a customer pays per unit of asset. * Platforms can update exchange rates at any time * Changes can be scheduled to take effect at a specific future time, ensuring predictable pricing * The exchange rate can optionally be overridden for [platform-initiated top-ups](https://docs.dev.credyt.ai/features/wallets-and-topups.md) Assets help to promote a transparent and user-friendly experience. Each asset has a unique code, a customer-facing name, a label for UI display, and an optional symbol. These elements exist to: * Ensure customers can clearly identify the asset they are purchasing * Provide consistent representation across the platform and Billing Portal ##### Example[​](#example "Direct link to Example") Let's create a Glitch Video Credit for your AI platform. We'll price the Credit at $0.10 or inversely, $1.00 buys 10 Credits. When creating an asset, you can specify either the: * `rate` in the source currency - in this example `0.10 USD` * `inverse_rate` in your custom asset - in this case `10`, since each $1.00 buys 10 credits POST https://api.credyt.ai/assets ```json { "code": "VIDGENMIN", "name": "Video Generation Minutes", "precision": 2, "symbol": "⏰", "label": "MIN", "rates": [ { "source": "USD", "rate": 0.1 } ] } ``` We can view the details of this asset at any time via the [Assets API](https://docs.dev.credyt.ai/api/assets-ops-get-asset.md): GET https://api.credyt.ai/assets/VIDCREDIT ```json { "code": "VIDGENMIN", "name": "Video Generation Minutes", "precision": 2, "label": "MIN", "symbol": "⏰", "rates": [ { "source": "USD", "rates": [ { "valid_from": "2026-02-06T10:01:29.686322Z", "rate": 0.1, "inverse_rate": 10 } ] } ], "created_at": "2026-02-06T10:01:29.686322Z" } ``` #### Get a Quote[​](#get-a-quote "Direct link to Get a Quote") [API Reference](https://docs.dev.credyt.ai/api/assets-ops-quote-asset.md) Once you've defined an asset you can use the quote capability to calculate and display how much of a custom asset a customer will receive when topping up (if they're topping up via the [Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md), this will be done automatically). To obtain a quote specify the source fiat currency and the amount to convert, and optionally a point in time (`exchange_at`) to support historical or scheduled conversions. It returns the exchange rate applied and the resulting amount of the asset. ##### Example[​](#example-1 "Direct link to Example") This quote calculates how many Glitch Video Credits a customer would receive for 10 USD. The `destination_rate` of 10 means each $1.00 USD buys 10 credits, resulting in a total of 100 credits. https://api.credyt.ai/assets/VIDCREDIT/quote ```json { "source": "USD", "amount": 10 } ``` **Response** ```json { "source": "USD", "source_amount": 10, "destination": "VIDGENMIN23", "destination_amount": 100, "rate": 0.1, "inverse_rate": 10 } ``` #### Changing asset rates[​](#changing-asset-rates "Direct link to Changing asset rates") If the platform updates the exchange rate and schedules it to take effect the next day, all new purchases will automatically use the new rate, ensuring that billing remains consistent and predictable. --- ### Auto Top-up Auto top-up is Credyt’s mechanism for keeping prepaid balances funded automatically, so usage-based products can run without interruption. It enables your customers to define simple rules that trigger a top-up whenever their balance drops below a certain threshold. Instead of relying on manual action at the exact moment a balance runs out, auto top-up ensures continuity for long-running or unpredictable workloads. This feature is essential for platforms that bill in real time, where usage can fluctuate rapidly, and a depleted balance could interrupt an in-progress task, degrade the user experience, or lead to unexpected churn. #### How auto top-up works in Credyt[​](#how-auto-top-up-works-in-credyt "Direct link to How auto top-up works in Credyt") Auto top-up is configured by your customers directly in the [Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md) and applied **per asset** (e.g., USD, credits, tokens, or minutes). In its current form, auto top-up is available to platforms using Credyt’s built-in payment processing, powered by Stripe’s payments infrastructure. For each asset, a customer can: * Enable or disable auto top-up * Choose a saved payment card or add a new one * Define a balance threshold * Define a top-up amount When the balance for a given asset drops below the configured threshold, Credyt automatically initiates an off-session payment via Stripe and credits the wallet once the payment succeeds. This happens without interrupting the customer’s workflow and without requiring any manual action when the balance runs low. ![Alt text for accessibility](/assets/images/autotopup_modal-3ac857c8e8955ffbcc0ee78d9e0c3082.png "Account balance view") #### Per-asset configuration[​](#per-asset-configuration "Direct link to Per-asset configuration") Auto top-up is asset-specific by design. Each wallet asset has its own independent auto top-up configuration. This allows customers to treat different balances independently, which is especially useful for products that combine multiple billing models or usage units. All saved payment cards belong to the customer account and are available across all asset configurations. ![Alt text for accessibility](/assets/images/balances_autotopup-08b4370e3c2beace69e824fcebc7c7bb.png "Account balance view") #### Card management and authorisation[​](#card-management-and-authorisation "Direct link to Card management and authorisation") Auto top-up relies on payment cards explicitly authorized by the end customer for future use. Card authorisation can happen in two ways: * When a customer adds a new card through the Billing Portal * When a customer completes a manual top-up and consents to saving the card for future use All card authorization flows, including any required authentication steps, are handled through Stripe’s secure payment infrastructure. The selection or change of the payment card used for auto top-up is performed exclusively by the end customer within the Billing Portal. Platforms redirect customers to the portal but do not directly control card selection. --- ### Billing Portal The Credyt Customer Billing Portal enables you to offer your customers a comprehensive billing experience with complete visibility into their balances, usage and top-up history. From here they can top up their accounts directly and manage their billing settings. ##### Key features[​](#key-features "Direct link to Key features") * Real-time balance updates in both fiat and custom assets (tokens, minutes, etc.) * Transparent reporting on usage and spend, helping customers plan ahead * Both manual and automated top-ups to prevent service interruptions * Self-service with no sign-up required for your customers * Fully hosted by Credyt — no need to build complex payment flows or dashboards yourself * Customizable with your own branding and product URLs #### Integration[​](#integration "Direct link to Integration") To open the billing portal for a particular customer you use the Credyt API to generate a pre-authenticated billing portal session link that you redirect the customer to. No additional UI or payment flow needs to be built on your side. See our [quickstart](https://docs.dev.credyt.ai/quickstart/billing-portal.md) for how to generate a billing portal session. #### Billing Portal UX[​](#billing-portal-ux "Direct link to Billing Portal UX") Below we break down the different sections of the billing portal. ##### Wallet Balances[​](#wallet-balances "Direct link to Wallet Balances") * Shows the customer’s wallet account balances across both fiat and custom assets * Displays total amount spent this month for easy tracking * Always kept up to date with usage events and top-ups ![Alt text for accessibility](/assets/images/balance-1a72c0fc0b0a7ed3f95819b84bc582db.png "Account balance view") ##### Topup and auto topup[​](#topup-and-auto-topup "Direct link to Topup and auto topup") * Manual top-up allows customers to add funds whenever they need. * Auto top-up automatically refills the wallet when balance falls below a set threshold, preventing service interruptions. * Applicable only if the platform uses Credyt’s payment rails via Stripe. * Ensures smooth operations and reduces friction in customer payments. ##### Spend history[​](#spend-history "Direct link to Spend history") * Charts show spend trends over time, in both fiat and custom units. * Helps customers understand spending patterns and plan for future usage. ![Alt text for accessibility](/assets/images/recent_spend-a96f3f3829f5086347ee0258a83b8508.png "Spend trend chart") ##### Usage history[​](#usage-history "Direct link to Usage history") * Each usage record shows the product name, the subject sent by the platform (e.g., the specific task or action performed), and a tooltip with the event description. * The fee description from the product configuration is also displayed, offering full transparency into how each event was billed. * This added context helps customers understand exactly what each usage item represents and how it relates to what they did in the AI product. ![Alt text for accessibility](/assets/images/recent_usage-32acb9441abd0dab9f437080f985dd3d.png "Usage by product and event") ##### Transactions[​](#transactions "Direct link to Transactions") A complete, consolidated record of all credit and debit events affecting a customer’s balance, including top-ups, fees, refunds, gifts, and adjustments. * Displays all relevant balance movements in one place for easy tracking and auditing. * Covers a broad range of transaction types, including Stripe top-ups, external adjustments, refunds, usage and ad-hoc fees, and promotional credits. * Includes filtering options by month, asset, and transaction category for efficient navigation of transaction history. ![Alt text for accessibility](/assets/images/transactions-b0d304a430bc0c2c25a774104f8e1613.png "Transactions table") --- ### Credit grants #### Introduction[​](#introduction "Direct link to Introduction") Prepaid balances are commonly used to track and bill usage. However, a single undifferentiated prepaid balance is often insufficient to support operational needs such as revenue recognition, expiry enforcement, tax calculation at redemption, promotional credits, and plan-specific incentives. These requirements call for more granular tracking and management of prepaid value. Credit grants provide this structure. A credit grant represents a discrete allocation of prepaid value with its own lifecycle, purpose, and financial attributes. Instead of treating a wallet account as one undifferentiated pool of funds, Credyt models it as a sequence of grants - each independently issued, consumed and monitored with its own distinct lifetime. This approach enables prepaid usage billing to operate correctly across billing, accounting, and compliance. #### A core primitive of real-time usage billing[​](#a-core-primitive-of-real-time-usage-billing "Direct link to A core primitive of real-time usage billing") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-credit-grants.md) Credit grants are the fundamental units of a prepaid balance and lie at the core of Credyt’s real-time, usage-based billing model. Each grant defines: * Its effective and expiry dates * The amount of value it holds * How it should be treated for billing, revenue, and compliance purposes ##### Issuing credit grants[​](#issuing-credit-grants "Direct link to Issuing credit grants") Credit grants enter a wallet through a small number of well-defined entry points. Each entry point determines the purpose of the grant and how its expiry is set - two attributes that are then exposed directly via the [Get credit grants](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-credit-grants.md) endpoint. When a customer initiates a top-up, and the payment is successfully processed, Credyt automatically creates a credit grant with the purpose set to `paid`. Paid credit grants have a default expiry of one year, ensuring that prepaid value is time-bound while remaining predictable for both the platform and the end user. Credit grants can also be created through wallet adjustments and may be used for promotional credits or for credits included in bundled packages or entitlements. In these cases, Credyt derives the purpose and expiry of the grant from the adjustment itself. The `reason` and `expires_at` parameters submitted via the [Wallet adjustments](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) API determine how the grant is classified and how long it remains valid. Credit grants do not have to become available immediately - the platform can define when they become effective using the `effective_from` parameter in the [Top-ups](https://docs.dev.credyt.ai/api/top-ups-ops-initiate-top-up.md) and [Wallet adjustments](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) APIs. Top-ups initiated directly from the Billing Portal become effective immediately by default. By standardizing how grants are issued, Credyt ensures that every credit grant has a clear origin, a defined purpose, and an explicit lifetime, all of which are visible and auditable at the grant level. ##### Consumption at grant level[​](#consumption-at-grant-level "Direct link to Consumption at grant level") An account’s balance is the sum of its active grants. Usage draws down from these grants following platform-defined rules, such as prioritizing included or promotional credits before paid ones, or consuming the earliest-expiring grants first. Because consumption deducts from grants as it occurs: * Revenue can be recognized at the time of consumption * Exchange rates/cost basis for custom units can be locked at purchase * Expiry and breakage are handled appropriately at the grant level * Taxes can be applied accurately using relevant jurisdiction and service metadata ##### Handling credit expiry[​](#handling-credit-expiry "Direct link to Handling credit expiry") When a credit grant expires, it is flagged as inactive and no longer available for usage. This triggers a set of processes to ensure accurate billing, accounting, and auditability: * Revenue recognition - any remaining deferred revenue linked to the expired credit grant is recognized as actual revenue. This moves the value from deferred revenue to recognized revenue in the underlying ledger. * Usage drawdown - expired credit grants are excluded from the available balances. Subsequent usage will draw from the next active credit grants according to platform-defined consumption rules. * Auditability - even after expiry, the credit grant record remains available for auditing purposes. These records can be retrieved through the [Get credit grants](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-credit-grants.md) endpoint, providing full visibility into grant history and status. * Grace Periods - Credyt implements a grace period for credit expiry, delaying the effective expiration by several hours. This delay accommodates late event submissions and synchronization issues, ensuring usage events are processed accurately without premature expiry. ##### Revenue recognition at consumption[​](#revenue-recognition-at-consumption "Direct link to Revenue recognition at consumption") Revenue in Credyt is recognized when credits are consumed or expire, not when they are purchased. When a customer tops up, the value is recorded as deferred revenue and only becomes recognized revenue as usage draws down from the associated credit grants. Each credit grant retains the transaction price and, where applicable, the exchange rate (cost basis) from the time of purchase. This ensures that, as usage is billed, whether in fiat or custom units, revenue can be calculated accurately in fiat and posted correctly to the general ledger, even if exchange rates change between top-up and consumption. By tying revenue recognition directly to grant-level consumption, Credyt avoids the accounting ambiguity that arises from flat prepaid balances and maintains precise, auditable revenue reporting. ##### Example[​](#example "Direct link to Example") GET /customers/:customerId/wallet/default:USD/grants?exclude\_expired=true ```json { "items": [ { "id": "9a946e9c-ee30-4af2-9e80-070337504190", "effective_at": "2026-01-01T00:00:00Z", "expires_at": "2026-12-31T23:59:59Z", "purpose": "paid", "created_at": "2025-01-01T00:00:05Z", "available": 17.58 }, { "id": "009d2d65-b2ef-4308-b81d-074b611254e2", "effective_at": "2026-01-15T00:00:00Z", "expires_at": "2026-02-15T23:59:59Z", "purpose": "promotional", "created_at": "2026-01-14T00:00:02Z", "available": 3.25 } ], "total_count": 2, "limit": 2, "offset": 0 } ``` --- ### Customers [API Reference](https://docs.dev.credyt.ai/api/customers-ops-create-customer.md) Before you can bill your customers, you need to register them in Credyt and subscribe them to the products they use. We require only the data necessary for you to identify your customers and perform core billing activities. Your own unique reference or ID (the customer `external_id`) can be provided and later used when submitting usage, avoiding the need to maintain ID mappings in your systems. If you use Credyt’s built-in payment processing, the external ID is included as metadata in Stripe, aiding payment operations. #### Subscribe a Customer to a Product[​](#subscribe-a-customer-to-a-product "Direct link to Subscribe a Customer to a Product") To streamline integration, subscriptions can be provided at the same as creating the customer. A customer can be subscribed to multiple products, which are identified by their respective product code and version. This determines the pricing that will be applied when usage is billed. For convenience, if you omit a product's version we'll use the current "default" version. You can also use the `default` identifier when working with the Product Catalog API. When a customer is subscribed to a product, Credyt automatically provisions wallet accounts in the currencies defined by the product’s pricing configuration. These accounts are used to track balances, top-ups, and usage from the start of the subscription. Unmatched Usage Make sure to subscribe a customer to all of the products they use. Unmatched usage events will be accepted but will not be billed. For more details on creating and managing products, see [Products and Pricing](https://docs.dev.credyt.ai/features/product-catalog.md). ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/customers ```json { "name": "Walter Kreiger", "external_id": "18991", "subscriptions": [ { "products": [ { "code": "glitch_video_std", "version": "default" } ] } ] } ``` **Response** ```json { "id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx" } ``` --- ### Products and Pricing The product catalog is a central concept in Credyt. It defines the products your platform offers and informs how the billing engine processes and charges for usage. Each product includes a pricing configuration, which determines how usage is measured and charged. A product has a unique code and an associated rate plan specifying pricing, metering, and billing units. Products are versioned automatically so you roll out changes to pricing safely without impacting existing customers. #### Create a Product[​](#create-a-product "Direct link to Create a Product") [API Reference](https://docs.dev.credyt.ai/api/product-ops-create-product.md) The Create a Product endpoint lets your platform define new products and their default pricing configuration (rate plan). A product represents what your customers consume, for example, a service, action, or unit of resource, and how they are billed for it. Each product requires a: * Customer-facing name * A unique code used to identifying it creating [Customer Subscriptions](https://docs.dev.credyt.ai/features/customers.md) * One or more prices You can define multiple prices to cater for all the billable aspects of your products. Each price has a usage calculation that determined how matching usage events should be measured and processed. ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/products ```json { "name": "Glitch Video", "code": "glitch_video_std", "prices": [ { "name": "Video Promotion", "type": "usage_based", "billing_model": { "type": "real_time" }, "usage_calculation": { "event_type": "video_promoted", "usage_type": "unit", "source_reference_field": "video_id" }, "pricing": [ { "asset": "USD", "values": [ { "unit_price": 0.5 } ] } ] } ], "publish": true } ``` **Response** ```json { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_std", "version": 1, "status": "published", "is_default": true } ``` #### Usage Calculation[​](#usage-calculation "Direct link to Usage Calculation") The usage calculation configuration determines how Credyt interprets incoming usage events. It supports several calculation modes providing flexibility for different pricing models: * **`unit`** – charges per occurrence of the event (e.g., per chat, per verification, per API call). * **`volume`** – charges based on the volume or quantity consumed, included in the event payload (e.g., tokens, minutes, megabytes). * **`unit_and_volume`** – combines both approaches In addition to a [usage event `subject`](https://docs.dev.credyt.ai/api/event-ops-send-usage.md), the usage calculation configuration can specify a `source_reference_field`, the name of a field in your event payload that helps correlate the generated usage fee with the customer activity, for example `video_generation_id`. ##### How usage events are billed[​](#how-usage-events-are-billed "Direct link to How usage events are billed") Product usage is billed by matching the `event_type` of incoming events to a price's `usage_calculation` configuration. If no matching configuration exists, the usage will be recorded, but not billed for. This ensures that each event is billed according to the correct pricing logic and allows multiple event types to coexist within a single product or across different products. ###### Pricing Example[​](#pricing-example "Direct link to Pricing Example") | Product | Event Type | Usage Mode | Source Reference Field | Description | | ------------ | ------------------ | ----------------- | ---------------------- | ---------------------------------------- | | Glitch Video | video\_promoted | unit | video\_id | Charges per promoted video | | Glitch Video | video\_minutes | volume | video\_id | Charges based on total minutes processed | | Glitch Text | message\_completed | unit\_and\_volume | chat\_id | Charges per chat + tokens used in chat | In this example: * A usage event with `event_type: video_promoted` will trigger the first unit-based price * A usage event with `event_type: video_minutes` will trigger the second price and bill based on the volume of minutes * A usage event with `event_type: message_completed` will trigger the third price, combining both approaches (unit + volume) #### Pricing[​](#pricing "Direct link to Pricing") The `pricing` configuration of a price defines the actual rates your customers pay for usage. Each product price can have pricing defined in multiple currencies or [custom assets](https://docs.dev.credyt.ai/features/assets.md), for example, a fiat currency like `USD` or a custom asset like as `TOK` (tokens) or `MIN` (minutes). The asset value defines: * **unit price** — the base rate per unit of usage (for unit-based models). * **volume rate** — the rate per aggregated volume unit (for volume-based models). * **min\_amount / max\_amount** — optional limits that cap or floor how much can be charged per event. This flexible structure allows you to model a wide range of usage-based pricing approaches, from simple per-event fees to complex, volume-based charging logic. #### Publishing and Versioning[​](#publishing-and-versioning "Direct link to Publishing and Versioning") [API Reference](https://docs.dev.credyt.ai/api/product-ops-update-product-version.md) By default, products are created in draft mode, allowing you to review or update the configuration before publishing. You can also validate the configuration by [simulating usage](https://docs.dev.credyt.ai/api/product-ops-simulate-usage.md), which lets you run events through the billing engine and view the generated fees without registering them in the system. When you need to update the pricing of an existing product, use the Update Product endpoint. Credyt automatically creates a new draft version of the product with your updated pricing details. You can choose to publish the version immediately (note that published versions are non-editable) or keep it in draft, test it by sending usage events, and then publish it — and make it the default version — using the Update a Product Version endpoint. Once published, a product becomes version-locked, ensuring billing consistency for customers already subscribed to it. Any future pricing or logic changes are introduced as new product versions, preserving historical accuracy. You can also archive a product or a product version. Deleting a product makes it unavailable for new subscriptions. If the product has already been used, it will be archived to preserve history; however, any new usage events for this product will not be accepted. Archiving a product version makes it unavailable for new subscriptions, but it remains active for customers already subscribed to it, and usage events will continue to be accepted. --- ### Dimensional Pricing [API Reference](https://docs.dev.credyt.ai/api/product-ops-create-product.md) Dimensional Pricing allows pricing to adapt based on custom attributes (billable dimensions) of a usage event; such as speed, quality, or model type. Instead of creating separate prices for each dimension value, you define a single price and assign values for each variation of your billable dimensions. This reduces your setup and maintenance effort and ensures pricing consistency across dimensions. In the following example we charge a different price based on the `speed` of the video generation task. This field is included in the usage events sent to Credyt. Here we charge $1.00/minute for "fast" workloads and $0.40/minute for "regular" speed workloads. POST https://api.credyt.ai/products ```json { "name": "Glitch Video Advanced", "code": "glitch_video_adv", "prices": [ { "name": "Video Generation Compute", "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", "billable_dimensions": ["speed"] }, "pricing": [ { "asset": "USD", "values": [ { "name": "Video Generation Minutes (Fast)", "dimensions": { "speed": "fast" }, "values": [ { "volume_rate": 1 } ] }, { "name": "Video Generation Minutes (Regular)", "dimensions": { "speed": "regular" }, "values": [ { "volume_rate": 0.4 } ] } ] } ] } ], "publish": true } ``` **Response** ```json { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_video_adv", "version": 1, "status": "published", "is_default": true } ``` When sending usage for a customer subscribed to the above product, the price will be matched based on the `event_type` and billing dimensions included in the `data` object of the incoming usage event. In the following example, the price for "Video Generation Minutes (Fast)" would be matched since `data.speed = "fast"`. 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" } } ] } ``` --- ### Hybrid billing with Entitlements Preview Feature Entitlements are currently in preview. Please contact our [support team](mailto:support@credyt.ai) for access. Combine traditional [fixed-fee pricing](https://docs.dev.credyt.ai/features/product-catalog/fixed-fee-pricing.md) with bundled credit entitlements to mix recurring revenue with usage-based overages seamlessly. Hybrid billing lets you charge a monthly subscription fee while granting customers a fixed credit allowance each billing cycle. When customers exceed their included credits, they pay for additional usage at your defined overage rates. This model works for AI products where you want predictable recurring revenue while maintaining the flexibility of usage-based pricing. #### When hybrid billing fits[​](#when-hybrid-billing-fits "Direct link to When hybrid billing fits") Hybrid billing works when: * You want predictable monthly revenue from subscriptions * Customers need a base credit allowance included with their plan * You charge for usage beyond the included allowance * Different plan tiers provide different credit allocations Common examples include SaaS products with tiered plans ($20/month with 1,000 credits included), developer tools with base usage quotas, and AI platforms with plan-based credit allowances. #### How entitlements work[​](#how-entitlements-work "Direct link to How entitlements work") Entitlements are "right-to-use" grants that decouple service access from direct credit purchases. While a commitment represents pre-funded balance intended for consumption, an entitlement represents a bundled allocation granted at the product level. When you subscribe a customer to a product with entitlements, Credyt automatically: 1. Grants the specified credit amount to the customer's wallet 2. Refreshes this allowance according to your defined schedule (daily, monthly, etc.) 3. Tracks consumption against the entitlement balance 4. Charges overage fees when credits are exhausted #### Entitlement types[​](#entitlement-types "Direct link to Entitlement types") Entitlements are categorized by their accounting purpose, which dictates how Credyt handles revenue recognition and cost tracking. ##### Bundled entitlements[​](#bundled-entitlements "Direct link to Bundled entitlements") Credits included as a feature of a fixed-fee plan. The subscription fee is recognized ratably over the billing cycle, while the credit value is generally assigned a revenue basis of $0 (the value is captured by the recurring fee). Example: "$20/month includes 1,000 credits" ##### Promotional entitlements[​](#promotional-entitlements "Direct link to Promotional entitlements") Free credits granted to incentivize signups, login streaks, or referrals. No revenue is recognized. These track a cost basis to record marketing expense when consumed. Example: "$2 free daily credits for new users" #### Creating a hybrid billing product[​](#creating-a-hybrid-billing-product "Direct link to Creating a hybrid billing product") Entitlements can grant credits in either fiat currency or [custom assets](https://docs.dev.credyt.ai/features/assets.md), for example credits, tokens or minutes. To use custom assets, first create the asset and define the buy rate, then create a product that uses the asset. ##### Step 1: Create a custom credit asset[​](#step-1-create-a-custom-credit-asset "Direct link to Step 1: Create a custom credit asset") Before creating your product, define a custom asset for your credits. This asset has a buy rate that determines how much customers pay when purchasing additional credits. In this example, we create a `CREDIT` asset where each credit costs $0.05 (or inversely, $1.00 buys 20 credits). POST https://api.credyt.ai/assets ```json { "code": "CREDIT", "name": "Credits", "precision": 0, "symbol": "⭐", "label": "CR", "rates": [ { "source": "USD", "rate": 0.05 } ] } ``` ##### Step 2: Create the product with entitlements[​](#step-2-create-the-product-with-entitlements "Direct link to Step 2: Create the product with entitlements") Now create a product that grants bundled credits and charges for actual usage, for example "AI Image Generations". ###### Example: monthly subscription with bundled credits[​](#example-monthly-subscription-with-bundled-credits "Direct link to Example: monthly subscription with bundled credits") This example creates a Premium Plan that costs $20/month and includes 1,000 credits that refresh monthly. The product charges 10 credits per image generation. When customers run out of bundled credits, they can purchase more at the $0.05 rate defined in the asset. POST https://api.credyt.ai/products ```json { "name": "Premium Plan", "code": "premium_monthly_01", "description": "Standard monthly subscription with included credit allowance.", "entitlements": [ { "name": "Monthly Credit Allowance", "asset": "CREDIT", "amount": 1000, "purpose": "bundled", "refresh": { "interval": "month", "strategy": "expire_and_replace" }, "accounting": { "revenue_basis": 0, "cost_basis": "auto" } } ], "prices": [ { "name": "Monthly Subscription Fee", "type": "fixed", "billing_model": { "type": "recurring", "recurring": { "interval": "month" } }, "pricing": [ { "asset": "USD", "values": [ { "unit_price": 20 } ] } ] }, { "name": "Image Generation", "type": "usage_based", "billing_model": { "type": "real_time" }, "usage_calculation": { "event_type": "image_generated", "usage_type": "unit" }, "pricing": [ { "asset": "CREDIT", "values": [ { "unit_price": 10 } ] } ] } ], "publish": true } ``` With this configuration: * Customer pays $20/month for the subscription * Receives 1,000 credits each month * Each image generation costs 10 credits * When credits are exhausted, customer can purchase more at $0.05/credit * Customer can generate 100 images with their included credits ###### Example: free tier with promotional credits[​](#example-free-tier-with-promotional-credits "Direct link to Example: free tier with promotional credits") This example models a Free Plan that costs $0 but includes a recurring daily entitlement of 50 credits. Each image generation costs 5 credits. POST https://api.credyt.ai/products ```json { "name": "Free Tier Product", "code": "free_tier_01", "entitlements": [ { "name": "Daily Reward", "asset": "CREDIT", "amount": 50, "purpose": "promotion", "refresh": { "interval": "day", "strategy": "expire_and_replace" }, "accounting": { "revenue_basis": 0.0, "cost_basis": "auto" } } ], "prices": [ { "name": "Image Generation", "type": "usage_based", "billing_model": { "type": "real_time" }, "usage_calculation": { "event_type": "image_generated", "usage_type": "unit" }, "pricing": [ { "asset": "CREDIT", "values": [ { "unit_price": 5 } ] } ] } ], "publish": true } ``` With this configuration: * No monthly fee * Customer receives 50 free credits daily * Each image generation costs 5 credits * Customer can generate 10 images per day with free credits * When credits are exhausted, customer can purchase more at $0.05/credit #### Entitlement configuration[​](#entitlement-configuration "Direct link to Entitlement configuration") | Field | Type | Description | | ---------------- | ------- | ----------------------------------------------------------------------------------------- | | `purpose` | Enum | Defines the accounting track: `bundled` or `promotion` | | `revenue_basis` | Decimal | Amount of revenue earned per unit used. Defaults to `0.00` for bundled/promotional grants | | `cost_basis` | Decimal | Internal cost to expense per unit used. Defaults to `auto` to follow the usage price | | `refresh` | Object | Defines the refresh lifecycle (e.g. refresh daily and do not rollover unused credits) | | `priority_score` | Integer | Dictates consumption order. Lower scores are burned first | ##### Refresh strategies[​](#refresh-strategies "Direct link to Refresh strategies") The `refresh` object controls how entitlements replenish: * `interval`: How often credits refresh (`day`, `month`, etc.) * `strategy`: What happens to unused credits * `expire_and_replace`: Unused credits expire, new allocation granted * `rollover`: Unused credits carry forward (up to defined limits) #### Consumption and priority rules[​](#consumption-and-priority-rules "Direct link to Consumption and priority rules") By default, Credyt consumes grants in the order they expire (FIFO). However, you can assign a higher `priority_score` to promotional grants to ensure free credits are exhausted before customers touch bundled or paid balances. ##### Example consumption order[​](#example-consumption-order "Direct link to Example consumption order") 1. Promotional credits (highest priority) 2. Bundled subscription credits 3. Purchased credits or pay-as-you-go This ensures customers use their free promotional credits first, then their included subscription credits, before incurring overage charges. #### Revenue recognition[​](#revenue-recognition "Direct link to Revenue recognition") When a bundled entitlement has a `revenue_basis > 0`, Credyt manages revenue recognition: * **Usage**: Revenue is recognized unit-by-unit as consumed * **Expiry**: Remaining balance at period end moves from contract liability to revenue as breakage For bundled entitlements with `revenue_basis: 0.00`, the subscription fee is recognized ratably over the billing cycle regardless of credit consumption. #### Subscribing customers[​](#subscribing-customers "Direct link to Subscribing customers") Once you've created your hybrid product, subscribe customers by referencing the product code when creating the customer: POST https://api.credyt.ai/customers ```json { "name": "John Doe", "external_id": "18991", "email": "j.doe@gmail.com", "subscriptions": [ { "products": [ { "code": "premium_monthly_01" } ] } ] } ``` When the subscription activates, Credyt automatically grants the entitlement credits to the customer's wallet and begins tracking consumption. --- ### Recurring Fixed Fee Pricing Preview Feature Recurring Fixed Fee Pricing is currently in preview. Please contact our [support team](mailto:support@credyt.ai) for access. With Recurring Fixed Fee Pricing you can charge your customers a fixed rate for access to your products or services on a recurring basis. This is ideal for SaaS products with tiered plans, monthly memberships, or any service with predictable recurring charges. When you subscribe a customer to a product with fixed fee pricing, Credyt automatically handles the billing cycle, invoicing, and payment collection according to the configuration you specify. #### Creating a Monthly Fixed Fee Product[​](#creating-a-monthly-fixed-fee-product "Direct link to Creating a Monthly Fixed Fee Product") [API Reference](https://docs.dev.credyt.ai/api/product-ops-create-product.md) Before you can subscribe your customers, you need to create products with fixed fee prices. Products are created via the Products API. ##### Example[​](#example "Direct link to Example") In this example we create a new product `glitch_pro` that costs $20.00/month and requires payment upfront. POST https://api.credyt.ai/products ```json { "name": "Glitch Pro Subscription", "code": "glitch_pro", "prices": [ { "name": "Monthly Subscription", "type": "fixed", "billing_model": { "type": "recurring", "recurring": { "interval": "month" } }, "pricing": [ { "asset": "USD", "values": [ { "unit_price": 20.0 } ] } ] } ], "publish": true } ``` #### Subscribing Customers[​](#subscribing-customers "Direct link to Subscribing Customers") [API Reference](https://docs.dev.credyt.ai/api/customers-ops-create-customer.md) Once you've created your fixed fee product, you can subscribe customers by referencing this product code when creating the customer: POST https://api.credyt.ai/customers ```json { "name": "John Doe", "external_id": "18991", "email": "j.doe@gmail.com", "subscriptions": [ { "products": [ { "code": "glitch_pro" } ] } ] } ``` **Response:** ```json { "id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "subscriptions": [ { "id": "sub_411xhg4kqakf3d8ybezbzta558", "status": "pending", "products": [ { "id": "prp_4e28n8kk41931f5yt5em49ecw7", "code": "glitch_pro", "version": "default" } ], "required_actions": [ { "type": "payment", "redirect_url": "https://billing.credyt.ai/api/..." } ] } ] } ``` When a subscription requires further action before it can be activated, such as collecting an initial payment, its status will be set to `pending` and it will contain one or more actions in the `required_actions` array. When payment is required there will be a required action of `type: payment` with a corresponding `redirect_url` you should redirect your customer to. This will typically be a link to the [Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md) where your customer will be prompted to complete payment. #### Webhook Notifications[​](#webhook-notifications "Direct link to Webhook Notifications") To receive a notification when the customer has completed the required actions, subscribe to the `subscription.activated` webhook. --- ### Profitability Real-time, usage-based pricing works best if you understand your costs just as well as your revenue. For AI-driven products, costs are often variable, workload-dependent, and incurred at different points in time than revenue. Fixed pricing models break down quickly in this environment, making it difficult to answer a fundamental question: is this product, or this customer, actually profitable? Credyt’s Profitability feature is designed to close that gap. It gives platforms a way to correlate what they earn with what they spend, at the level where it matters most: individual products, workloads, and customers. #### From real-time billing to business insights[​](#from-real-time-billing-to-business-insights "Direct link to From real-time billing to business insights") Credyt’s core infrastructure orchestrates real-time billing. The Profitability layer builds on that foundation to help you answer *how much you should charge,* and whether your pricing truly works. The feature combines: * **Usage events** (already powering billing), and * **Cost data** from underlying vendors and infrastructure With both inputs in one place, platforms can monitor profitability in real time, validate pricing assumptions against actual costs, quickly surface unprofitable customers or workloads, and adjust pricing models before issues compound. #### How it works[​](#how-it-works "Direct link to How it works") The sections below outline the core building blocks of Credyt Profitability and explain how they work together to connect usage, costs, and revenue into a coherent profitability model. ##### Vendors[​](#vendors "Direct link to Vendors") [API Reference](https://docs.dev.credyt.ai/api/vendors-ops-create-vendor.md) Vendors are the external services or infrastructure that power your product - for example, an AI model provider, a compute platform, or a third-party API. Each cost recorded in Credyt is linked to a vendor. POST https://api.credyt.ai/events/vendors ```json { "name": "OpenAI", "external_id": "openai" } ``` **Response:** ```json { "id": "vnd_4rjb887sb1h4j2m0hdjmh49gdg", "created_at": "2026-02-17T09:42:22.470555Z" } ``` tip You can use your external ID when submitting costs in your events by specifying the `vendor_external_id` field instead of `vendor_id`. ##### Costs[​](#costs "Direct link to Costs") [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) The `costs` object is intentionally structured to mirror usage-based fees. A `costs` item can include: * Unit or volume-based cost information * Rates (e.g. cost per token, per minute, per task) * Optional metadata for further analysis This symmetry between fees and costs makes profitability calculations consistent and predictable. ```json "costs": [ { "id": "68116730-e125-408b-8f75-90f1fb9aa7dd", "vendor_id": "vnd_4rcmsv3fagtvha1j05q4fymsmw", "description": "OpenAI Sora", "metadata": { "model": "sora-fast", "resolution": "1080p", "billing_type": "per_minute" }, "units": 0, "unit_price": 0, "input_volume": 0, "volume_rate": 0, "package_size": 0, "amount": 0.16, "currency": "USD" } ] ``` ##### Cost attribution[​](#cost-attribution "Direct link to Cost attribution") [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) The power of Credyt Profitability comes from how costs are attached to usage. Costs can be attributed at different levels of granularity: * **Customer-level** - when costs apply broadly to a customer * **Event-level** - when a specific usage event directly incurs cost * **Subject-level** - when costs relate to a task or outcome (e.g. a `ticket_id` or `generation_id`) Subject-level attribution is especially useful for multi-stage or deferred-cost workflows. For example, if costs begin accumulating before a final “charge” event is emitted, they can still be attached to the same subject and factored into the final profitability calculation. It is the platform’s responsibility to submit cost information along with usage data by including costs in the usage events sent to Credyt. This ensures that costs are properly linked to customers, events, or subjects for accurate profitability tracking. POST https://api.credyt.ai/events ```json { "customer_id": "cust_4zrjbt38gmpb55h95ygp38sp40", "events": [ { "id": "9c2c8e3a-7f6b-4f5e-9c1f-2e6b6a4a9f21", "event_type": "video_generated", "occurred_at": "2026-01-05T14:32:18Z", "subject": "chat_videoId39854734", "description": "Video gen completed", "costs": [ { "id": "68116730-e125-408b-8f75-90f1fb9aa7dd", "vendor_id": "vnd_4rcmsv3fagtvha1j05q4fymsmw", "description": "OpenAI Sora", "metadata": { "model": "sora-fast", "resolution": "1080p", "billing_type": "per_minute" }, "amount": 0.16, "currency": "USD" } ], "data": { "minutes": 2, "model": "video fast", "speed": "fast" } } ] } ``` ##### Profitability[​](#profitability-1 "Direct link to Profitability") [API Reference](https://docs.dev.credyt.ai/api/event-ops-get-event.md) Once revenue and costs are linked, Credyt can calculate profitability across multiple dimensions: * **Per event** - gross revenue, total cost, net revenue, and margin * **Per customer** - understanding which customers are sustainable * **Per product** - identifying profitable and loss-leading offerings These metrics are exposed through existing retrieval endpoints, starting from the most granular level and rolling up from there. Specifically, the profitability data for individual events is available in the `stats` object returned by both the [Get an event's details](https://docs.dev.credyt.ai/api/event-ops-get-event.md) and [List events](https://docs.dev.credyt.ai/api/event-ops-list-events.md) endpoints. GET https://api.credyt.ai/events/:eventId ```json { "id": "9c2c8e3a-7f6b-4f5e-9c1f-2e6b6a4a9f21", "event_type": "video_generated", "occurred_at": "2026-01-05T14:32:18Z", "subject": "chat_videoId39854734", "description": "Video gen completed", "data": { "model": "video fast", "speed": "fast", "minutes": 2 }, "customer_id": "cust_4zrjbt38gmpb55h95ygp38sp40", "created_at": "2026-01-05T14:32:18Z", "fees": [ { "id": "fee_5a1s2xq3ky8z16b1enqybz1qdn", "product_id": "prp_42b28p940qcq31r7amf2729snb", "product_code": "glitch_video_adv_1", "product_version": 1, "price_id": "prc_475p31bj838yec0q2fy66snbcy", "price_name": "Video Generation Compute", "currency": "MIN", "dimensions": { "speed": "fast" }, "usage_type": "volume", "volume_field": "minutes", "input_volume": 2.0, "volume_rate": 1, "description": "Chat message completed", "amount": 2.0 } ], "costs": [ { "id": "68116730-e125-408b-8f75-90f1fb9aa7dd", "vendor_id": "vnd_4rcmsv3fagtvha1j05q4fymsmw", "description": "OpenAI Sora", "metadata": {}, "amount": 0.16, "currency": "USD" } ], "stats": { "gross_revenue": 0.2, "total_costs": 0.16, "net_revenue": 0.04, "margin": 0.2, "currency": "USD" } } ``` The initial version of Credyt Profitability focuses on foundational primitives rather than complex dashboards. By starting with event-level revenue and cost correlation, platforms gain the raw insight needed to safely experiment with pricing and detect margin erosion early. As the feature evolves, this foundation enables richer analysis without changing how data is captured today. Future iterations will expand on this foundation with: * Broader cost distribution models * Deeper vendor analysis * Subject-level profitability views In its initial form, Credyt Profitability provides platforms with a useful, real-time view into how their product economics are performing. --- ### Usage Events [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) Usage events represent the activities in your system that you want to bill or (in the future) track costs for. Each event corresponds to a measurable outcome, such as an API call, a chat completion, or a video processed. Every usage event has a unique identifier that serves as an idempotency key. This ensures safe retries without accidental double billing, even if the same event is submitted multiple times due to network issues or other errors. When sending usage events you must provide a valid customer identifier. This allows Credyt to match the usage to the correct customer account and apply the appropriate pricing according to their [subscriptions](https://docs.dev.credyt.ai/features/customers.md#subscribe-a-customer-to-a-product). Usage not linked to a valid subscription will be ignored. Usage events are billed in real time and the customer's balance will be debited as soon as an event is processed. Credyt supports a number of usage-based pricing models: * **`unit`** – charges per occurrence of the event (e.g., per chat, per verification, per API call). * **`volume`** – charges based on the volume or quantity consumed, included in the event payload (e.g., tokens, minutes, megabytes). * **`unit_and_volume`** – combines both approaches The `event_type` specified in the usage event must match the `event_type` configured in a product price’s usage calculation configuration for it to be charged for. View [Products and Pricing](https://docs.dev.credyt.ai/features/product-catalog.md) guide for more details. By combining usage events with Credyt’s wallet and rate plan structure, you can build flexible, customer-friendly monetization models, whether you charge in fiat, tokens, or other custom units. ##### Example[​](#example "Direct link to Example") POST https://api.credyt.ai/events ```json { "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "event_type": "video_promoted", "occurred_at": "2025-10-17T21:21:27.024729Z", "subject": "video_5f53d23a4958", "description": "Video Promoted", "data": { "promo_id": "pro_4tbftjwzxja1h71nzas1g0g1xm" // configured as `source_reference_field` } } ] } ``` #### Correlating Usage[​](#correlating-usage "Direct link to Correlating Usage") We recommend you include the `subject` field in all usage events to correlate the usage to an activity in your system. This is used both by the [billing portal](https://docs.dev.credyt.ai/features/billing-portal.md) and later profitability analysis so you can view both revenue and costs for a particular activity. For finer grained traceability, you can include an additional reference that can be linked to a product price's `source_reference_field`. #### Simulating Usage[​](#simulating-usage "Direct link to Simulating Usage") Usage events can also be simulated before they affect actual balances. This is useful for validating new product configurations, experimenting with pricing models, or testing new features without impacting live customers. Simulated events calculate fees in the same way as live events but do not modify the wallet balance. --- ### Wallets and Topups Credyt's unique architecture unifies multiple billing models under a core primitive, the customer wallet. Every customer has one wallet, and that wallet can hold multiple accounts, each dedicated to a specific asset. Accounts are created automatically when a customer is subscribed to a product and can represent both fiat currencies or any [custom assets](https://docs.dev.credyt.ai/features/assets.md) you define. Keeping wallets funded is critical for continuous product use. Credyt gives you two complementary ways to accept top-up payments, powered by Stripe. Hybrid Billing If you have a hybrid billing setup that leverages an external provider, be sure to read our [Adjustments](https://docs.dev.credyt.ai/advanced-topics/adjustments-charges-gifts.md) guide. #### Option 1: Customer Billing Portal[​](#option-1-customer-billing-portal "Direct link to Option 1: Customer Billing Portal") The easiest way for your customers to add funds is through the hosted [Billing Portal](https://docs.dev.credyt.ai/features/billing-portal.md), a self-service billing centre where they can check their balances, manage auto top-ups (recharge), and monitor their product usage: * Customers initiate top-ups directly in the portal * The only integration step is generating a session link and redirecting the customer * No sign-up is required on the customer side * The customer is responsible for defining the top-up amount * For custom assets, the default exchange rate is used Read more about the billing portal [here](https://docs.dev.credyt.ai/features/billing-portal.md). ##### Create a Billing Portal Session[​](#create-a-billing-portal-session "Direct link to Create a Billing Portal Session") [API Reference](https://docs.dev.credyt.ai/api/billing-portal-create-portal-session.md) POST https://api.credyt.ai/billing-portal/sessions ```json { "customer_id": "{{customerId}}", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt/failure" } ``` **Response** ```json { "redirect_url": "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "expires_at": "2025-10-18T07:23:43Z" } ``` Redirect the customer to the `redirect_url`, where the customer can view their balance and initiate a top-up. #### Option 2: Top-up API[​](#option-2-top-up-api "Direct link to Option 2: Top-up API") Use the Top-up API when you want more control over the top-up flow, for example, if you choose to embed a top-up CTA directly within your product. * You collect or define the amount to top up in your own product * Your backend calls the Top-up API to create a checkout session * Credyt returns a `redirect_url` that navigates directly to the top-up payment page * After payment, the customer is returned to the customer billing portal * When topping up custom assets you have the option to override the default exchange rate * Use this to implement tiering or incentives ##### Initiate a top-up[​](#initiate-a-top-up "Direct link to Initiate a top-up") [API Reference](https://docs.dev.credyt.ai/api/top-ups-ops-initiate-top-up.md) POST https://api.credyt.ai/top-ups ```json { "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "amount": 25.0, "currency": "USD", "description": "Video Promotion Credits", "return_url": "https://glitch.ai/account", "failure_url": "https://glitch.ai/callbacks/credyt-failure" } ``` **Response** ```json { "id": "top_473cr1y0ghbyc3m1yfbwvn3nxx", "status": "initiated", "redirect_url": "https://billing.credyt.ai/api/sign-in?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", "created_at": "2024-07-29T15:51:28.071Z", "expires_at": "2024-07-29T15:51:28.071Z" } ``` Redirects the customer to the `redirect_url` to complete the top-up payment. #### Check the Wallet Balance[​](#check-the-wallet-balance "Direct link to Check the Wallet Balance") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md) After we receive confirmation that payment has succeeded the customer's wallet account balance will be updated. Typically this happens before the customer is redirected back to the billing portal. You can query a customer's wallet balances at any time, via the Customer Wallet API. ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** ```json { "accounts": [ { "id": "default:USD", "name": "default", "asset": "USD", "available": 14.566678 }, { "id": "default:TOK", "name": "default", "asset": "TOK", "available": 993450234 } ] } ``` #### Testing[​](#testing "Direct link to Testing") To make testing easier, all payments in test mode are processed through Credyt's default test Stripe account. We'll be adding the ability to use your own Stripe account for testing in the near future. When testing payments interactively with Stripe, you can use their standard test cards, for example: * Number: `4242 4242 4242 4242` * Expiry: Any future month/year (e.g. `12/34`) * CVC: any three‑digit CVC e.g. `123` * Any values for the other fields For the full list of test card numbers and scenarios, see [Stripe’s docs](https://docs.stripe.com/testing#cards). --- ## Advanced Topics ### Adjustments, Gifts and Ad-hoc Charges The Adjustments API is the main way to keep customer balances in sync with events that happen outside of Credyt. Whenever a payment, refund, or credit is processed externally, the platform is responsible for notifying Credyt so that wallet balances stay accurate. #### Common use-cases[​](#common-use-cases "Direct link to Common use-cases") 1. **External PSP payments** - when subscription or top-up payments are processed through your own payment provider, you add the balance in Credyt via an adjustment. 2. **Refunds** - when funds are returned to a customer, you subtract the amount with a refund adjustment. 3. **Free credits / gifts** - when you want to reward users, run promotions, or compensate for issues, you credit the customer's balance directly. 4. **Ad-hoc charges** - when you may need to apply charges manually, outside of the normal usage processing flow. #### External PSP Payments[​](#external-psp-payments "Direct link to External PSP Payments") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) When subscriptions or top-ups are charged through your own PSP, the payment never reaches Credyt directly. To maintain accurate balances, send an adjustment with the same amount and asset. A detailed implementation guide is available in our [Hybrid model](https://docs.dev.credyt.ai/use-cases/hybrid-model.md) article. ##### Example[​](#example "Direct link to Example") This adjustment adds $25 to the customer’s USD account. POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": 25, "description": "Monthly Subscription", "reason": "external_topup", "expires_at": "2024-07-29T15:51:28.071Z", "metadata": { "psp": "stripe", "payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0" } } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` #### Refunds[​](#refunds "Direct link to Refunds") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) Refunds are negative adjustments. You refund through your PSP (or Stripe Dashboard if using Credyt payments), then notify Credyt. For further details, refer to our [Refunds article](https://docs.dev.credyt.ai/advanced-topics/refunds.md). ##### Example[​](#example-1 "Direct link to Example") This subtracts $20 from the customer’s fiat account balance (externally refunded). POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": -20, "description": "Technical failure", "reason": "external_refund", "expires_at": "2024-07-29T15:51:28.071Z", "metadata": { "psp": "stripe", "payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0" } } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` #### Free Credits / Gifts[​](#free-credits--gifts "Direct link to Free Credits / Gifts") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) Credyt allows you to grant gifts or free credits to customers through the Adjustments API. This lets you reward users, run promotions, or compensate for issues with a simple API call that updates their wallet balance in real-time. You can also define an expiry date for these credits when granting them, enabling time-limited promotions and helping drive engagement, and monetization. You can issue credits without a payment by applying a positive adjustment. ##### Example[​](#example-2 "Direct link to Example") Customer wallet is credited with 1,000 tokens. POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "TOKENS", "amount": 1000, "description": "Signup bonus", "reason": "gift", "expires_at": "2024-07-29T15:51:28.071Z", "metadata": { "signup_channel": "referral", "referral_id": "2c963f66afa6" } } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` #### Ad-hoc Charges[​](#ad-hoc-charges "Direct link to Ad-hoc Charges") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-charge.md) While usage-based billing is typically driven by real-time events, there are situations where you may need to apply charges manually, outside of the normal usage processing flow. Use **ad-hoc charge adjustments** to do exactly that. Ad-hoc charges are another form of balance adjustment, but unlike credits or gifts, they always deduct funds from a customer’s balance. This makes them particularly useful in scenarios where: * Usage data cannot be sent in real time due to technical issues or service interruptions * External data providers (for example, an AI API or third-party service) deliver usage information with delays * You need to apply one-off or corrective fees that aren’t tied to a usage event — such as overage adjustments, manual service fees, or administrative costs Each charge includes details such as the amount, currency, description, and subject (a contextual reference, such as a session or service ID). You can also include optional metadata and store calculation inputs (e.g., volume, rate, or unit price) for traceability and transparency to the customer. All ad-hoc charges appear in the customer’s Billing Portal usage history, displaying the information provided in the `Create a charge` request - including descriptions, amounts, and other contextual details you’ve shared. To ensure safe retries, each request must include a unique `transaction_id`, which acts as an idempotency key. If the same `transaction_id` is sent again, Credyt will recognize it as a duplicate and will not duplicate the charge. ##### Example[​](#example-3 "Direct link to Example") POST https://api.credyt.ai/customers/:customerId/wallet/charges ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "subject": "chat_5f53d23a4958", "description": "Overage costs for GPT-4 usage", "metadata": { "model": "gpt-4-1" }, "input_units": null, "input_volume": 2652000, "unit_price": null, "volume_rate": 0.5, "package_size": 1000000, "amount": 1.326 } ``` #### Key requirements and best practices[​](#key-requirements-and-best-practices "Direct link to Key requirements and best practices") * A unique `transaction_id` is required for each adjustment. * Amounts should be positive for crediting the account (top-ups, subscriptions, gifts) and negative for debiting the account (refunds, other adjustments). * The `reason` field indicates the type of adjustment (`external_topup`, `external_refund`, `gift`, `other`). * The `metadata` field can be used to attach PSP references, campaign IDs, or internal notes for reconciliation. --- ### Checkout Branding Stripe Checkout supports flexible branding options that help your topup flow feel native to your platform’s experience. When your customers add funds through the Billing Portal or via topup sessions, they will see your custom colours, logo, and other brand elements directly in Stripe’s hosted interface. You can configure these settings from your connected Stripe Dashboard under Settings → Business → Branding. Once saved, your branding automatically applies to all Checkout sessions initiated through Credyt. From your Stripe Dashboard, you can: * Upload your company logo. * Define primary and accent colours to match your platform’s theme. * Set your business name and statement descriptor for better payment recognition. * Adjust fonts and shapes of the checkout elements. These changes require no additional API configuration; updates made in your Stripe Dashboard take effect immediately. Branding settings can be tested in the test environment once you’ve connected a Stripe test account, or directly in the production account during pre-production testing, as changes are fast to execute and apply in real time. For detailed setup guidance, see [Stripe’s branding configuration documentation](https://docs.stripe.com/get-started/account/branding). --- ### Refunds [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) Refunds are not currently supported directly within Credyt. If you need to issue refunds, you must do so directly with your payment provider (your PSP or Stripe, if you use Credyt’s built-in payments). You can then use the Wallet Adjustments API to adjust the customer’s balance within Credyt. #### Refunds with an External PSP[​](#refunds-with-an-external-psp "Direct link to Refunds with an External PSP") If you use your own PSP for payment processing: 1. Initiate the refund through your PSP’s dashboard or API. 2. Notify Credyt of the refunded amount using the Adjustments API. Use a unique `transaction_id` and specify `reason: "external_refund"`. ##### Example[​](#example "Direct link to Example") This subtracts $20 from the customer’s fiat account balance. POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": -20, "description": "Technical failure", "reason": "external_refund", "expires_at": "2024-07-29T15:51:28.071Z" } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` #### Refunds with Credyt Payments[​](#refunds-with-credyt-payments "Direct link to Refunds with Credyt Payments") If you use Credyt’s built-in payments processing (via Stripe): 1. Initiate the refund in the Stripe Dashboard. Stripe handles payment reversal, receipts, and settlement. 2. Notify Credyt of the refund through the Adjustments API, so the customer’s balance is updated. ##### Example[​](#example-1 "Direct link to Example") This subtracts $20 from the customer’s fiat account balance. POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": -20, "description": "Technical failure", "reason": "external_refund", "expires_at": "2024-07-29T15:51:28.071Z" } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` #### Best Practices[​](#best-practices "Direct link to Best Practices") * Always send refunds as a negative adjustment with `reason: "external_refund"`. * Use a unique identifier for `transaction_id` that ties the refund to the original payment. The Adjustments API supports metadata, which you can use to attach identifiers or other relevant information to make reconciliation and traceability easier. * Keep refund amounts and currencies consistent with the original payment to avoid reconciliation issues. --- ### Stripe Payments This article explains how to connect your own Stripe account to Credyt for testing and production payments, configure checkout branding, and (optionally) set up tax rules. #### Overview[​](#overview "Direct link to Overview") Credit partners with Stripe to process customer payments for wallet top-ups and automated balance refills. Using Stripe via Credyt allows your platform to manage payments securely, provide receipts, and ensure that wallet balances are updated accurately without additional development effort. During early testing, all payments are handled through Credyt’s shared test Stripe account, so you can start integrating without needing to set up your own account. As you approach go-live, we recommend connecting your own test Stripe account. This ensures that your integration behaves exactly as it will in production, allowing you to test branding, tax calculations, and refunds in a realistic environment. * Stripe is used to process all top-ups and auto-refills for your customers’ wallets. * Initial sandbox testing runs through Credyt’s shared test account, so no setup is required to start integration. * Connecting your own test Stripe account allows you to validate your integration before going live. * Both test and live Stripe environments are supported, and you can connect to each separately to maintain isolation between testing and production. #### Connect Your Own Stripe Account[​](#connect-your-own-stripe-account "Direct link to Connect Your Own Stripe Account") When you’re ready to move closer to production, connecting your own Stripe account allows you to test payments and branding under conditions that closely match your live environment. While initial sandbox testing uses Credyt’s shared test account, using your own account ensures your integration behaves exactly as it will in production. * Connecting your own Stripe account lets you test refunds, branding, and tax workflows in a realistic environment. Connecting your Stripe account is straightforward: Credyt generates an onboarding link from your Platform Dashboard. You click the link and complete Stripe’s connection flow. In test mode, no KYC or real bank account details are required; fast-click through the test onboarding flow to complete the set-up. Once connected, your Stripe account will handle all top-ups and auto-refills initiated through Credyt. This gives you full visibility into payment activity, including transaction metadata, while Credyt automatically synchronises wallet balances without additional engineering effort. * Click the onboarding link in your Platform Dashboard to connect your Stripe account. * In test mode, no KYC or payout setup is required, so you can quickly validate payments, branding, and tax configurations. * You’ll see all payments and related metadata (customer IDs, topup references, and amounts) directly in your Stripe Dashboard. * After a successful connection, your Stripe account will appear as “connected” in your Platform Dashboard. **Note**: > You can safely skip this step for early sandbox testing, but connecting your own account before production is strongly recommended. #### Handling Refunds and Disputes[​](#handling-refunds-and-disputes "Direct link to Handling Refunds and Disputes") All refund and dispute operations are managed directly in Stripe. When a customer requests a refund, you need to initiate it from your Stripe Dashboard. Keep in mind that refunded amounts are not automatically updated in the Credyt wallet balance. To ensure accuracy, your platform must also send Credyt an Adjustment request to deduct the amount refunded from the wallet. ##### Issue a refund[​](#issue-a-refund "Direct link to Issue a refund") 1. Log in to your Stripe Dashboard. 2. Use the global search bar to locate the customer or payment. You can search using: * Email address * Credyt customer ID * External (platform) customer ID, if implemented 3. Open the payment you want to refund. 4. Use the Actions menu to issue either a full or partial refund. After the refund is processed in Stripe, your platform must submit an Adjustment request to Credyt to deduct the refunded amount from the customer’s wallet. ##### Disputes[​](#disputes "Direct link to Disputes") Disputes (chargebacks) are also managed in Stripe. Credyt does not automatically reverse or resolve disputed payments. Your platform should monitor disputes directly in Stripe and follow their resolution workflow. Once the dispute outcome is known, you can adjust the corresponding wallet balance in Credyt if funds need to be credited or debited. [Learn more about handling disputes in Stripe](https://docs.stripe.com/disputes) #### Configure and Test Tax (Optional)[​](#configure-and-test-tax-optional "Direct link to Configure and Test Tax (Optional)") If your products require tax calculation, Stripe Tax can help you automatically determine and collect the right amount of tax for each top-up or payment. This configuration happens entirely in your connected Stripe account, and most of the required business information (such as company name, address, and registration details) is already available from the onboarding process. To enable and test tax handling: * Enable Stripe Tax from your connected Stripe Dashboard — setup is straightforward since most required data points are pre-filled from onboarding. * Make sure your business address and product codes are correct, as these determine the applicable tax regions and rates. * Trigger a test top-up session with tax enabled to verify that Stripe correctly calculates and displays tax amounts in both Checkout and the Tax module in your Stripe Dashboard. * Optionally, explore value-added services available through Stripe’s partner ecosystem, such as automated filing and tax reporting — these may require additional setup or subscription. At this stage, tax configuration and testing are handled directly in Stripe; no API changes are needed in Credyt. For detailed setup guidance, see [Stripe’s Tax documentation](https://docs.stripe.com/tax). #### Going Live with Stripe[​](#going-live-with-stripe "Direct link to Going Live with Stripe") Once you’re ready to move from testing to production, you’ll need to connect your live Stripe account. This ensures that top-ups and automated balance refills in your production environment are fully operational and compliant. To go live: * **Start from your production Credyt account.** Initiate the Stripe onboarding directly from your production Credyt Platform Dashboard, just as you did in test mode. During this step, you can either create a new Stripe account or link an existing one to Credyt. If you choose to link an existing Stripe account, your existing credentials and business profile information will remain intact (and can be edited during onboarding if needed). Payment activities and settings associated with Credyt will, however, remain segregated - managed under the Credyt connected account within your Stripe Dashboard, separate from your original Stripe setup. * **Complete Stripe’s onboarding and KYC process.** Stripe will guide you through its standard verification steps. Credyt pre-fills certain data points for convenience (such as business name, support email, and website), but you can edit these details in Stripe’s onboarding form if needed. If you connect an existing Stripe account that’s already verified, the KYC process is typically faster, as Stripe will reuse much of your existing information. * **Wait for Stripe’s review and approval.** After submitting all requested details, Stripe will review your account. In some cases, they may require additional verification (for example, a full SSN in the U.S. or proof of identity). This review can take a few days, and the account won’t be able to accept payments until it’s approved. We recommend starting this process at least two weeks before your anticipated launch date to avoid delays. * **Confirm the connection.** Once Stripe has approved the account and enabled payments, the Stripe section in your Credyt Platform Dashboard will display the status Connected — indicating that you’re ready to process live payments. #### Troubleshooting[​](#troubleshooting "Direct link to Troubleshooting") Even with a smooth setup, you may occasionally run into issues during onboarding or payments. Below are the most common cases and how to resolve them. ##### Onboarding link expired or invalid[​](#onboarding-link-expired-or-invalid "Direct link to Onboarding link expired or invalid") If your Stripe onboarding link no longer works (for example, if too much time has passed or you closed the tab before completing it): * Return to your Credyt Platform Dashboard and generate a new onboarding link. * Use the new link to pick up the process where you left off. ##### Stripe account shows as “Pending” in Credyt[​](#stripe-account-shows-as-pending-in-credyt "Direct link to Stripe account shows as “Pending” in Credyt") This means Stripe is still reviewing your details or awaiting verification documents. * Log in to your Stripe Dashboard and check for any required actions or document uploads. * Once you complete these steps, your status in Credyt will automatically update to Connected once Stripe approves the account. ##### Payments fail during testing or production[​](#payments-fail-during-testing-or-production "Direct link to Payments fail during testing or production") If a test or live payment fails: * Confirm that your Stripe account is fully connected in Credyt (status: *Connected*). * Check the Stripe Dashboard → Payments tab for error codes or messages. Stripe provides detailed failure reasons such as insufficient funds, card declines, or incomplete setup. * Ensure that webhooks are enabled in your connected account - Credyt uses them to update wallet balances after successful payments. ##### Refunds not reflected in Credyt balance[​](#refunds-not-reflected-in-credyt-balance "Direct link to Refunds not reflected in Credyt balance") Credyt does **not** automatically update wallet balances when a refund is processed in Stripe. * To adjust the wallet, your platform must send an Adjustment request to Credyt’s API after issuing the refund in Stripe. * This ensures the balance in Credyt accurately reflects the refunded amount. ##### Tax or branding changes not visible in Checkout[​](#tax-or-branding-changes-not-visible-in-checkout "Direct link to Tax or branding changes not visible in Checkout") If tax amounts or branding updates aren’t appearing as expected: * Confirm you’re editing settings in the same Stripe account connected to your current Credyt environment (test vs production). * For tax issues, verify that Stripe Tax is enabled and correctly configured (see Stripe Tax documentation). The most common issues revolve around the configuration of product tax codes and applicable jurisdictions (states or countries). * Branding changes under Settings → Business → Branding apply immediately in real time, but you may need to refresh or reopen your Checkout session to see updates. --- ## Use Cases ### Fiat vs Custom Units AI platforms bill in many ways: some charge directly in fiat currencies for transparency, others rely on credits for consumer-friendly experiences, and many introduce custom assets like tokens, GPU hours, or video minutes to match usage more closely to product value. Credyt supports all these cases with a simple model: every customer has one wallet, and that wallet can hold multiple accounts, each dedicated to a specific asset. Accounts are created automatically on first top-up and can represent fiat, credits, or any custom unit you define when configuring products and pricing. #### Fiat Accounts[​](#fiat-accounts "Direct link to Fiat Accounts") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-account.md) A fiat account tracks balances in real currencies like USD or EUR. When a customer holds an account in fiat, usage is deducted in fiat terms (e.g. $0.006 per second). Fiat accounts are straightforward to reconcile and enterprise-friendly. **Example:** ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet/:accountId' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** ```bash { "pending_in": 500, "pending_out": 100, "id": "default:usd", "name": "default", "asset": "USD", "available": 14.566678 } ``` Credyt returns information about `default:usd` account in the customer’s wallet such as pending transactions and available balance. #### Credit Accounts (Custom Units)[​](#credit-accounts-custom-units "Direct link to Credit Accounts (Custom Units)") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-account.md) A credits account holds balances in abstract units like “tokens” or “video minutes.” You can create and manage any custom asset you wish to offer. Each asset can have multiple exchange rates for different fiat currencies. Credyt uses the exchange rate to convert fiat to custom assets when topping up the customer balance. Read more about [Asset management](https://docs.dev.credyt.ai/features/assets.md). **Example:** ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet/:accountId' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** ```bash { "pending_in": 50000, "pending_out": 10000, "id": "default:tok", "name": "default", "asset": "TOK", "available": 993450234 } ``` #### Mixed Accounts (Fiat + Custom Units)[​](#mixed-accounts-fiat--custom-units "Direct link to Mixed Accounts (Fiat + Custom Units)") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md) A single wallet can contain both fiat and credit accounts. Top-ups are applied to the correct account depending on the asset type. Usage events deduct from the account linked to the billed product asset. **Example Wallet:** ```bash curl -L 'https://api.credyt.ai/customers/:customerId/wallet' \ -H 'Accept: application/json' \ -H 'X-CREDYT-API-KEY: ' ``` **Response** ```bash { "accounts": [ { "id": "default:usd", "name": "default", "asset": "USD", "available": 14.566678 }, { "id": "default:tok", "name": "default", "asset": "TOK", "available": 993450234 } ] } ``` Here, the customer has both a fiat balance ($14.56) and a balance of 993450234 tokens. --- ### Hybrid Model **Subscriptions and Topups** Many AI platforms start with subscriptions and later add topups to handle usage spikes. Usage spikes can dramatically increase infrastructure spend, making subscription-only models insufficient for real-world profitability. That’s why a hybrid billing model, combining stable subscriptions with usage-based topups, is becoming prevalent in the AI economy. Credyt supports this hybrid approach even if your subscriptions are already managed externally. * **Subscriptions remain outside Credyt** - you keep using your existing PSP and billing system. * **Credyt is informed when a subscription payment succeeds** via the Adjustments API, which credits the customer’s wallet. * **Topups for additional usage** can be handled in two ways: * **Through Credyt** - using the Billing Portal or topup API (requires connecting a Stripe account). * **Outside Credyt** - process the payment with your PSP, then notify Credyt using the Adjustments API. This lets you add real-time usage billing without rebuilding your subscription flow or changing payment providers. #### Implementation guide[​](#implementation-guide "Direct link to Implementation guide") ##### Reflect Subscription Payments in Credyt[​](#reflect-subscription-payments-in-credyt "Direct link to Reflect Subscription Payments in Credyt") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) When a subscription renews in your PSP, call the Adjustments API to increase the wallet balance: POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": 25, "description": "Monthly Subscription", "reason": "external_topup", "expires_at": "2024-07-29T15:51:28.071Z", "metadata": { "psp": "stripe", "payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0" } } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` Wallet account balance increases by the subscription value. ##### Handle Topups for Additional Usage[​](#handle-topups-for-additional-usage "Direct link to Handle Topups for Additional Usage") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) **Option A: Use Credyt’s Payment Rails (Stripe Checkout)** * Customer tops up via **Billing Portal** (self-service) or **Topup API** (your UI). Read about [Topups](https://docs.dev.credyt.ai/features/wallets-and-topups.md). * Credyt processes the payment through Stripe. * Requires either creating a new Stripe account or connecting your existing one via Credyt. **Option B: Keep Topups External** * Process the payment with your PSP. * Call the Adjustments API to reflect the new balance in Credyt. POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "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** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` ##### Send Usage Events[​](#send-usage-events "Direct link to Send Usage Events") [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) Once the wallet is funded (from subscription or topups), usage events will deduct balances in real time: POST https://api.credyt.ai/events ```json { "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "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 } } ] } ``` --- ### Subscriptions Only Model Many AI platforms start with a subscription-only model, as it provides predictable recurring revenue and a straightforward customer experience. In some cases, companies rely on this approach due to limitations of their existing billing providers, which may not support real-time usage billing or flexible unit conversions. AI workloads, however, can fluctuate significantly, making it challenging to align subscription revenue with actual infrastructure costs. Credyt approaches this problem differently: instead of managing subscriptions directly, it uses pre-paid wallet balances that can be credited via the Adjustments API and billed in real time as usage occurs. This setup allows platforms to continue processing subscriptions through their existing PSP while gaining real-time usage tracking and flexible billing, and positions them to evolve toward a hybrid subscription and topups model as their needs grow. #### Implementation Guide[​](#implementation-guide "Direct link to Implementation Guide") ##### Reflect Subscription Payments in Credyt[​](#reflect-subscription-payments-in-credyt "Direct link to Reflect Subscription Payments in Credyt") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) When a subscription payment is received in your PSP, call the Adjustments API to credit the customer’s wallet according to the defined asset: POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "transaction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "account_name": "default", "asset": "USD", "amount": 25, "description": "Monthly Subscription", "reason": "external_topup", "expires_at": "2024-07-29T15:51:28.071Z", "metadata": { "psp": "stripe", "payment_intent": "pi_3RjbbNJNSIruR1rb0GwMGpH0" } } ``` **Response** ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "created_at": "2024-07-29T15:51:28.071Z" } ``` The wallet balance is updated as per the specified amount and asset. ##### Send Usage Events[​](#send-usage-events "Direct link to Send Usage Events") [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) As customers use your AI product, report usage events to Credyt. These events deduct from the wallet balance in real time: POST https://api.credyt.ai/events ```json { "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "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 } } ] } ``` Wallet balances decrease in real time as usage is reported, giving you immediate visibility into consumption and remaining credits. ##### Final Notes[​](#final-notes "Direct link to Final Notes") * Platforms continue managing subscriptions with their existing PSP; Credyt does not replace subscription management. * Using pre-paid wallets allows for flexible unit conversions, real-time billing, and a smooth path toward hybrid subscription + topups models. * This approach is ideal for companies looking to add real-time usage tracking without overhauling their existing subscription flows. --- ### 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[​](#implementation-guide "Direct link to Implementation Guide") #### Initialise Wallet Balance with a Top-up[​](#initialise-wallet-balance-with-a-top-up "Direct link to Initialise Wallet Balance with a Top-up") ##### Using Credyt's payment rails[​](#using-credyts-payment-rails "Direct link to Using Credyt's payment rails") * [API Reference Topups](https://docs.dev.credyt.ai/api/top-ups-ops-initiate-top-up.md). * [API Reference Billing Portal](https://docs.dev.credyt.ai/api/top-ups-ops-initiate-top-up.md) If you use Credyt’s payment rails, initiate the flow via [Billing Portal or the Top-up API](https://docs.dev.credyt.ai/features/wallets-and-topups.md). For example, via Top-up API: POST https://api.credyt.ai/top-ups ```json { "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 includes a `redirect_url` to Stripe Checkout. Redirect the customer to complete payment. **Response** ```json { "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" } ``` ##### Using an external PSP[​](#using-an-external-psp "Direct link to Using an external PSP") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-create-adjustment.md) If you handle payments externally, reflect the top-up in Credyt via Adjustments API: POST https://api.credyt.ai/customers/:customerId/wallet/adjustments ```json { "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** ```json { "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[​](#deduct-usage-from-the-wallet "Direct link to Deduct Usage from the Wallet") [API Reference](https://docs.dev.credyt.ai/api/event-ops-send-usage.md) Once a wallet has funds, usage is billed in real time. Each event reduces the available balance. POST https://api.credyt.ai/events ```json { "events": [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "customer_id": "cust_473cr1y0ghbyc3m1yfbwvn3nxx", "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[​](#check-wallet-balance "Direct link to Check Wallet Balance") [API Reference](https://docs.dev.credyt.ai/api/customer-wallet-ops-get-customer-wallet.md) At any time, the platform can query balances: GET https://api.credyt.ai/customers/:customerId/wallet ```bash ``` **Response** ```json { "accounts": [ { "id": "default:usd", "name": "default", "asset": "USD", "available": 14.566678 }, { "id": "default:tok", "name": "default", "asset": "TOK", "available": 993450234 } ] } ``` --- ## API Reference ### API #### [📄️ Introduction](https://docs.dev.credyt.ai/api/credyt-api.md) --- ### Create account Create a new connected account #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get an account's details Returns a connected account's details #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List accounts Returns a paged list of connected accounts #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 303 The request has succeeded. Redirection **Response Headers** * **location** The Location header contains the URL where the status of the long running operation can be checked. --- ### Add a new asset buy rate Adds a new buy rate for an asset #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Create an asset Create a new custom asset #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get an asset's details Returns an existing asset #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List assets Returns a paged list of assets sorted by code alphabetically #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 The request has succeeded. --- ### Get a quote Helper to get a quote for an asset #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 400 * 401 * 422 The request has succeeded. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Create a portal session Creates a new session for the customer billing portal. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Credyt API Version: 1.0 Export * [OpenAPI Spec](https://docs.dev.credyt.ai/openapi/openapi.1.0.yaml) #### Authentication[​](#authentication "Direct link to Authentication") * API Key: ApiKeyAuth | Security Scheme Type: | apiKey | | ---------------------- | ---------------- | | Header parameter name: | X-CREDYT-API-KEY | --- ### Create adjustment Adjustments allow you to directly impact the balance of an account outside of normal usage processing. This might be necessary to reflect out-of-bound operations such as refunds, or if you operate a hybrid setup and collect funds outside of Credyt. Every adjustment must have a corresponding `reason` that influences how revenue is ultimately recognized. The adjustment `transaction_id` is used as an idempotency key to ensure safe retries. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Create a charge Charges allow you to charge ad-hoc fees to an account outside of normal usage processing. The charge `transaction_id` is used as an idempotency key to ensure safe retries. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get a customer's wallet account Returns the detailed balances of a specific account in a customer's wallet #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### Get credit grants for a wallet account Returns credit grants associated with the customer's account. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 400 * 404 The request has succeeded. The server could not understand the request due to invalid syntax. The server cannot find the requested resource. --- ### Get a customer's wallet Returns the available balances of the accounts in a customer's wallet #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### Get a wallet transaction Returns the details of a wallet transaction #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### Create a customer Create a new customer #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Add a subscription to a customer Adds a new subscription to a customer #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get a customer's details Returns a customer's details #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List customers Returns a paged list of customers #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 303 The request has succeeded. Redirection **Response Headers** * **location** The Location header contains the URL where the status of the long running operation can be checked. --- ### Update a customer Update a customer #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 404 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. The server cannot find the requested resource. Client error --- ### Update a subscription Updates a customer's subscription #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 404 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. The server cannot find the requested resource. Client error --- ### Update a subscription product Updates a customer's subscription product #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 404 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. The server cannot find the requested resource. Client error --- ### Get an event's details Returns an event's details and any generated usage fees #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List events Returns a paged list of events ordered by submission date in descending order. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 The request has succeeded. --- ### Submit events Submit usage events for a customer. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Archive a product version Archives an existing product version making it unavailable for subscription #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Create a product Creates a new product #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Update product Updates an existing product creating a new version #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Delete or archive a product Deletes an existing product. If the product has been used it will be archived. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get a product's details Gets the details of an existing product and its versions #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### Get a product version's details Get a version of a product. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List products Get all products #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 303 The request has succeeded. Redirection **Response Headers** * **location** The Location header contains the URL where the status of the long running operation can be checked. --- ### Simulate usage Simulate usage calculation for a product by sending test usage events #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 400 * 401 * 422 The request has succeeded. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Update a product version Update an existing version of a product. Only unpublished versions can be modified. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 409 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. The request conflicts with the current state of the server. Client error --- ### Get a top-up's details Returns an existing top-ups #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### Initiate top-up Initiates a top-up to a customer's wallet. #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Create a vendor Create a new vendor #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get a vendor's details Returns a vendor's details #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List vendors Returns a paged list of vendors #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 303 The request has succeeded. Redirection **Response Headers** * **location** The Location header contains the URL where the status of the long running operation can be checked. --- ### Create a webhook destination Create a new webhook destination #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 201 * 400 * 401 * 422 The request has succeeded and a new resource has been created as a result. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Delete a webhook destination Delete a webhook destination #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 204 * 400 * 401 * 422 There is no content to send for this request, but the headers may be useful. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error --- ### Get a webhook destination's details Returns a webhook destination's details #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 * 404 The request has succeeded. Access is unauthorized. The server cannot find the requested resource. --- ### List webhook events List webhook events with filtering and cursor-based pagination #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 The request has succeeded. Access is unauthorized. --- ### List webhook destinations Returns a paged list of webhook destinations #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 401 The request has succeeded. Access is unauthorized. --- ### Test a connected account webhook destination Test a webhook destination for a connected account #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 202 * 401 * 404 The request has been accepted for processing, but processing has not yet completed. Access is unauthorized. The server cannot find the requested resource. --- ### Test connected account webhook destinations Test webhook destinations for a connected account #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 202 * 401 * 404 The request has been accepted for processing, but processing has not yet completed. Access is unauthorized. The server cannot find the requested resource. --- ### Test a webhook destination Test a webhook destination #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 202 * 401 * 404 The request has been accepted for processing, but processing has not yet completed. Access is unauthorized. The server cannot find the requested resource. --- ### Test webhook destinations Test webhook destinations #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 202 * 401 * 404 The request has been accepted for processing, but processing has not yet completed. Access is unauthorized. The server cannot find the requested resource. --- ### Update a webhook destination Update a webhook destination #### Request[​](#request "Direct link to request") #### Responses[​](#responses "Direct link to Responses") * 200 * 400 * 401 * 422 The request has succeeded. The server could not understand the request due to invalid syntax. Access is unauthorized. Client error ---