AI Chatbot Builder

Chatbot API Reference

Build, train, and deploy RAG-powered AI chatbots on any website. Query your knowledge base, manage conversations, stream responses, and capture leads — all via REST API.

RAG Search
pgvector semantic search
Multi-source
PDF, URL, Q&A, Drive, Notion
Streaming
SSE token streaming
Rate Limits
Per-session & daily caps

Quick Start

Embed a fully functional RAG chatbot on any page in under 2 minutes.

1

Get your Bot ID from the chatbot builder dashboard

Your Bot ID
bash
1# Found in Dashboard → Web → Chatbot Builder → Deploy tab
2BOT_ID=cb_k7x2m9p3
2

Add the embed snippet before </body>

index.html
html
1<!-- Polybrand AI Chatbot (RAG-powered) -->
2<script>
3 (function(w,d,s,o,f,js,fjs){
4 w['_pbChat']=o; w[o]=w[o]||function(){
5 (w[o].q=w[o].q||[]).push(arguments)};
6 js=d.createElement(s); fjs=d.getElementsByTagName(s)[0];
7 js.async=1; js.src=f; js.id=o;
8 fjs.parentNode.insertBefore(js,fjs);
9 })(window,document,'script','pbchat',
10 'https://widget.polybrand.ai/v1/loader.js');
11
12 pbchat('init', {
13 botId: 'cb_k7x2m9p3', // Your unique Bot ID
14 color: '#6366f1', // Primary brand colour
15 position: 'bottom-right', // 'bottom-right' | 'bottom-left'
16 model: 'gemini-1.5-pro', // LLM model
17 rag: true, // Enable knowledge base lookup
18 });
19</script>

Your chatbot is live — visitors can now chat instantly.

To train the bot on your content, add knowledge sources via the Knowledge Base API or the dashboard builder.

RAG Architecture

Every chat message goes through a Retrieval-Augmented Generation (RAG) pipeline powered by pgvector stored in Supabase. Documents and URLs are chunked, embedded, and stored as 1536-dimensional vectors for cosine-similarity search.

1
User message
WebSocket / REST
2
Embed query
text-embedding-004
3
Vector search
pgvector cosine sim
4
Inject context
top-k chunks → prompt
5
LLM response
Gemini / GPT / Claude
💡Set match_threshold (0–1) to control how strictly the vector search filters results. A value of 0.7 works well for most use cases.

Chat API

POST/v1/chatbot/{bot_id}/chat

Send a user message and receive a RAG-augmented response. Supports both standard JSON and Server-Sent Events streaming.

ParameterTypeRequiredDescription
messagestringrequiredThe user's message text.
session_idstringrequiredClient-generated UUID. Used for rate limiting and conversation threading.
streambooleanoptionalSet to true to receive response as Server-Sent Events (SSE). Default: false.
match_countintegeroptionalNumber of knowledge-base chunks to retrieve. Default: 5.
match_thresholdfloatoptionalMinimum cosine similarity (0–1) for retrieved chunks. Default: 0.7.
Standard Request
bash
1curl -X POST "https://app.polybrand.io/api/v1/chatbot/cb_k7x2m9p3/chat" \
2 -H "Authorization: Bearer pb_live_..." \
3 -H "Content-Type: application/json" \
4 -d '{
5 "message": "What are your business hours?",
6 "session_id": "sess_abc123",
7 "match_count": 5,
8 "match_threshold": 0.72
9 }'
Response (standard)
json
1{
2 "reply": "We\'re open Monday to Friday, 9 AM – 6 PM EST.",
3 "sources": [
4 {
5 "content": "Business hours: Mon–Fri 9AM–6PM EST. Closed weekends.",
6 "source_type": "document",
7 "source_name": "company-faq.pdf",
8 "similarity": 0.94
9 }
10 ],
11 "usage": {
12 "prompt_tokens": 842,
13 "completion_tokens": 23,
14 "total_tokens": 865
15 },
16 "rate_limit": {
17 "messages_remaining": 47,
18 "sessions_today_remaining": 98
19 }
20}
Streaming Request (SSE)
bash
1curl -X POST "https://app.polybrand.io/api/v1/chatbot/cb_k7x2m9p3/chat" \
2 -H "Authorization: Bearer pb_live_..." \
3 -H "Content-Type: application/json" \
4 -d '{"message":"Tell me about your pricing","session_id":"sess_abc123","stream":true}'
SSE Stream
text
1data: {"delta":"Our pricing"}
2data: {"delta":" starts at $"}
3data: {"delta":"29/month"}
4data: {"delta":" for the Starter plan."}
5data: [DONE]
POST/v1/chatbot/{bot_id}/rate-limit/check

Check whether a session or IP is within the configured rate limits before sending a message. Useful for pre-flight checks in custom widget implementations.

Request Body
json
1{
2 "session_id": "sess_abc123",
3 "ip_hash": "sha256_of_visitor_ip"
4}
Response
json
1{
2 "allowed": true,
3 "sessions_today": 3,
4 "messages_in_session": 12,
5 "session_limit": 50,
6 "daily_limit": 100
7}
⚠️Always hash visitor IPs client-side using SHA-256 before sending — never send raw IP addresses to the API.

Conversations API

GET/v1/chatbot/{bot_id}/conversations

Returns a paginated list of conversation sessions. Supports date range filtering for analytics.

Example Request
bash
1curl "https://app.polybrand.io/api/v1/chatbot/cb_k7x2m9p3/conversations?limit=20&since=2026-03-01" \
2 -H "Authorization: Bearer pb_live_..."
Response
json
1{
2 "data": [
3 {
4 "id": "conv_9a3f...",
5 "session_id": "sess_abc123",
6 "started_at": "2026-03-03T10:12:00Z",
7 "ended_at": "2026-03-03T10:18:44Z",
8 "message_count": 8,
9 "escalated": false,
10 "resolved": true,
11 "csat_rating": 5,
12 "lead_data": { "name": "Jane Doe", "email": "jane@example.com" }
13 }
14 ],
15 "pagination": { "has_more": true, "next_cursor": "Y29udl8..." }
16}
PATCH/v1/chatbot/{bot_id}/conversations/{conversation_id}

Update a conversation — typically used to submit a CSAT rating or mark as escalated.

Request Body
json
1{
2 "csat_rating": 5,
3 "escalated": false,
4 "resolved": true,
5 "lead_data": {
6 "name": "Jane Doe",
7 "email": "jane@example.com",
8 "company": "Acme Corp"
9 }
10}

Knowledge Base API

Manage the RAG vector store. Sources are automatically chunked, embedded with Google's text-embedding-004, and indexed into pgvector for instant semantic search.

GET/v1/chatbot/{bot_id}/knowledge

List all knowledge sources (URLs, documents, Q&A pairs) for a chatbot with their indexing status.

Response
json
1{
2 "urls": [
3 {
4 "id": "url_8f3a...",
5 "url": "https://yoursite.com/faq",
6 "status": "indexed",
7 "pages_found": 38,
8 "last_crawled_at": "2026-03-03T08:00:00Z"
9 }
10 ],
11 "documents": [
12 {
13 "id": "doc_4c1b...",
14 "name": "company-handbook.pdf",
15 "size_bytes": 2457600,
16 "status": "indexed",
17 "chunk_count": 124
18 }
19 ],
20 "qa_pairs": [
21 { "id": "qa_7e2f...", "question": "Do you ship internationally?", "answer": "Yes, to 50+ countries." }
22 ],
23 "stats": {
24 "total_chunks": 174,
25 "total_sources": 3,
26 "last_indexed": "2026-03-03T08:12:00Z"
27 }
28}
POST/v1/chatbot/{bot_id}/knowledge/urls

Queue a URL for crawling. The crawler will follow internal links and extract text from all discovered pages.

ParameterTypeRequiredDescription
urlstringrequiredFully-qualified URL to crawl (e.g. https://yoursite.com/faq).
max_depthintegeroptionalMaximum crawl depth from the seed URL. Default: 2.
max_pagesintegeroptionalMaximum number of pages to index. Default: 100.
Request Body
json
1{
2 "url": "https://yoursite.com/faq",
3 "max_depth": 2,
4 "max_pages": 50
5}
Response
json
1{
2 "id": "url_8f3a...",
3 "url": "https://yoursite.com/faq",
4 "status": "queued",
5 "created_at": "2026-03-03T10:00:00Z"
6}
POST/v1/chatbot/{bot_id}/knowledge/documents

Upload a document file for text extraction, chunking, and vector embedding. Supports PDF, DOCX, TXT, CSV, Markdown, and XLSX.

ℹ️Upload documents as multipart/form-data. Maximum file size is 50 MB. Processing time varies: typically 5–30 seconds depending on file size.
Example Request
bash
1curl -X POST "https://app.polybrand.io/api/v1/chatbot/cb_k7x2m9p3/knowledge/documents" \
2 -H "Authorization: Bearer pb_live_..." \
3 -F "file=@company-handbook.pdf" \
4 -F "chunk_size=512" \
5 -F "chunk_overlap=64"
Response
json
1{
2 "id": "doc_4c1b...",
3 "name": "company-handbook.pdf",
4 "size_bytes": 2457600,
5 "file_type": "pdf",
6 "status": "processing",
7 "created_at": "2026-03-03T10:05:00Z"
8}

Poll GET /v1/chatbot/{bot_id}/knowledge or listen for the knowledge.document.indexed webhook to know when processing is complete.

POST/v1/chatbot/{bot_id}/knowledge/qa

Add a guaranteed Q&A pair. These are embedded and stored in the vector store like any other chunk, but always have the highest retrieval priority.

Request Body
json
1{
2 "question": "Do you offer a free trial?",
3 "answer": "Yes! Every plan includes a 14-day free trial. No credit card required."
4}
POST/v1/chatbot/{bot_id}/knowledge/reindex

Trigger a full reindex of all knowledge sources. Useful after bulk updates or when sources have changed significantly.

⚠️Reindexing deletes all existing embeddings and rebuilds the vector store from scratch. The chatbot remains available during reindexing, falling back to the previous index until the new one is ready.
Response
json
1{
2 "job_id": "reindex_job_9c2e...",
3 "status": "queued",
4 "estimated_duration_seconds": 45
5}

Configuration API

GET/v1/chatbot/{bot_id}

Retrieve the full configuration object for a chatbot, including appearance, AI model, rate limits, and lead capture settings.

Response
json
1{
2 "id": "cb_k7x2m9p3",
3 "brand_profile_id": "brd_2k9s8d...",
4 "bot_name": "Acme Assistant",
5 "personality": "professional",
6 "primary_color": "#6366f1",
7 "position": "bottom-right",
8 "window_size": "standard",
9 "theme": "auto",
10 "ai_model": "gemini-1.5-pro",
11 "language": "auto",
12 "is_published": true,
13 "show_sources": true,
14 "rate_limit_messages_per_session": 50,
15 "rate_limit_sessions_per_day": 100,
16 "lead_capture_enabled": true,
17 "lead_capture_fields": { "name": true, "email": true, "phone": false, "company": false },
18 "escalation_enabled": false,
19 "total_conversations": 1204,
20 "total_messages": 8932,
21 "avg_csat": 4.7,
22 "created_at": "2026-01-15T00:00:00Z",
23 "updated_at": "2026-03-03T09:00:00Z"
24}
PATCH/v1/chatbot/{bot_id}

Update chatbot configuration. All fields are optional — only supplied fields are modified.

ParameterTypeRequiredDescription
bot_namestringoptionalDisplay name shown in the chat header.
greetingstringoptionalFirst message sent by the bot when a conversation starts.
system_promptstringoptionalCustom instructions injected into every LLM request.
primary_colorstringoptionalHex color code for the widget's brand accent.
ai_modelstringoptionalLLM to use: gemini-1.5-pro | gemini-1.5-flash | gpt-4o | claude-3-5.
is_publishedbooleanoptionalSet to true to make the chatbot publicly accessible.
rate_limit_messages_per_sessionintegeroptionalMax messages per conversation session. Default: 50.
rate_limit_sessions_per_dayintegeroptionalMax conversation sessions per IP per day. Default: 100.
webhook_urlstringoptionalHTTPS endpoint to receive real-time conversation events.
Example: Publish + update model
json
1{
2 "is_published": true,
3 "ai_model": "gemini-1.5-pro",
4 "system_prompt": "You are a friendly support agent for Acme Corp. Always end responses with \"Is there anything else I can help you with?\""
5}

Analytics API

GET/v1/chatbot/{bot_id}/analytics

Retrieve daily aggregate metrics for the last N days.

Example Request
bash
1curl "https://app.polybrand.io/api/v1/chatbot/cb_k7x2m9p3/analytics?days=30" \
2 -H "Authorization: Bearer pb_live_..."
Response
json
1{
2 "summary": {
3 "total_conversations": 1204,
4 "total_messages": 8932,
5 "avg_csat": 4.7,
6 "resolution_rate": 0.84,
7 "escalation_rate": 0.06,
8 "leads_captured": 312
9 },
10 "daily": [
11 {
12 "date": "2026-03-03",
13 "conversations": 48,
14 "messages": 362,
15 "unique_visitors": 41,
16 "avg_duration_seconds": 187,
17 "escalations": 2,
18 "leads_captured": 14,
19 "avg_csat": 4.8
20 }
21 ]
22}

Webhooks

Set a webhook_url in the configuration to receive real-time HTTP POST events for every chatbot interaction. All payloads are signed with an X-Polybrand-Signature header (HMAC-SHA256).

conversation.startedNew session began
message.receivedUser sent a message
message.sentBot sent a reply
lead.capturedLead form submitted
conversation.escalatedHanded off to human
conversation.endedSession closed + CSAT
knowledge.indexedSource finished indexing
rate_limit.exceededSession/IP limit hit
Example Webhook Payload
json
1{
2 "event": "message.received",
3 "chatbot_id": "cb_k7x2m9p3",
4 "conversation_id": "conv_9a3f...",
5 "session_id": "sess_abc123",
6 "timestamp": "2026-03-03T10:15:32Z",
7 "data": {
8 "message": "What are your business hours?",
9 "reply": "We\'re open Monday to Friday, 9 AM – 6 PM EST.",
10 "sources_used": 2,
11 "tokens_used": 865
12 }
13}
Verify Signature (Node.js)
typescript
1import crypto from "crypto";
2
3function verifyWebhookSignature(
4 payload: string,
5 signature: string,
6 secret: string
7): boolean {
8 const expected = crypto
9 .createHmac("sha256", secret)
10 .update(payload)
11 .digest("hex");
12 return crypto.timingSafeEqual(
13 Buffer.from(signature),
14 Buffer.from(`sha256=${expected}`)
15 );
16}

JavaScript / TypeScript SDK

The official Polybrand JS SDK wraps the REST API with type-safe methods, automatic retries, and streaming support.

Installation
bash
1npm install @polybrand/chatbot-sdk
2# or
3pnpm add @polybrand/chatbot-sdk
client.ts
typescript
1import { PolybrandChatbot } from "@polybrand/chatbot-sdk";
2
3const chatbot = new PolybrandChatbot({
4 apiKey: process.env.POLYBRAND_API_KEY!,
5 botId: "cb_k7x2m9p3",
6});
7
8// ── Send a message ────────────────────────────────────────
9const response = await chatbot.chat({
10 message: "What are your business hours?",
11 sessionId: "sess_abc123",
12});
13console.log(response.reply); // "We're open Mon–Fri..."
14console.log(response.sources); // [{ content, source_name, similarity }]
15
16// ── Stream a response ─────────────────────────────────────
17for await (const chunk of chatbot.chatStream({
18 message: "Describe your product lineup.",
19 sessionId: "sess_abc123",
20})) {
21 process.stdout.write(chunk.delta);
22}
23
24// ── Add knowledge source ──────────────────────────────────
25await chatbot.knowledge.addUrl({
26 url: "https://yoursite.com/faq",
27 maxDepth: 2,
28 maxPages: 50,
29});
30
31// ── Upload document ───────────────────────────────────────
32const doc = await chatbot.knowledge.uploadDocument(
33 fs.createReadStream("./handbook.pdf"),
34 "handbook.pdf"
35);
36console.log(doc.status); // "processing" → "indexed"
37
38// ── Get analytics ─────────────────────────────────────────
39const stats = await chatbot.analytics.get({ days: 30 });
40console.log(stats.summary.total_conversations); // 1204

Error Codes

HTTP CodeError CodeDescription
400invalid_requestMissing or malformed request parameters.
401unauthorizedMissing or invalid API key.
403forbiddenYour plan does not include this feature.
404chatbot_not_foundNo chatbot found for the given bot_id.
422knowledge_limit_reachedMaximum knowledge sources reached for your plan.
429rate_limit_exceededSession or daily message limit hit.
503model_unavailableThe selected LLM is temporarily unavailable; retrying with fallback.

Base URL

All requests
bash
1https://app.polybrand.io/api/v1/chatbot

All endpoints require an Authorization: Bearer pb_live_… header. API keys are generated in Account → API Settings.

PolyBrand Developer Documentation | PolyBrand