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/creditsThe 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
| Field | Type | Description |
|---|---|---|
credits.total | number | Spendable balance. Normally the sum of the three buckets below. |
credits.plan_credits | number | Subscription bucket. 0 when there is no subscription record. |
credits.credit_pack | number | One-time purchase bucket. |
credits.redemption | number | Gift-code / promotion bucket. |
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
| Type | Source | Behavior |
|---|---|---|
plan_credits | Subscription plan | Topped up each billing cycle. Paid plans roll unused credits forward up to a cap; free plans are reset to the plan amount instead of accumulating. |
credit_pack | One-time purchases | Never expire |
redemption | Gift codes, promotions | Never expire |
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
- Plan credits (used first)
- Credit pack credits
- 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:
| Field | Description |
|---|---|
credits_used | Total credits actually deducted for this generation, multiplier-adjusted. |
credits_breakdown | Array of per-model rows: model, amount, base, final, duration_multiplier, pricing. |
Both fields are omitted when no deduction rows exist yet — do not treat their absence as "free".
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"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-sessionThis endpoint lives under /api/credit-usage, not under /api/v1. It authenticates with the same X-API-Key header.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
caller_session_id | string | Conditional | The session id to aggregate. 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. |
startDate | string | No | Lower bound on created_at. Any value new Date() can parse; unparseable values are ignored rather than rejected. |
endDate | string | No | Upper 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"
}
]
}
}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"
}Pre-flight minimums
| Generation type | Minimum total |
|---|---|
| Chat | 1 |
| Image, image edit, speech, sound, transcription, global image edit (upscale / background-removal) | 2 |
| Music | 3 |
| Lipsync, Creative Director, global video edit | 5 |
| Video, video from image, elements, first & last frame | 10 |
| Video-to-video, 3D | 20 |
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 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.