ColineColineColineDocs

Kairo Code Integration

You can integrate Kairo Code into external editors or agents today, without waiting for the full Platform API.

Kairo Code integrations call:

  • POST https://coline.app/api/kairo/code/stream

after authenticating users with Coline OAuth.

What is ready now

  • Production endpoint: POST /api/kairo/code/stream (SSE)
  • OAuth flows: Authorization Code + PKCE and Device Flow
  • User billing model: Requests are billed against the user’s Coline Kairo monthly quota
  • Model discovery: GET /api/kairo/models

Authentication model

Kairo Code does not use standalone API keys. Integrations should connect a user account via OAuth.

Required scopes

ScopePurpose
kairo.code:streamAccess Kairo Code streaming endpoint
kairo.models:readRead supported model list

Create your OAuth client in the Developer Console at /developers/ai#kairo-oauth.

OAuth quickstart

1) Start authorization (PKCE)

const scope = "kairo.code:stream kairo.models:read";
const clientId = "kairo_client_your_id";
const redirectUri = "https://your-editor.com/oauth/callback";

const authorizeUrl = new URL("https://coline.app/api/kairo/oauth/authorize");
authorizeUrl.searchParams.set("response_type", "code");
authorizeUrl.searchParams.set("client_id", clientId);
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
authorizeUrl.searchParams.set("scope", scope);
authorizeUrl.searchParams.set("state", state);
authorizeUrl.searchParams.set("code_challenge", codeChallenge);
authorizeUrl.searchParams.set("code_challenge_method", "S256");
window.location.assign(authorizeUrl.toString());

2) Exchange code for tokens

const tokenRes = await fetch("https://coline.app/api/kairo/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    grant_type: "authorization_code",
    client_id: "kairo_client_your_id",
    redirect_uri: "https://your-editor.com/oauth/callback",
    code,
    code_verifier,
  }),
});

const tokens = await tokenRes.json();

Device flow (CLI/IDE)

const start = await fetch(
  "https://coline.app/api/kairo/oauth/device/authorize",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      client_id: "kairo_client_your_id",
      scope: "kairo.code:stream kairo.models:read",
    }),
  },
);

const device = await start.json();
// Show user_code and verification_uri_complete in your UI

Kairo Code stream request

const response = await fetch("https://coline.app/api/kairo/code/stream", {
  method: "POST",
  headers: {
    Accept: "text/event-stream",
    "Content-Type": "application/json",
    Authorization: `Bearer ${accessToken}`,
    "x-coline-client": "my-editor",
    "x-coline-client-version": "1.0.0",
    "x-coline-client-platform": "desktop",
  },
  body: JSON.stringify({
    modelType: "claude-opus-4.6",
    enableTools: false, // default for code gateway; keep editor-native tools primary
    reasoningLevel: 1, // 0 disables thinking, >0 enables it
    thinkingEffort: "high", // low | medium | high | max (Opus 4.6)
    contents: [
      {
        role: "user",
        parts: [{ text: "Review this patch and suggest improvements." }],
      },
    ],
  }),
});

Parse the SSE response

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const frames = buffer.split("\n\n");
  buffer = frames.pop() ?? "";

  for (const frame of frames) {
    const dataLine = frame
      .split("\n")
      .find((line) => line.startsWith("data: "));
    if (!dataLine) continue;
    const payload = JSON.parse(dataLine.slice(6));
    if (payload.error) throw new Error(payload.error);
    if (typeof payload.text === "string") process.stdout.write(payload.text);
  }
}

Kairo Code SDK

The Kairo Code SDK surface is:

  • createKairoCode({ auth, clientInfo, defaultModel, baseUrl, fetch })
  • stream(request) -> returns raw response + async events
  • streamText(request) -> convenience text accumulator
  • streamAcp(request) -> ACP/A2A-friendly event stream (message_delta, tool_*, done)
  • streamAcpText(request) -> convenience text accumulator for ACP/A2A requests
import { createKairoCode } from "@colineapp/kairo-code";
import { createTokenManager, MemoryTokenStorage } from "@colineapp/kairo-auth";
import { extractTextChunks } from "@colineapp/kairo-core";

const tokenManager = createTokenManager({
  clientId: "kairo_client_your_id",
  storage: new MemoryTokenStorage(),
});
await tokenManager.setTokenResponse(tokenResponse);

const kairoCode = createKairoCode({
  auth: tokenManager,
  clientInfo: { name: "my-editor", version: "1.0.0", platform: "desktop" },
});

const { events } = await kairoCode.stream({
  modelType: "gpt-5.2",
  enableTools: false, // set true only if you want Coline tool execution
  contents: [{ role: "user", parts: [{ text: "Refactor this function." }] }],
});

for await (const event of events) {
  for (const chunk of extractTextChunks(event.data)) {
    process.stdout.write(chunk);
  }
}

ACP / A2A integration

Kairo Code remains an OAuth + HTTP/SSE provider (/api/kairo/code/stream), and the SDK now ships the adapter layer for ACP/A2A-style runtimes.

import { createKairoCode } from "@colineapp/kairo-code";
import { createTokenManager, MemoryTokenStorage } from "@colineapp/kairo-auth";

const tokenManager = createTokenManager({
  clientId: "kairo_client_your_id",
  storage: new MemoryTokenStorage(),
});
await tokenManager.setTokenResponse(tokenResponse);

const kairoCode = createKairoCode({
  auth: tokenManager,
  clientInfo: { name: "my-editor", version: "1.0.0", platform: "desktop" },
});

const { events } = await kairoCode.streamAcp({
  modelId: "claude-opus-4.6",
  enableTools: false,
  reasoningEnabled: true,
  thinkingEffort: "high",
  messages: [
    { role: "user", content: "Refactor this function for readability." },
  ],
});

for await (const event of events) {
  if (event.type === "message_delta") {
    process.stdout.write(event.text);
  }
  if (event.type === "workspace_unavailable") {
    console.error(event.message);
  }
}

Notes:

  • ACP naming is kept for compatibility with existing editor integrations.
  • ACP governance and feature work has been converging into A2A under the Linux Foundation; streamAcp works as the adapter layer while you migrate runtime contracts.

ACP CLI bridge package

For ACP-native editors, install the Kairo ACP binary:

bun add -g --no-cache @colineapp/kairo-code-acp

Runtime env vars:

  • KAIRO_ACCESS_TOKEN (required)
  • KAIRO_BASE_URL (optional, defaults to https://coline.app)
  • KAIRO_MODEL_ID (optional, defaults to gpt-5.2)
  • KAIRO_ENABLE_TOOLS (optional, default false)

Claude thinking controls

  • Claude Opus 4.6: use thinkingEffort with low, medium, high, or max (adaptive thinking)
  • Opus 4.6 thinkingEffort: "max" uses a higher usage multiplier (6x).
  • Claude Sonnet 4.5 / Opus 4.5: use reasoningLevel as on/off (0 off, 1-3 on). Gateway uses a fixed 32k thinking budget when on.
  • thinkingBudget is deprecated for Claude in public integrations.
  • Interleaved thinking is enabled on Bedrock requests by the gateway (interleaved-thinking-2025-05-14 beta header).

Gateway guardrails

The Kairo Code gateway applies public integration guardrails:

  • modelType supports the same full model set as Kairo and Coline Code
  • compareMode is disabled
  • useWebSearch and useImageGen are disabled
  • enableTools defaults to false so editor-native tools remain primary (set true to opt in)
  • reasoningLevel accepts 0 through 3
  • thinkingEffort accepts low, medium, high, max

Endpoint reference

MethodPathPurpose
GET/api/kairo/oauth/authorizeStart OAuth Authorization Code flow
POST/api/kairo/oauth/tokenToken exchange / refresh / device polling
POST/api/kairo/oauth/device/authorizeStart device flow
GET/api/kairo/modelsList available models
POST/api/kairo/code/streamStream Kairo Code responses

Integration checklist

  1. Create OAuth client and enable kairo.code:stream
  2. Implement PKCE or device flow login
  3. Store and rotate refresh tokens
  4. If host is ACP/A2A-native, use streamAcp as the adapter entrypoint
  5. Call /api/kairo/code/stream with user access token
  6. Parse SSE and surface incremental output in your editor
  7. Handle quota/authorization errors in UI