Documentation

API Reference

The Kelu public API — client-key authenticated endpoints for streaming chat with citations, hybrid search, form deflection, WebSocket chat, and the MCP server. Full docs live at docs.kelu.dev.

Authentication

The public API uses two credential formats. Pick the one that matches where the code runs.

Public Client Key

Safe to embed in browsers, mobile apps, and other client-side code. Scoped to a single knowledge base. Only allows Chat, Search, Feedback, Suggested, Related, and Form-Deflect endpoints.

X-Client-Key: kl_pk_your_public_key

Format: kl_pk_…

Client ID + Secret

For server-side integrations. Must not be exposed client-side. Same endpoint coverage as the public key, plus write endpoints on higher tiers.

X-Client-Id: kl_ci_…
X-Client-Secret: kl_cs_…

Format: kl_ci_… + kl_cs_…

Getting Your Keys

  1. Log in to your Kelu dashboard.
  2. Open the knowledge base you want to expose.
  3. Navigate to Integration Keys.
  4. Create a Public Client Key (browser use) or a Client ID + Secret pair (server use).
  5. Copy the credentials — secrets are shown once. Keys are scoped to that KB and can be revoked instantly.

Base URL

https://api.kelu.dev

All responses are JSON. Chat endpoints stream as text/event-stream (SSE); an alternative WebSocket transport is available at /api/v1/public/knowledge-bases/:knowledgeBaseId/ws.

Rate limiting is billing-based, not per-minute: each Chat call counts against your monthly AI-question quota. Free = 100/mo, Pro = 1,000/mo, Enterprise custom. Search, suggested-questions, and MCP search_docs / list_sources calls do not count against the quota.

Chat API Example

REQUEST — POST /api/v1/public/knowledge-bases/:kbId/chat
{
  "message": "How do I rate-limit the API?",
  "thread_id": "<optional prior conversation id>",
  "top_k": 8,
  "group_ids": []
}

// Headers
X-Client-Key: kl_pk_...
Accept: text/event-stream
RESPONSE — SSE frames
data: {"citations":[{"title":"Rate Limits","url":"https://docs.example.com/rate","excerpt":"..."}]}

data: {"token":"Use "}
data: {"token":"the "}
data: {"token":"X-RateLimit-Limit "}
data: {"token":"header..."}

data: {"done":true,"conversation_id":"...","message_id":"..."}

Search API Example

REQUEST — POST /api/v1/public/knowledge-bases/:kbId/search
{
  "query": "authentication API key",
  "top_k": 5,
  "group_ids": []
}

// Headers
X-Client-Key: kl_pk_...
RESPONSE
{
  "results": [
    {
      "title": "Authentication",
      "url": "https://docs.example.com/auth",
      "excerpt": "Pass your API key as...",
      "score": 0.97
    }
  ]
}

Form Deflection Example

Non-streaming — returns a cited answer with a confidence score, plus a deflect flag. Use inside a support form to answer questions before they become tickets.

REQUEST — POST /api/v1/public/knowledge-bases/:kbId/form-deflect
{
  "subject": "Billing question",
  "message": "How do I upgrade my plan?",
  "fields": { "product": "Pro" }
}
RESPONSE
{
  "answer": "Open Settings → Billing and click 'Upgrade to Pro'...",
  "citations": [ /* ... */ ],
  "confidence": 0.91,
  "deflect": true,
  "conversation_id": "...",
  "deflection_id": "..."
}

All Public Endpoints

Chat

POST/api/v1/public/knowledge-bases/:knowledgeBaseId/chatSSE streaming RAG chat with citations
POST/api/v1/public/threads/:threadId/chatContinue a previous chat thread (SSE)
GET/api/v1/public/knowledge-bases/:knowledgeBaseId/wsWebSocket chat transport (alternative to SSE)

Search & Suggestions

POST/api/v1/public/knowledge-bases/:knowledgeBaseId/searchHybrid search — returns ranked chunks with scores
POST/api/v1/public/knowledge-bases/:knowledgeBaseId/relatedRelated-articles for a given question
GET/api/v1/public/knowledge-bases/:knowledgeBaseId/suggested-questionsQuestion suggestions for the widget

Feedback

POST/api/v1/public/feedbackRecord a thumb up/down on a message
DELETE/api/v1/public/feedback/:messageIdWithdraw a previously-recorded vote

Form Deflection

POST/api/v1/public/knowledge-bases/:knowledgeBaseId/form-deflectAnswer a support-form submission before it becomes a ticket (non-streaming, returns confidence)

Widget Config

GET/api/v1/public/knowledge-bases/:knowledgeBaseId/widget-configWidget bootstrap: knowledge-base name, captcha requirement, site key, hide-branding permission

MCP (Model Context Protocol)

POST/mcpJSON-RPC — tools: search_docs, ask_question, list_sources

MCP Server

Every knowledge base exposes a Model Context Protocol (MCP) endpoint. Cursor, Claude Desktop, ChatGPT with MCP, and any MCP-compatible client can invoke your knowledge base as structured tools.

POST https://api.kelu.dev/mcp
X-Client-Key: kl_pk_…

Tools

  • search_docs — hybrid search returning ranked chunks with scores.
  • ask_question — full RAG answer with citations (counts against monthly AI-question quota).
  • list_sources — enumerate the knowledge base’s connected sources.
// JSON-RPC 2.0 { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "ask_question", "arguments": { "question": "How do I paginate the list endpoint?" } }, "id": 1 }

See the MCP feature page for setup instructions per client (Cursor, Claude, ChatGPT).

SDKs

Every public endpoint is also reachable via the typed SDKs. See the SDK feature page.

  • @kelu/sdk — framework-agnostic client for browsers, React Native, and Node.
  • @kelu/react <KeluChat /> component and useKeluChat headless hook.
  • @kelu/widget — hosted Ask AI launcher, one script tag.
npm install @kelu/sdk import { Kelu } from "@kelu/sdk"; const kelu = new Kelu({ clientKey: "kl_pk_..." }); const stream = await kelu.chat({ knowledgeBaseId: "kb_abc123", message: "How do I paginate the list endpoint?", }); for await (const event of stream) { if (event.type === "token") process.stdout.write(event.text); if (event.type === "citations") console.log("sources:", event.citations); }

Quotas & Errors

Each end-user chat message counts as one AI question. Search, suggested-questions, and MCP search_docs / list_sources calls don’t count.

Free

100

AI questions / month

Pro

1,000

AI questions / month

Enterprise

Custom

contact sales

Above quota: chat requests are rejected with a 402 Payment Required response (or, on streaming paths, an SSE error frame) with a specific quota-exceeded message. Upgrading takes effect immediately.

Need help?

Full docs at docs.kelu.dev. Anything not covered? Contact us.

Contact Support