USD Console Quick Start
Discover models, obtain a fixed USD quote, and safely track an API generation.
The USD console is in development. Catalog presence does not mean a model can run.
Check quoteSupported, quoteCapabilities, and the returned quote's
generationEnabled. Do not submit while generation is disabled.
Choose the correct API
| Existing Developer API | USD console | |
|---|---|---|
| Base path | /api/v1 | /api/developer-console |
| Balance | Kolbo subscription credits | Separate prepaid USD balance |
| Credential | Existing app API key | USD console API key |
| Generation | Type-specific generation endpoints | Fixed quote, then job submission |
USD keys cannot call the credit-billed API. Neither balance automatically funds the other. Sign in with your existing Kolbo account to manage the console; keep API keys in your server's secret store, never in browser code or prompts.
1. Let your agent discover the contract
Set KOLBO_API_BASE to your deployment's /api/developer-console base. For local
development, use http://127.0.0.1:5050/api/developer-console.
Read these public endpoints first:
GET /llms.txt: short agent instructions and safety rules.GET /discovery: capabilities, endpoints and current availability.GET /openapi.json: machine-readable request and response schemas.GET /catalog?page=1&limit=100: model IDs, options, media and starting prices.
These four are public (no key) and share a limit of 30 requests per minute per IP.
Catalog page accepts 1–1000 and limit 1–100; anything else returns
400 INVALID_PAGINATION. Follow nextPage until it is null. Use the exact model ID
and an allowed request variant. Do not guess parameters from the model name or copy a
different model's settings. Starting prices are not final quotes.
Authenticated endpoints (send X-API-Key):
| Method and path | Purpose |
|---|---|
GET /account | Payer account.id (user:… or org:…), kind, name, canManage, plus balance, fundingEnabled, paymentMode, generationEnabled |
POST /inputs/image | Upload one private PNG, JPEG or WebP (max 20 MiB, 16 megapixels) |
POST /inputs/video | Upload one private MP4 (max 500 MiB, 300 seconds) |
POST /inputs/audio | Upload one private WAV, MP3, OGG or M4A (max 100 MiB, 300 seconds) |
POST /quotes | Obtain a fixed USD quote |
POST /jobs | Submit an approved quote |
POST /jobs/reconcile | Resolve an uncertain submission |
GET /jobs/{id} | Track a job |
GET /requests?page=1&limit=100&modelId= | Paginated reservation history (modelId optional) |
GET /analytics?month=YYYY-MM | Daily UTC usage per model for one month (defaults to the current month) |
Uploads are multipart/form-data with exactly one field named file and no other
fields. They require a write-enabled key and return 201 with { "input": { "id", "kind", "contentType", "size", "width", "height", ..., "expiresAt" } }.
No public URL is returned; pass input.id into the quote. Do not automatically retry
an upload whose outcome is uncertain.
2. Obtain a fixed price
This request obtains a quote only. It does not start generation or charge funds.
curl "$KOLBO_API_BASE/quotes" \
-H "X-API-Key: $KOLBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"seedance-2-5","prompt":"A quiet mountain lake at sunrise","duration":4,"resolution":"720p","aspectRatio":"16:9","soundEnabled":true}'Text-to-video requires model, prompt, duration (integer seconds), resolution,
aspectRatio and soundEnabled (must be true), and omits operation and
quality. Other request shapes select a variant with operation. Validate the body
against discovery.requestSchemas.quote, then narrow it with the chosen model's
quoteCapabilities; model limits can be narrower than the schema. Unknown fields are
rejected.
operation | Required fields | Media input |
|---|---|---|
| omitted (text-to-video) | model, prompt, duration, resolution, aspectRatio, soundEnabled | none; optional draft: true forces 480p Draft where supported |
text_to_image | model, operation, prompt, resolution (1K, 2K, 4K), aspectRatio; quality only when quoteCapabilities.qualities lists values | optional inputImageId (one reference image) when quoteCapabilities.inputImage permits it |
image_to_video | text-to-video fields plus operation, inputImageId | one uploaded image |
video_edit | model, operation, prompt, resolution, inputVideoId | one uploaded video; duration is inherited from the source |
video_extend | video_edit fields plus duration (4–30 new seconds) | one uploaded video |
draft_references | text-to-video fields plus operation, references; model seedance-2-5 (resolution 480p-draft) or seedance-2-5-draft (resolution 480p); duration 4–30 | 1–12 { id, role }: either one first_frame plus an optional last_frame (with aspectRatio: "adaptive"), or up to 9 reference_image and 3 reference_video entries (40 video seconds total) |
draft_enhance | model, operation, sourceJobId, resolution | a completed draft job you own; no prompt or duration |
multilingual | text-to-video fields plus operation, references; model is seedance-2-5-multilingual | up to 3 { id, role: "reference_image" } |
morphious | model, operation, resolution, aspectRatio, references; optional prompt | 1–31 { id, role }: exactly one reference_video plus the mode's allowed number of reference_image entries |
genjutsu | model, operation, resolution (480p or 720p), references; optional prompt | 2–9 { id, role }: exactly one reference_video, the rest reference_image |
lipsync | model (seedance-2-5-lipsync), operation, mode (dialogue or music_video), durationMs (4000–30000), resolution, aspectRatio, scenePrompt, characters (up to 3), references (1–16) | clips (up to 12, dialogue), music (one excerpt), stills (up to 3 image IDs); reference roles dialogue_audio, music_audio, still_image |
Every media ID is a UUID returned by an upload endpoint for the same account. Per-model
reference counts, durations and resolutions are in each catalog model's
quoteCapabilities.
A quote response contains id, account, request (the normalized request),
amountMicroUsd, currency (USD), expiresAt and generationEnabled. Media-input
quotes other than image_to_video also return billableSeconds.
Display amountMicroUsd / 1000000 as USD. Obtain the payer's approval for that
amount. Check generationEnabled and expiresAt before submission. Video-input
quotes require an account-owned inspected inputVideoId; input and output seconds
may both be billable. Do not send a media URL in place of that ID.
3. Submit once, then track the same job
Before sending, durably save the quote id, the quote's account (the same value
as GET /account account.id) and a fresh UUID as the idempotency key. The key must
match ^[a-zA-Z0-9_-]{16,100}$. Submit only these fields:
{
"quoteId": "THE_APPROVED_QUOTE_ID",
"expectedAccount": "THE_QUOTE_ACCOUNT",
"idempotencyKey": "YOUR_PERSISTED_UUID"
}Send this body to POST /jobs with a write-enabled X-API-Key. Any other field
returns 400 INVALID_JOB; an expectedAccount that differs from the key's payer
returns 409 ACCOUNT_CHANGED. Never send a client-calculated price. A successful
submission returns 202 with the job. Poll GET /jobs/{id} every five seconds while
queued or running; slow down to thirty seconds for needs_attention.
A job contains id, account, model, status (queued, running,
needs_attention, completed or failed), amountMicroUsd, currency,
createdAt, chargedMicroUsd (non-zero only when completed), reservedMicroUsd
(non-zero only while queued or running) and metadata. A failed job adds
failure: { code, message }; a completed job adds result: { url, expiresAt } while
the output is available.
- Completed: retrieve
result.urlbeforeresult.expiresAt. Stream the bytes into your own storage. Saving the URL alone does not retain the output. - Failed: inspect the job's charged and reserved amounts; do not infer billing from the HTTP response alone.
- Unknown submission outcome: retain the same saved identity. Retry that exact
payload or send it to
POST /jobs/reconcile. Never create a new key merely because a request timed out.
Reconciliation does not start generation. It returns
{ account, status: "accepted", job } for an admitted attempt, or
{ account, status: "not_admitted" }, which permanently closes that unaccepted attempt. A reconciliation error
is still unresolved, not permission to duplicate it.
Never send your API key to the result's media URL.
Limits and money
The current concurrency limit is 20 queued/running requests per account, shared
across keys and the playground. Exceeding it returns 429 CONCURRENCY_LIMIT with
Retry-After: 5, retryAfter: 5 and maxConcurrent: 20.
Rate limits are separate; honor Retry-After and retryAfter:
| Endpoints | Limit | 429 code |
|---|---|---|
llms.txt, discovery, openapi.json, catalog | 30 / minute / IP | none; the body is { "status": false, "error": "...", "message": "..." } |
POST /quotes | 60 / minute / user | QUOTE_RATE_LIMIT |
POST /jobs, POST /jobs/reconcile | 60 / minute / user | JOB_RATE_LIMIT |
GET /jobs/{id} | 240 / minute / user | POLL_RATE_LIMIT |
POST /inputs/* | 6 / minute / user | INPUT_RATE_LIMIT (INPUT_INSPECTOR_BUSY when processing capacity is full, INPUT_STORAGE_LIMIT when stored inputs are at capacity) |
Apart from that public 429, errors are returned as { "error": { "code": "..." } }:
| Status | Codes |
|---|---|
| 400 | INVALID_QUOTE, INVALID_QUOTE_CONFIGURATION, INVALID_JOB, INVALID_PAGINATION, INVALID_MODEL_ID, INVALID_MONTH, INPUT_FILE_REQUIRED, INVALID_MEDIA_INPUT, LIMIT_FILE_COUNT, LIMIT_FIELD_COUNT, LIMIT_PART_COUNT, LIMIT_UNEXPECTED_FILE |
| 401 / 403 | AUTHENTICATION_REQUIRED, ACCOUNT_ACCESS_DENIED, USD_KEY_REQUIRED, INTERACTIVE_LOGIN_REQUIRED |
| 402 | INSUFFICIENT_FUNDS |
| 404 | QUOTE_NOT_FOUND, INPUT_MEDIA_NOT_FOUND, JOB_NOT_FOUND, DRAFT_NOT_FOUND |
| 409 | ACCOUNT_CHANGED, IDEMPOTENCY_CONFLICT, ADMISSION_CLOSED, PAYMENT_RECOVERY_REQUIRED |
| 410 | DRAFT_EXPIRED |
| 413 / 415 / 422 | LIMIT_FILE_SIZE, MULTIPART_REQUIRED, QUOTE_MODEL_UNSUPPORTED, INPUT_VIDEO_TOO_LONG, DRAFT_RESOLUTION_UNSUPPORTED, INVALID_INPUT_IMAGE, INVALID_INPUT_VIDEO, INVALID_INPUT_AUDIO |
| 429 | CONCURRENCY_LIMIT, QUOTE_RATE_LIMIT, JOB_RATE_LIMIT, POLL_RATE_LIMIT, INPUT_RATE_LIMIT, INPUT_INSPECTOR_BUSY, INPUT_STORAGE_LIMIT |
| 503 | GENERATION_UNAVAILABLE, INPUT_UPLOADS_UNAVAILABLE, QUOTE_UNAVAILABLE, JOB_UNAVAILABLE, CATALOG_UNAVAILABLE, INPUT_UPLOAD_FAILED, ACCOUNT_UNAVAILABLE |
A quote normally expires within ten minutes, or earlier with its input. Outputs are retained for 30 days.
Wallet amounts use integer micro-USD. Catalog usdPerUnit values are already
dollars per the indicated unit. Do not apply subscription-credit discounts or a
second credit-to-dollar conversion. Manage top-ups, payment methods and automatic
refill through interactive console login, not an agent's API key.
Developer API Overview
Programmatically generate images, videos, music, speech, and sound effects with the Kolbo API.
Skills, Plugin & MCP Setup
Connect Kolbo's AI tools to Claude, ChatGPT, Cursor and any MCP app — one-click connector (no API key) or a single config block. Native image, video, music and chat tools.