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
| Scope | Purpose |
|---|---|
kairo.code:stream | Access Kairo Code streaming endpoint |
kairo.models:read | Read 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 UIKairo 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 rawresponse+ asynceventsstreamText(request)-> convenience text accumulatorstreamAcp(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;
streamAcpworks 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-acpRuntime env vars:
KAIRO_ACCESS_TOKEN(required)KAIRO_BASE_URL(optional, defaults tohttps://coline.app)KAIRO_MODEL_ID(optional, defaults togpt-5.2)KAIRO_ENABLE_TOOLS(optional, defaultfalse)
Claude thinking controls
- Claude Opus 4.6: use
thinkingEffortwithlow,medium,high, ormax(adaptive thinking) - Opus 4.6
thinkingEffort: "max"uses a higher usage multiplier (6x). - Claude Sonnet 4.5 / Opus 4.5: use
reasoningLevelas on/off (0off,1-3on). Gateway uses a fixed32kthinking budget when on. thinkingBudgetis deprecated for Claude in public integrations.- Interleaved thinking is enabled on Bedrock requests by the gateway (
interleaved-thinking-2025-05-14beta header).
Gateway guardrails
The Kairo Code gateway applies public integration guardrails:
modelTypesupports the same full model set as Kairo and Coline CodecompareModeis disableduseWebSearchanduseImageGenare disabledenableToolsdefaults tofalseso editor-native tools remain primary (settrueto opt in)reasoningLevelaccepts0through3thinkingEffortacceptslow,medium,high,max
Endpoint reference
| Method | Path | Purpose |
|---|---|---|
| GET | /api/kairo/oauth/authorize | Start OAuth Authorization Code flow |
| POST | /api/kairo/oauth/token | Token exchange / refresh / device polling |
| POST | /api/kairo/oauth/device/authorize | Start device flow |
| GET | /api/kairo/models | List available models |
| POST | /api/kairo/code/stream | Stream Kairo Code responses |
Integration checklist
- Create OAuth client and enable
kairo.code:stream - Implement PKCE or device flow login
- Store and rotate refresh tokens
- If host is ACP/A2A-native, use
streamAcpas the adapter entrypoint - Call
/api/kairo/code/streamwith user access token - Parse SSE and surface incremental output in your editor
- Handle quota/authorization errors in UI