Kolbo.AIKolbo.AI Docs
Developer API

Authentication

Create and manage API keys for the Kolbo Developer API.

All API requests require an API key passed via the X-API-Key header.

API Key Format

Keys follow the format kolbo_live_<60 hex characters> — the literal prefix kolbo_live_ plus 30 random bytes rendered as hex.

The kolbo_live_ prefix is mandatory. Any key that does not start with it is rejected as Invalid API key format before any lookup happens.

Creating a Key

Go to Developer Console and click Create Key.

Via API

The key-management endpoints under /api/api-keys sit behind the same authentication layer as the rest of the API, so either credential works: a JWT from your browser session, or an existing X-API-Key that carries write permission. The examples below use the JWT form because that is what the Developer Console does.

An API key with write permission can mint, reveal and revoke further API keys on the same account. Treat a write key as equivalent to full account access and scope your integrations accordingly.

curl -X POST https://api.kolbo.ai/api/api-keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Integration", "permissions": ["read", "write"], "expiresInDays": 365}'

Request Body

ParameterTypeRequiredDescription
namestringYesLabel for the key. Must be a non-empty string; whitespace is trimmed. An empty or non-string value returns 400.
permissionsstring[]NoAny subset of read | write. Defaults to ["read", "write"]. Any other value returns 400admin keys cannot be self-created.
expiresInDaysnumberNoDefaults to 365. Parsed with parseInt, then clamped to 1730. Out-of-range values are clamped rather than rejected (1000730, -51); 0 and unparseable values fall back to 365.

Returns 201 on success:

{
  "status": true,
  "data": {
    "id": "key_id",
    "keyPrefix": "kolbo_live_a1b2c3d4e...",
    "name": "My Integration",
    "permissions": ["read", "write"],
    "createdAt": "2026-03-05T10:00:00Z",
    "expiresAt": "2027-03-05T10:00:00Z"
  },
  "fullKey": "kolbo_live_abc123def456...",
  "message": "API key created. You can view the full key again any time from this page."
}

The full key is not one-time. It is stored encrypted alongside the validation hash, so you can retrieve it again with the reveal endpoint below or from the Developer Console.

Reveal a Key Again

curl https://api.kolbo.ai/api/api-keys/KEY_ID/reveal \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Returns { "status": true, "fullKey": "kolbo_live_..." }. Ownership is enforced in the lookup, so a key belonging to someone else is indistinguishable from one that does not exist (404).

Keys minted before the encrypted-copy feature existed cannot be revealed. They return 400 with This key was created before full-reveal was supported. Create a new key to view it in full. — the only fix is to create a replacement key.

keyPrefix (returned by the create, list and details endpoints) is the first 20 characters of the key followed by a literal .... It is a display label, not a usable credential.

Using the Key

Include it in every request via the X-API-Key header:

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

JavaScript (fetch):

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

Python (requests):

import requests

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

Optional: Tagging a Session

Every request may additionally carry X-Kolbo-Caller-Session-Id, a stable identifier you choose for one run of your integration. Credit deductions made while it is present are tagged with it, so you can later ask what a whole run cost — see Credits & Billing.

HeaderTypeRequiredDescription
X-Kolbo-Caller-Session-IdstringNo1–128 characters, matching [A-Za-z0-9._:-]+ only. A UUID is the expected shape. Anything longer, empty, or containing a character outside that set is silently discarded — the request still succeeds, it is just not tagged.
curl https://api.kolbo.ai/api/v1/models \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Kolbo-Caller-Session-Id: run-2026-07-27-a"

Managing Keys

List Keys

curl https://api.kolbo.ai/api/api-keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Returns { "status": true, "data": [ ... ] }, newest first. The list is not filtered — revoked and expired keys are returned alongside live ones. Read isActive and isExpired rather than assuming every row is usable.

FieldTypeDescription
idstringKey id — the KEY_ID path segment for reveal / details / revoke.
keyPrefixstringFirst 20 characters of the key plus a literal .... Display label, not a credential.
namestringThe label you supplied at creation.
permissionsstring[]read and/or write.
isActivebooleanfalse once revoked. Revocation is a flag flip; the row is never deleted.
isExpiredbooleanComputed against expiresAt at read time.
lastUsedstring | nullTimestamp of the last successful authentication. null if never used.
usageCountnumberIncremented on every successful authentication.
createdAt / expiresAtstringISO timestamps.

Get Key Details

curl https://api.kolbo.ai/api/api-keys/KEY_ID \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Returns the same field set as one list row, under data. A key id that does not exist returns 404; one that exists but belongs to someone else returns 403 — unlike the reveal endpoint, which collapses both into 404.

Revoke a Key

curl -X DELETE https://api.kolbo.ai/api/api-keys/KEY_ID \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Revocation is immediate and permanent — there is no un-revoke. The key stays in the list with isActive: false.

Permission Scopes

A key carries read, write, or both.

  • Safe methods (GET, HEAD, OPTIONS) are always allowed, whatever the key's scope.
  • A key without write (or admin) is blocked on every mutating request, returning 403 with code API_KEY_READ_ONLY.
  • Two paid music routes — POST /api/v1/music-library/clean/{trackId} and POST /api/v1/music-library/import — enforce write permission on every key, including grandfathered ones.

Scope enforcement only applies to keys minted after it was introduced. Older keys are grandfathered and can still perform writes even if their listed permissions say read only. Do not rely on an old key's read label as a security boundary — mint a fresh key if you need a genuinely read-only credential.

Limits

  • Maximum 50 active keys per user (active = not revoked and not expired). Creating a 51st returns 400.
  • Expiration is required — every key has an expiresAt. Default 365 days, clamped to 1–730 days.
  • Permissions: read and write only (admin keys cannot be self-created).
  • Key creation is rate limited to 10 attempts per hour per user; the reveal endpoint to 30 per minute. Both return 429.

When a Key Stops Working

An otherwise valid key is rejected when any of these are true:

ConditionStatusResponse
Wrong prefix, unknown key, revoked, or past expiresAt401Invalid API key format / Invalid or expired API key
Account restricted by an administrator401User account has been restricted
Account soft-deleted and pending permanent deletion401Restore the account via the emailed link to reactivate existing keys
Email not verified403{ "status": false, "message": "...", "emailNotVerified": true }

Every 401 above shares one body — { "message": "...", "tokenExpired": false } — with no code field. The four possible messages are Invalid API key format, Invalid or expired API key, User account has been restricted, and the deletion-grace-window message. Distinguish them by reading message, not by branching on a code.

Keys are not auto-revoked during the deletion grace window, so restoring an account brings its existing keys back without re-creating them.

Security Best Practices

  • Store keys in environment variables, never in code
  • Use separate keys for different integrations
  • Revoke unused keys promptly
  • Monitor usage via the key details endpoint — every successful authentication bumps usageCount and lastUsed