Knowledge Base Management
Upload and manage your brand's FAQ, product catalog, promotions, and policies. All KB entries are automatically embedded and indexed for RAG retrieval.
List Knowledge Base Entries
Retrieve all KB entries for your tenant.
GET /api/tenants/me/kb?type=FAQ&isActive=true&limit=20
Query Parameters
| Param | Type | Default | Notes |
|---|---|---|---|
type | enum | all | FAQ, SKU, Promotion, Policy, Custom |
isActive | boolean | all | Filter by active/inactive status |
limit | number | 20 | Page size (max 100) |
after | string | Cursor for pagination |
Response
{
"data": [
{
"id": "kb_ulid",
"tenantId": "ulid",
"title": "How do I track my order?",
"type": "FAQ",
"content": "Go to Orders → click the order → view tracking number...",
"tags": ["orders", "tracking"],
"isActive": true,
"expiresAt": null,
"createdAt": "2026-03-01T00:00:00Z",
"updatedAt": "2026-03-12T00:00:00Z"
}
],
"pagination": {
"limit": 20,
"hasMore": false
}
}
Create Knowledge Base Entry
Add a new FAQ, product info, promotion, or policy.
POST /api/tenants/me/kb
Request
{
"title": "Polo Shirt YD-001",
"type": "SKU",
"content": "Color: White, Black, Navy. Material: 100% cotton. Size: XS-XXL. Price: 299,000đ",
"tags": ["clothing", "polos"],
"expiresAt": null
}
Field Descriptions
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | ✓ | Entry title (indexed for search) |
type | enum | ✓ | FAQ, SKU, Promotion, Policy, Custom |
content | string | ✓ | Full text content (max 4000 chars) |
tags | string[] | Keywords for semantic search | |
expiresAt | ISO8601 | Promotion expiry date (optional) |
Response
{
"id": "kb_ulid",
"title": "Polo Shirt YD-001",
"type": "SKU",
"content": "Color: White, Black, Navy...",
"tags": ["clothing", "polos"],
"isActive": true,
"expiresAt": null,
"embeddingStatus": "pending",
"createdAt": "2026-03-12T00:00:00Z"
}
Note: embeddingStatus: pending means the entry is being indexed. It will be available for RAG in ~2 seconds.
Update Knowledge Base Entry
Modify an existing KB entry.
PUT /api/tenants/me/kb/:entryId
Request
{
"title": "Polo Shirt YD-001 (Updated)",
"content": "Color: White, Black, Navy, Olive...",
"tags": ["clothing", "polos", "spring-collection"],
"expiresAt": null
}
Response
{
"id": "kb_ulid",
"title": "Polo Shirt YD-001 (Updated)",
"embeddingStatus": "pending",
"updatedAt": "2026-03-12T14:30:00Z"
}
Delete Knowledge Base Entry
Remove a KB entry from your knowledge base.
DELETE /api/tenants/me/kb/:entryId
Response
{
"success": true,
"message": "Entry deleted"
}
Get Entry Details
Retrieve a single KB entry with full content.
GET /api/tenants/me/kb/:entryId
Response
{
"id": "kb_ulid",
"title": "How do I track my order?",
"type": "FAQ",
"content": "Go to Orders → click the order → view tracking number. SMS notification sent to your phone number on file.",
"tags": ["orders", "tracking"],
"isActive": true,
"expiresAt": null,
"embeddingStatus": "completed",
"embedding": null,
"usageCount": 3,
"lastUsedAt": "2026-03-12T14:00:00Z",
"createdAt": "2026-03-01T00:00:00Z",
"updatedAt": "2026-03-12T00:00:00Z"
}
Promotions & Expiry
Promotion entries with expiresAt are automatically deactivated after the expiry date. They will not appear in RAG results.
{
"title": "Spring Sale: 30% Off",
"type": "Promotion",
"content": "30% discount on all polo shirts until March 31, 2026",
"tags": ["sale", "polos"],
"expiresAt": "2026-03-31T23:59:59Z"
}
Background job runs every 5 minutes to deactivate expired promotions.
RAG Retrieval
When a customer message arrives, Dolly searches your knowledge base:
- Embed customer message — All-MiniLM local embedding
- Vector search — pgvector similarity search returns top 3 hits (regardless of confidence score)
- Inject into prompt — All 3 KB entries added as context
- Gate 2 validates — Hallucination gate ensures AI doesn't use KB entries to invent unverified claims
Key Design: Always return top 3 hits (no minimum score cutoff). The hallucination gate is the guard against low-confidence results being misused. This design ensures the AI always has context to work with, even for edge-case queries.
Example:
Customer: "Áo polo có được giặt khô không?"
Vector search returns:
1. "Care instructions: Machine wash cold, hang dry" (high confidence)
2. "Returns policy includes care damage" (medium confidence)
3. "Customer review about fabric" (low confidence)
All 3 injected into prompt.
Haiku reads all 3, but Gate 2 validates that claims are only from the high/medium confidence entries.
Embedding Status
When you create or update a KB entry, Dolly automatically embeds the content:
- pending — Waiting to be indexed
- completed — Ready for RAG retrieval
- failed — Embedding failed (e.g., invalid content)
Monitor embeddingStatus to know when entries are live.
Usage Stats
Each KB entry tracks how often it was retrieved during RAG:
usageCount— Times this entry was in top-3 RAG resultslastUsedAt— Last time it was injected into a response
Use this to identify your most helpful content.
Error Responses
| Error | HTTP | Cause |
|---|---|---|
INVALID_REQUEST | 400 | Missing title, invalid type, content empty |
NOT_FOUND | 404 | Entry does not exist |
CONFLICT | 409 | Duplicate title in same type |
INTERNAL_ERROR | 500 | Embedding failed — retry |