API Reference
Complete documentation for the Pravia API — integrate AI Employees, manage documents, and configure your bots programmatically.
Authentication
Dashboard (Session Cookie)
Dashboard API requires a Better Auth session cookie. No API key, no Authorization header — just log in. Tenant isolation enforced: GET /api/documents?botId=<other> → 404/403.
Widget (Public)
The widget chat endpoint is public and rate-limited (30/min per IP, env RATE_LIMIT_WIDGET_PER_MIN). No authentication — botId is a public identifier, not a key. Server enforces active-bot check, tenant isolation and never returns private owner data.
Session cookie example (no Authorization header)
curl -X POST "/api/chat" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<session>" \
-d '{
"botId": "your-bot-id",
"query": "Hello!"
}'
# Session cookie required — log in via /login first. No Authorization header.Chat Endpoints
| Parameter | Type | Required | Description |
|---|---|---|---|
| botId | string | Yes | The unique identifier of your bot (public ID, not a key — botId ≠ API key). |
| query | string | Yes | The user's message text (max 2000 characters). |
| conversationId | string | No | Optional conversation ID for maintaining context across multiple requests. |
| model | string | No | Dashboard only. Override model — allowed only if your plan permits; otherwise ignored and bot.model is used. |
Request Example — Dashboard
{
"botId": "bot_abc123",
"query": "What is your return policy?",
"conversationId": "conv_xyz789"
}Response Example — Dashboard (sources include content)
// Dashboard: POST /api/chat (Session) — includes chunk content
{
"conversationId": "conv_xyz789",
"answer": "Our return policy allows returns within 30 days of purchase.",
"sources": [
{ "chunkId": "...", "documentId": "...", "content": "...", "score": 0.92 }
],
"offline": false
}Public endpoint for the embedded widget. Accepts botId, query, conversationId and visitorId — model is not accepted (always bot.model). Rate-limited to 30 requests/min per IP (env RATE_LIMIT_WIDGET_PER_MIN, default 30). botId is a public identifier, not an API key. Tenant isolation enforced server-side: private owner data is never returned.
Request Example — Widget (public)
{
"botId": "bot_abc123",
"query": "What is your return policy?",
"conversationId": "conv_xyz789",
"visitorId": "visitor_123"
}Response Example — Widget (sources without content)
// Widget: POST /api/widget/chat (Public, SSE) — sources without content
{
"conversationId": "conv_xyz789",
"answer": "Our return policy allows returns within 30 days of purchase.",
"sources": [
{ "chunkId": "...", "documentId": "...", "score": 0.92 }
]
}
// Public widget never returns chunk content — only IDs + score.
// SSE: { chunk, done } + final done { conversationId, messageId, sources }Bot Management
Retrieve a list of all your bots.
curl -X GET "/api/bots" \
-H "Content-Type: application/json"Create a new bot with the specified configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Bot name (1-64 characters). |
| description | string | No | Optional description of your bot's purpose. |
| model | string | No | Default model for this bot. |
{
"name": "Support Bot",
"description": "Answers customer questions based on our knowledge base",
"model": "pravia"
}Document Management
Retrieve all documents for a specific bot.
| Parameter | Type | Required | Description |
|---|---|---|---|
| botId | string | Yes | Filter documents by bot. |
Add knowledge sources to a bot. Supports: file upload (PDF, Markdown, DOCX, TXT), URL extraction (Website), Sitemap XML import, or raw text. Use multipart/form-data for files, or JSON for URL/text/sitemap.
Rate Limits
| Endpoint | Rate Limit |
|---|---|
| Widget Chat (/api/widget/chat) | 30 req/min per IP (env RATE_LIMIT_WIDGET_PER_MIN) |
| Dashboard API (/api/chat, /api/bots, /api/documents) | 30 req/min per user |
Error Responses
| Code | HTTP Status | Description |
|---|---|---|
| 400 | 400 | Bad request. Returns a string error message like 'botId is required', 'query is required', or 'Query too long'. |
| 401 | 401 | Unauthorized. Session cookie missing or invalid. |
| 403 | 403 | Forbidden. Billing limit reached or access denied. |
| 404 | 404 | Not found. Bot not found or inactive. |
| 503 | 503 | Service temporarily unavailable. Billing limit exceeded. |
| 500 | 500 | Internal server error. |
Endpoint Summary
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/chat | Session cookie | Dashboard chat (tenant-isolated). Model override only if allowed by plan; sources include chunk content. |
| POST | /api/widget/chat | Public (botId ≠ API key) | Widget chat — public, rate-limited (30/min/IP), tenant-isolated; sources without content (IDs + score only), no model override. |
| GET | /api/bots | Session | List all bots in your account. |
| POST | /api/bots | Session | Create a new bot. |
| GET | /api/bots/:id | Session | Retrieve a single bot by ID. |
| GET | /api/documents | Session | List documents for a bot. |
| POST | /api/documents | Session | Upload a document to a bot. |