Skip to content

Credits System

CutX uses a credit-based billing system. Every AI generation costs credits, deducted atomically when a job is created.

Job TypeCreditsUnderlying CostModel
copy1Free (Workers AI)Llama 3.1 70B
static_ad3~$0.04/imageFlux 1.1 Pro
tts2~$0.045/30sMinimax Speech
ugc_video40~$4.50/30sOmniHuman
i2v10~$0.50–1.00/clipWan 2.2
reframe20~$2.50/30sLuma
scrape0FreeBuilt-in

Credits are deducted before the job runs — not after:

1. User submits generation request
2. System checks credit balance
3. If sufficient → atomically deduct credits + create job
4. If insufficient → return 402 (Payment Required)
5. Job enters queue for processing

The deduction is recorded as a credit_transaction with:

  • type: "deduction"
  • reference_id: the job ID
  • balance_after: new balance after deduction

The deductCredits() function uses a conditional update:

UPDATE credit_balances
SET balance = balance - $cost,
lifetime_used = lifetime_used + $cost
WHERE user_id = $userId AND balance >= $cost

If the balance is too low, zero rows are affected and the request is rejected. This prevents race conditions from concurrent requests.

Credits are refunded automatically when a job fails:

Job fails → markJobFailed() → refundCredits()

Refunds create a transaction with:

  • type: "refund"
  • reference_id: the job ID
  • description: reason for the refund

Refunds restore the exact number of credits that were deducted. Scrape jobs (0 credits) skip the refund step.

Credits enter user accounts through four channels:

TypeDescription
purchaseOne-time credit pack via Stripe Checkout
subscriptionMonthly allocation from an active plan
bonusAdmin-granted credits (promotional, support)
free_tier25 credits on account creation (automatic)
PackCreditsPrice
Starter50$4.99
Creator150$12.99
Pro500$39.99
Studio1500$99.99
TierMonthly CreditsPriceAd Spend Fee
Free25 (one-time)$06%
Starter100/mo$9.99/mo6%
Pro500/mo$29.99/mo5%
Agency2000/mo$99.99/mo4%

Subscription credits are added on each billing cycle. Unused credits carry over — they never expire.

Each user has a credit_balances row with:

FieldDescription
balanceCurrent spendable credits
lifetime_purchasedTotal credits ever added
lifetime_usedTotal credits ever deducted

A trigger automatically creates this row with 25 free credits when a new user signs up.

Every credit movement is logged in credit_transactions:

{
"id": "uuid",
"user_id": "uuid",
"amount": -3,
"type": "deduction",
"description": "static_ad generation",
"reference_id": "job-uuid",
"balance_after": 47,
"created_at": "2026-03-09T..."
}

This provides a complete audit trail for debugging and support.