Kolbo.AIKolbo.AI Docs
Developer API

Credits & Billing

Check your credit balance and understand how credits work.

All generations consume credits from your account. Credits come from your subscription plan, credit packs, and redemptions.

Endpoint

GET /api/v1/account/credits

The endpoint takes no query parameters and no request body. It always reports the balance of the account the API key belongs to — there is no way to query another user.

curl

curl https://api.kolbo.ai/api/v1/account/credits \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

async function main() {
  const response = await fetch("https://api.kolbo.ai/api/v1/account/credits", {
    headers: { "X-API-Key": "YOUR_API_KEY" }
  });
  const data = await response.json();
  console.log(data.credits.total);
}
main();

Python

import requests

response = requests.get(
    "https://api.kolbo.ai/api/v1/account/credits",
    headers={"X-API-Key": "YOUR_API_KEY"}
)
print(response.json()["credits"]["total"])

Response

{
  "success": true,
  "credits": {
    "total": 1500,
    "plan_credits": 1000,
    "credit_pack": 400,
    "redemption": 100
  }
}

Response Fields

FieldTypeDescription
credits.totalnumberSpendable balance. Normally the sum of the three buckets below.
credits.plan_creditsnumberSubscription bucket. 0 when there is no subscription record.
credits.credit_packnumberOne-time purchase bucket.
credits.redemptionnumberGift-code / promotion bucket.

Balances are numbers, not integers — some charges (chat turns, for example) are billed in tenths of a credit, so expect values like 1499.7.

total is not always the sum of the three buckets. Legacy accounts predating the bucket split report all three buckets as 0 while total carries the real balance from the account's single legacy credit field. Always spend against total; treat the three buckets as informational.

total is a gross balance — it does not subtract in-flight reservations. Credits for a generation that is still running are held as a reservation and are already unavailable, but they are still counted in total. Immediately after firing a batch, total reads higher than what you can actually spend.

Credit Types

TypeSourceBehavior
plan_creditsSubscription planPaid personal credits roll over while paid access is active, with new monthly grants capped at three monthly allocations. Annual plans also allocate monthly. Free plans reset instead of accumulating.
credit_packOne-time purchasesNever expire; no monthly or 90-day reset. Separate from the subscription balance cap and retained after paid access ends.
redemptionGift codes, promotionsNever expire

The three-allocation subscription cap is a balance cap, not a three-month expiry. When paid access ends, the subscription bucket returns to the free allowance; purchased pack credits remain. See Subscription & Billing for retention and comparison rules. The Developer USD wallet is a separate product; these credit-bucket rules describe the credit-billed API.

Credit Deduction

Credits are reserved when a generation starts and confirmed at the real, multiplier-adjusted cost when it finishes. If a generation fails or is cancelled, the reservation is released and any already-deducted credits are refunded.

Deduction Order

  1. Plan credits (used first)
  2. Credit pack credits
  3. Redemption credits

Legacy accounts with no buckets deduct from their single credit field instead. Every bucket is floored at zero, so a race can never drive a balance negative.

What a Generation Actually Cost

Poll GET /api/v1/generate/{generation_id}/status. Once state is completed the response carries the authoritative numbers:

FieldDescription
credits_usedTotal credits actually deducted for this generation, multiplier-adjusted.
credits_breakdownArray with one { model, amount } row per deduction linked to the generation. model is the billed model identifier; amount is what that row deducted.

Both fields are omitted when no deduction rows exist yet — do not treat their absence as "free". Base vs. final cost and resolution per deduction are available from the caller-session endpoint below (recent[].base / final / resolution).

GET /api/v1/generate/creative-director/{id}/status never carries credits_used or credits_breakdown — each scene is billed independently. Reconcile Creative Director batches with the caller-session endpoint below.

Cancelling returns credits_refunded on the cancel response:

curl -X POST https://api.kolbo.ai/api/v1/generate/GENERATION_ID/cancel \
  -H "X-API-Key: YOUR_API_KEY"
{
  "success": true,
  "generation_id": "6650...",
  "type": "video",
  "state": "cancelled",
  "credits_refunded": 40
}

credits_refunded falls back to 0 when the cancel reports no refunded amount. Cancelling a batch also returns batch_cancelled_count. Cancel failures return 404 (NOT_FOUND, or no code at all when the id is not one of your API generations), 403 (FORBIDDEN), 409 (CANNOT_CANCEL, NOT_IN_PROGRESS) or 503 (CANCELLATION_SETTLEMENT_PENDING).

What a Whole Integration Session Cost

Every request may carry an optional X-Kolbo-Caller-Session-Id header — a stable identifier you choose for one run of your integration (see Authentication). Credit deductions made while that header is present are tagged with it, and you can aggregate them afterwards:

GET /api/credit-usage/by-caller-session

This endpoint lives under /api/credit-usage, not under /api/v1. It authenticates with the same X-API-Key header.

Query Parameters

ParameterTypeRequiredDescription
caller_session_idstringConditionalThe session id to aggregate. Wins over the header when both are sent. Required unless you send the same value in the X-Kolbo-Caller-Session-Id header on this request. Must be a string — an array or object value returns 400. Truncated to 128 characters.
startDatestringNoLower bound on created_at. Any value new Date() can parse; unparseable values are ignored rather than rejected.
endDatestringNoUpper bound on created_at. Same parsing rule.
curl "https://api.kolbo.ai/api/credit-usage/by-caller-session?caller_session_id=run-2026-07-27-a" \
  -H "X-API-Key: YOUR_API_KEY"

Response

{
  "message": "Caller-session usage retrieved successfully",
  "data": {
    "caller_session_id": "run-2026-07-27-a",
    "total": 184,
    "count": 12,
    "by_tool": [{ "generation_type": "image", "amount": 96, "count": 8 }],
    "by_model": [{ "model": "nano-banana-2", "amount": 96, "count": 8 }],
    "recent": [
      {
        "amount": 12,
        "model": "nano-banana-2",
        "generation_type": "image",
        "generation_id": "6650...",
        "created_at": "2026-07-27T10:00:00Z",
        "base": 8,
        "final": 12,
        "resolution": "2K"
      }
    ]
  }
}

Only deduction records are counted (refunds are not netted out). Charges where you were the requester on a shared project but another account paid are included. by_tool and by_model are sorted by amount, highest first.

total is the real, multiplier-adjusted spend — not an estimate from base credits. recent is capped at the 50 most recent deductions, newest first. Missing the id entirely returns 400 with caller_session_id required as a string (query param or X-Kolbo-Caller-Session-Id header).

Insufficient Credits

The generation routes listed in the table below run a pre-flight balance check before doing any work. It compares your total against a per-type minimum floor — a lower bound meant to reject requests that cannot succeed with any model of that type. Failing it returns 403:

{
  "success": false,
  "error": "Insufficient credits for image. Your balance is 1, minimum required: 2. Top up at app.kolbo.ai to continue.",
  "code": "INSUFFICIENT_CREDITS",
  "balance": 1,
  "required": 2,
  "pricing_url": "https://app.kolbo.ai/pricing?..."
}
FieldDescription
balanceYour current total (0 when the account has no subscription record).
requiredThe floor for this generation type (table below).
pricing_urlLink to the app's pricing page, where plans and credit packs are bought.

Pre-flight minimums

Generation typeRoutes (under /api/v1)Minimum total
ChatPOST /chat, POST /analyze/video1
Image, image editPOST /generate/image, POST /generate/image-edit2
Speech, sound, transcriptionPOST /generate/speech, POST /generate/sound, POST /transcribe2
Global image editPOST /edit/image2
MusicPOST /generate/music (including composition_plan mode), POST /generate/music/extend, POST /generate/music/cover3
Lipsync, Creative DirectorPOST /generate/lipsync, POST /generate/creative-director5
Global video editPOST /edit/video (skipped for operation: "draft_quote")5
Video, video from image, elements, first & last framePOST /generate/video, POST /generate/video/from-image, POST /generate/elements, POST /generate/first-last-frame10
Video-to-video, 3DPOST /generate/video-from-video, POST /generate/3d20
Audio separationPOST /audio/separate, POST /audio/clean-dialogue, POST /audio/ambience20

Any generation type not in this table falls back to a floor of 1. These are floors, not prices — clearing one says nothing about whether the model you picked is affordable.

Other credit-spending routes carry no SDK-layer floor at all — POST /visual-dna/character-sheet, POST /video/trim, POST /voices/clone, POST /generate/music/reference-audio, POST /generate/music/edit-section and the two paid /music-library actions go straight to the underlying controller, whose own reservation is the first and only credit check. Expect the insufficient-credits error from those to arrive later and in the controller's own shape, not as a synchronous INSUFFICIENT_CREDITS.

Passing this pre-flight check does not mean the generation is affordable. It only proves you clear the floor for that generation type — and the check is deliberately best-effort: if the balance lookup itself fails, the request is allowed through rather than blocked. The real reservation happens afterwards using the selected model's exact cost, and can still fail. Compute the expected cost from GET /api/v1/models (see Models & Pricing) before submitting anything expensive.

Getting More Credits

  • Upgrade your plan at kolbo.ai/pricing
  • Purchase credit packs from your dashboard

There is no API to buy credits — top-ups happen in the app only. To show a user what they could buy, read the read-only catalog:

GET /api/v1/account/plans
curl https://api.kolbo.ai/api/v1/account/plans \
  -H "X-API-Key: YOUR_API_KEY"

The response carries your account's real plans, prices and promotions:

FieldDescription
successtrue.
credits.totalSame spendable balance as /account/credits.
current_plan{ key, name } of your subscription plan, or null.
plans, credit_packsArrays with the same row shape: key, name, interval, credits, price, original_price, discount_percent, promo_text, currency (default usd), top_up_discount, subscriber_price, is_subscriber. price is what you would pay now (promotional or subscriber price when one applies); original_price is the list price when a discount applies, otherwise null. discount_percent / promo_text are set only when you are eligible for a promotion. top_up_discount marks plans whose subscribers get cheaper credit packs; on a pack, subscriber_price is that cheaper price and is_subscriber says whether you already qualify.
pricing_urlLink to the app's pricing page — the only place a purchase can be made.

This route never creates a checkout session or payment link.