Skip to main content

Overview

Virtual credits are a form of currency that enables pay-as-you-go pricing models where customers are charged based on their actual usage. Unlike subscriptions that provide access to features, credits are consumed when customers use specific services or resources. Credits are ideal for:
  • API call pricing: Charge per API request or batch of requests
  • Compute resources: Bill for processing time, storage, or bandwidth
  • Service units: Token-based access to services like support hours or consulting time
  • Flexible top-ups: Allow customers to purchase credits as needed

Credit System Architecture

Frontier implements credits using a double-entry bookkeeping system:
  • Credit transactions: Add credits to customer accounts (purchases, awards)
  • Debit transactions: Remove credits from accounts (usage consumption)
  • Balance calculation: Sum of credits minus sum of debits
  • Dual entries: Each transaction creates two entries (customer and system accounts)
Double-entry bookkeeping ensures balance accuracy and consistency. For example, when a customer purchases 100 credits, a credit transaction adds 100 to their account while a debit transaction removes 100 from the system account.

Transaction Types

Credit Transactions

Add credits to a customer account:
SourceDescription
system.buyCredits purchased by customer
system.awardedCredits awarded by platform (promotions, rewards)
system.starterOnboarding credits for new customers
system.revertCredits restored from reversed usage
system.overdraftOverdraft credits (if enabled)

Debit Transactions

Remove credits from a customer account:
SourceDescription
Usage reportingCredits consumed via usage APIs
Manual adjustmentsPlatform-initiated debits

Purchasing Credits

Customers purchase credits by buying products with credits behavior through checkout sessions.

Create Credit Product

Define a product that awards credits when purchased:
products:
  - name: support_credits
    title: Support Credits
    description: Purchase support hours as credits
    behavior: credits
    config:
      credit_amount: 100  # Credits awarded per purchase
    prices:
      - name: default
        amount: 20000  # $200.00 in cents
        currency: usd

Purchase Flow

1

Create Checkout Session

Customer initiates checkout for a credit product.
2

Complete Payment

Customer completes payment through Stripe Checkout.
3

Credits Awarded

Upon successful payment, credits are automatically added to the customer’s account.
4

Transaction Created

A credit transaction with source system.buy is recorded.

Create Checkout for Credits

curl -X POST 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/checkouts' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "success_url": "https://example.com/success",
    "cancel_url": "https://example.com/cancel",
    "feature_body": {
      "feature": "support_credits"
    }
  }'

Consuming Credits

Report usage to consume credits from a customer’s account.

Report Usage

curl -X POST 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/usages' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "amount": 20,
    "source": "api_calls",
    "description": "ML model inference - 100 requests",
    "user_id": "user_123",
    "metadata": {
      "model": "gpt-4",
      "requests": "100"
    }
  }'
Parameters:
  • amount: Number of credits to consume (required)
  • source: Source application or event triggering usage (required)
  • description: Human-readable description of usage (optional)
  • user_id: ID of user who initiated usage (optional)
  • metadata: Additional custom data (optional)
If the customer doesn’t have enough credits, the request will fail with insufficient credits error. Ensure you check balance before reporting usage or handle the error gracefully.

Usage Example

Here’s a real-world example of reporting credit usage:
// After running ML inference
const requestCount = 100;
const creditsPerRequest = 0.2;
const totalCredits = requestCount * creditsPerRequest; // 20 credits

const response = await fetch(
  `/v1beta1/organizations/${orgId}/billing/${billingId}/usages`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      amount: totalCredits,
      source: 'ml_inference',
      description: `GPT-4 inference - ${requestCount} requests`,
      user_id: userId,
      metadata: {
        model: 'gpt-4',
        requests: requestCount.toString(),
        tokens_used: '5000'
      }
    })
  }
);

if (!response.ok) {
  if (response.status === 402) {
    // Insufficient credits - prompt user to purchase more
    showPurchaseCreditsModal();
  }
}

Checking Balance

Retrieve the current credit balance for a customer:
curl -X GET 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/balance' \
  -H 'Authorization: Bearer <token>'
The balance represents the total credits available for consumption.

Transaction History

List all credit transactions for a customer:
curl -X GET 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/transactions?start_time=2024-03-01T00:00:00Z' \
  -H 'Authorization: Bearer <token>'
Query Parameters:
  • start_time: Filter transactions from this time (ISO 8601)
  • end_time: Filter transactions until this time (ISO 8601)

Reverting Usage

If usage was incorrectly reported or a service failed, you can revert the usage and restore credits.

Full Revert

Revert the entire usage amount:
curl -X POST 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/usages/{usage_id}/revert' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{}'

Partial Revert

Revert only a portion of the usage:
curl -X POST 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/usages/{usage_id}/revert' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{
    "amount": 10
  }'
This reverts 10 credits out of the original usage amount.
Reverted credits are added back to the customer’s account with source system.revert. Each revert creates a new credit transaction.

Revert Use Cases

  • Service Failures: ML model fails to complete, API request times out
  • Incorrect Billing: Usage was reported with wrong amount
  • Customer Satisfaction: Goodwill credit restoration for issues
  • Testing: Revert test usage in development environments

Awarding Credits

Platform administrators can award credits to customers for promotions, rewards, or compensation:
curl -X POST 'https://frontier.example.com/v1beta1/organizations/{org_id}/billing/{billing_id}/credits' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <admin_token>' \
  -d '{
    "amount": 50,
    "source": "system.awarded",
    "description": "Promotional credits for new customer",
    "metadata": {
      "promotion": "LAUNCH2024"
    }
  }'

Onboarding Credits

Automatically award credits when customers are created or subscribe to plans:

Customer Onboarding Credits

billing:
  customer:
    onboard_credits_with_org: 100
Every new organization receives 100 credits automatically.

Plan Starter Credits

plans:
  - name: starter_monthly
    on_start_credits: 50
    products:
      - name: starter_access
Customers receive 50 credits when they subscribe to this plan.
Onboarding credits have source system.starter and are awarded automatically by the system.

Credit Balance Calculation

The balance is calculated as:
Balance = Sum(Credit Transactions) - Sum(Debit Transactions)
Example:
TransactionTypeAmountBalance
Initial--0
Purchase creditsCredit+100100
Onboarding awardCredit+50150
API usageDebit-20130
ML inferenceDebit-30100
Service failure revertCredit+30130

Monitoring Credit Usage

Low Balance Alerts

Implement proactive notifications when customers are running low on credits:
const balance = await getBalance(customerId);
const threshold = 50; // Warn when below 50 credits

if (balance.amount < threshold) {
  await sendEmail(customer.email, {
    subject: 'Low Credit Balance',
    body: `You have ${balance.amount} credits remaining. Purchase more to continue using the service.`
  });
}

Usage Analytics

Track credit consumption patterns:
SELECT 
  source,
  SUM(amount) as total_credits,
  COUNT(*) as usage_count,
  AVG(amount) as avg_per_usage
FROM transactions
WHERE 
  customer_id = 'cus_123'
  AND type = 'debit'
  AND created_at >= NOW() - INTERVAL '30 days'
GROUP BY source;

Best Practices

1

Check Balance Before Usage

Always verify sufficient credits exist before allowing operations to prevent failures.
2

Implement Graceful Degradation

When credits are insufficient, guide users to purchase more rather than hard-failing.
3

Set Appropriate Credit Amounts

Price credit packages at amounts that align with typical usage patterns.
4

Provide Usage Visibility

Show customers their credit balance and recent transactions in your UI.
5

Enable Alerts

Notify customers proactively when balance is low to prevent service interruptions.
6

Use Descriptive Sources

Set meaningful source values to help customers understand where credits are consumed.
7

Leverage Metadata

Store additional context in metadata for detailed usage analytics and debugging.

Troubleshooting

Insufficient Credits Error

Customer attempted to use more credits than available: Solution:
  • Check balance before reporting usage
  • Guide customer to purchase more credits
  • Consider enabling overdraft (if supported)

Balance Not Updating

Credit transactions not reflecting in balance: Solution:
  • Verify transaction was successfully created (check response)
  • Ensure double-entry transactions completed
  • Check for database synchronization issues

Credits Not Awarded After Purchase

Customer completed payment but credits not added: Solution:
  • Verify product has credits behavior configured
  • Check credit_amount is set in product config
  • Ensure webhook events from Stripe are being processed
  • Review transaction logs for errors

Next Steps

Products and Plans

Create credit products with proper behavior configuration

Subscriptions

Award starter credits with subscriptions

Customers

Configure onboarding credits for new customers

Entitlements

Combine credits with feature access control

Build docs developers (and LLMs) love