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. Works only on the public endpoints listed below, plus MCP when Allow MCP access is ticked. Chat, search, feedback and form-deflect calls also need a reCAPTCHA token when reCAPTCHA is on.

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, with no reCAPTCHA token and no origin check.

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. Open the Integrations tab, under Client Keys.
  4. Click Create key and pick Public key (browser use) or 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://app.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.

Each client key allows 600 requests per minute by default (over it, you get 429), and 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 / list_sources calls do not count against the quota.

Chat API Example

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

// Headers
X-Client-Key: kl_pk_...
X-Captcha-Token: <reCAPTCHA token, when reCAPTCHA is on>
Accept: text/event-stream
RESPONSE — SSE frames
data: {"citations":[{"title":"Rate Limits","url":"https://docs.example.com/rate","excerpt":"..."}]}

data: {"delta":"Use ","done":false}
data: {"delta":"the ","done":false}
data: {"delta":"X-RateLimit-Limit ","done":false}
data: {"delta":"header...","done":false}

data: {"done":true,"thread_id":"...","message_id":"...","citations":[...]}

Search API Example

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

// Headers
X-Client-Key: kl_pk_...
X-Captcha-Token: <reCAPTCHA token, when reCAPTCHA is on>
RESPONSE
{
  "results": [
    {
      "chunk": { "content": "Pass your API key as...", "heading_path": ["Authentication"] },
      "document": { "title": "Authentication", "url": "https://docs.example.com/auth" },
      "rrf_score": 0.031,
      "rerank_score": 0.79
    }
  ],
  "count": 1
}

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": [{ "label": "Product", "value": "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_<name>_knowledge_sources (search_docs also works), ask_question, list_sources, feedback, get_documents (off by default)

MCP Server

Every knowledge base can have its own Model Context Protocol (MCP) servers: create one under the knowledge base’s Integrations tab → MCP Server and copy its install command. A non-internal knowledge base also answers on the shared endpoint below, with any of its client keys that has Allow MCP access. Cursor, Claude Desktop, ChatGPT with MCP, and any MCP-compatible client can invoke your knowledge base as structured tools.

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

Tools

  • search_<name>_knowledge_sources — hybrid search returning the best-matching chunks, with titles and URLs. Named after the knowledge base: one called “Acme API” publishes search_acme_api_knowledge_sources. search_docs also works.
  • ask_question — full RAG answer with citations (counts against monthly AI-question quota).
  • list_sources — enumerate the knowledge base’s connected sources.
  • feedback — record a wrong answer or missing documentation. Reports appear in Traces.
  • get_documents — whole pages by URL (up to 10). Off by default, and not listed while off.
// 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

The React and JavaScript SDKs are on npm. Install one with npm install, embed the hosted widget, or call the REST API above directly. See the SDK feature page.

  • @keluhq/sdk — framework-agnostic client for browsers, React Native, and Node.js 18 or later.
  • @keluhq/react — <KeluChat /> component and useKeluChat headless hook. Needs React 18 or later.
  • Hosted widget — Ask AI launcher, one script tag from widget.kelu.dev.
<!-- Hosted widget --> <script async src="https://widget.kelu.dev/kelu-widget.js" data-widget-id="YOUR_WIDGET_ID" data-client-key="kl_pk_..."></script> # Or stream an answer from the REST API curl -N https://app.kelu.dev/api/v1/public/knowledge-bases/KB_ID/chat \ -H "X-Client-Id: kl_ci_..." \ -H "X-Client-Secret: kl_cs_..." \ -H "Content-Type: application/json" \ -d '{"query": "How do I paginate the list endpoint?"}'

Quotas & Errors

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

Free

100

AI questions / month

Pro

1,000

AI questions / month

Enterprise

Custom

contact sales

Above quota: streaming chat returns an SSE error frame with error_code: quota_exceeded, and non-streaming calls such as form-deflect return 402 Payment Required, each 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