Kolbo.AIKolbo.AI Docs
Developer API

Projects

Drop SDK generations into a specific project instead of the auto-created "API Generations" bucket.

By default every generation made through the SDK lands in an auto-created project called "API Generations". Most users want their API output to show up alongside the rest of their work in the web app -- so every generation endpoint accepts an optional project_id body field that routes the result into the project of your choice.

Listing Projects

The API has no concept of project names -- only ObjectIds. Call GET /v1/projects to discover the ID for any project the API key's user can write to (owned, or shared with edit / full / owner permission).

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

Response:

{
  "success": true,
  "projects": [
    { "id": "65f1c8a2e4b0a3c1d9f5e123", "name": "Acme Campaign", "role": "owner",  "is_default": false },
    { "id": "65f1c8a2e4b0a3c1d9f5e456", "name": "Shared Brand Kit", "role": "edit",  "is_default": false },
    { "id": "65f1c8a2e4b0a3c1d9f5e789", "name": "API Generations", "role": "owner", "is_default": true  }
  ]
}

The project with is_default: true is the auto-created "API Generations" bucket. SDK calls land there whenever project_id is omitted.

View-only shares are filtered out -- the SDK can only write into projects you can edit.

Using project_id

Add project_id to the body of any generation endpoint:

curl -X POST https://api.kolbo.ai/api/v1/generate/image \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A neon-lit alleyway at midnight",
    "project_id": "65f1c8a2e4b0a3c1d9f5e123"
  }'

The generation will appear in that project in the web app, mixed with sessions created from the UI.

project_id is per-call, not sticky — there is no server-side "current project". Once you are working inside a named project, pass its id on every generation, upload, and chat call; any call that omits it falls back to "API Generations".

Moving a Session Between Projects

If a session ended up in the wrong project (usually the "API Generations" default), move it — together with all of its media library items — instead of regenerating:

PATCH /api/v1/sessions/:sessionId/project
FieldTypeRequiredDescription
project_idstringYesTarget project ObjectId. You need edit / full / owner permission on it.
typestringNoSession type hint to speed up the lookup: image, video, video_from_image, music, speech, sound, image_edit, creative_director, chat, elements, first_last_frame, lipsync, video_from_video, transcription, global_image_edit, global_video_edit, shorts. Omit if unsure — all types are probed.

Works for any session you own: generation sessions (the session_id returned on every generation submit), chat conversations, transcription sessions, and so on.

curl -X PATCH https://api.kolbo.ai/api/v1/sessions/65f1c8a2e4b0a3c1d9f5e999/project \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "project_id": "65f1c8a2e4b0a3c1d9f5e123" }'

Response:

{
  "success": true,
  "session": {
    "id": "65f1c8a2e4b0a3c1d9f5e999",
    "name": "API Image Generation - 2026-07-12",
    "project_id": "65f1c8a2e4b0a3c1d9f5e123",
    "previous_project_id": "65f1c8a2e4b0a3c1d9f5e789",
    "moved_media_count": 3
  }
}

moved_media_count is the number of media library items carried along with the session. Moving a session to the project it is already in is a no-op that returns success.

To move individual media items (rather than a whole session), see the media move endpoints in Media Library: PATCH /v1/media/:id/project, POST /v1/media/bulk/move, and POST /v1/media/folders/:id/move-contents.

Creating and Managing Projects

POST /api/v1/projects            — { "name": "…", "description": "…" }  (plan project limits apply)
PUT  /api/v1/projects/:id        — { "name": "…", "description": "…" }  (rename / update brief)
PUT  /api/v1/projects/:id/archive     — hide from the active list (reversible)
PUT  /api/v1/projects/:id/unarchive   — restore

The description (max 10k chars, markdown) doubles as the project brief and feeds the AI profile. Deletion is intentionally not exposed — deleting a project cascades to every session, generation, and media item, so it stays an in-app, human-confirmed action.

Listing Sessions

GET /api/v1/sessions?project_id=&type=&page=&limit=

Enumerates the caller's sessions across ALL types (image, video, music, chat, transcription…), newest activity first. type accepts the same values as the session-move endpoint. Each row: session_id, name, type, project_id, timestamps. Pairs with PATCH /v1/sessions/:sessionId/project for reorganizing.

Project Knowledge Base (Context / RAG)

Feed domain knowledge into a project — scripts, briefs, research, URLs — and the platform synthesizes a living markdown profile used to ground AI work in the project.

POST   /api/v1/projects/:projectId/context/url    — { "url": "…" }
POST   /api/v1/projects/:projectId/context/text   — { "text": "…", "title": "…" }
GET    /api/v1/projects/:projectId/context        — list sources (with AI summaries + status)
DELETE /api/v1/projects/:projectId/context/:fileKey
GET    /api/v1/projects/:projectId/profile        — the synthesized living brief (markdown)
POST   /api/v1/projects/:projectId/profile/regenerate

Sources return status: "analyzing" and settle in the background — no polling needed. Adding sources requires edit+ permission on the project; reading requires any access.

Errors

StatusCodeCause
400SDK_PROJECT_INVALID_IDproject_id is not a valid ObjectId.
403SDK_PROJECT_ACCESS_DENIEDYou have view permission on the project but not edit or higher.
404SDK_PROJECT_NOT_FOUNDThe project does not exist, is soft-deleted, or you have no access at all. (We return 404 for both cases so the API does not leak project existence.)
404(Session move) the session does not exist or is not owned by you.

MCP Tools

If you are using Kolbo through the @kolbo/mcp server (Claude Desktop, Claude Code, claude.ai connector), the matching tools are list_projects and move_session. Every generate_* tool accepts an optional project_id arg whose value comes from that list.

1. list_projects
2. pick the project the user named -> capture its `id`
3. generate_image  (or any other generate_* tool)
   { prompt: "...", project_id: "<id from step 2>" }

When the user does not mention a project, omit project_id and the generation lands in the user's "API Generations" default. If something landed in the wrong project, move_session relocates a whole session (plus its media), and move_media / bulk_move_media relocate individual items.