API Reference
Complete REST API documentation for Knowably. Build integrations, automate workflows, and create custom interfaces using the same endpoints that power the application.
Every feature in Knowably is backed by a REST API. The same endpoints that power the web application are available for building integrations, automations, and custom interfaces. I use them myself when testing new pipeline configurations.
For guided walkthroughs, see the Agent Configuration Guide or the Embed Widget Setup Guide.
Base URL and Conventions
All tenant-scoped endpoints follow this pattern:
api/{workspace}/...
Replace {workspace} with your workspace slug.
Request format. All request bodies are JSON. Set Content-Type: application/json on every request.
Response format. Single resources are wrapped in a data object. List endpoints return paginated collections with data, links, and meta keys - the standard Laravel pagination envelope.
Resource identifiers. Every resource is identified by UUID. Internal database IDs never reach the API. I made this choice early and it saved debugging time later. In API responses, the UUID is returned as id.
Pagination. List endpoints accept page and per_page query parameters. Some endpoints support paginate=false to return all results without pagination.
Successful deletes return 204 No Content with an empty body.
Plan limits are enforced at the middleware level, not in controllers. When a limit is reached, the API returns 403 Forbidden with a message indicating which limit was exceeded.
Authentication
Knowably uses two authentication mechanisms depending on the context.
Sanctum Token Authentication
All api/{workspace}/... endpoints require a Bearer token in the Authorization header:
Authorization: Bearer {your-token}
Tokens are issued during login and can be refreshed, revoked, or listed through the auth endpoints below.
Embed Session Authentication
The embed widget uses a separate session-based mechanism. After creating a session via the embed session endpoint, pass the token in the X-Embed-Token header:
X-Embed-Token: {session-token}
Sessions are validated against the originating domain on every request.
Auth Endpoints
| Method | Path | Description |
|---|---|---|
GET |
api/auth/user |
Get the authenticated user |
POST |
api/auth/logout |
Log out and invalidate the current session |
POST |
api/auth/token/refresh |
Refresh the access token |
POST |
api/auth/token/revoke |
Revoke the current token |
POST |
api/auth/token/revoke-all |
Revoke all tokens for the current user |
GET |
api/auth/tokens |
List all active tokens and devices |
DELETE |
api/auth/tokens/{token} |
Revoke a specific device token |
All auth endpoints require an active Sanctum session except where the token itself is being created.
Chats
The streaming endpoint is the core of the chat experience. Everything else here supports it - creating conversations, listing history, cleaning up.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/chats |
List chats for the authenticated user (paginated) |
GET |
api/{workspace}/chats/agents |
List agents available for new chats |
GET |
api/{workspace}/agents/{agent}/chats |
Get a single agent with chat context |
POST |
api/{workspace}/chats |
Create a new chat |
GET |
api/{workspace}/chats/{chat} |
Get a chat with its messages |
PUT/PATCH |
api/{workspace}/chats/{chat} |
Update a chat (title, etc.) |
DELETE |
api/{workspace}/chats/{chat} |
Delete a chat |
POST |
api/{workspace}/chats/{chat}/stream |
Stream a chat response |
GET |
api/{workspace}/available-models |
List enabled LLM models for chat |
Create Chat
POST api/{workspace}/chats
{
"agent_id": "uuid",
"message": "What is our remote work policy?"
}
Subject to plan limits on chat count. On success, a background job generates a title for the conversation automatically.
Returns 201 with a ChatResource.
Stream Chat Response
POST api/{workspace}/chats/{chat}/stream
{
"message": "Can you elaborate on the flexible hours section?",
"large_language_model_id": "uuid"
}
Returns Content-Type: text/event-stream. The response body contains newline-delimited JSON chunks:
{"chunkType": "text", "content": "Based on the policy document..."}
{"chunkType": "thinking", "content": "The user is asking about..."}
{"chunkType": "error", "content": "Stream failed"}
Each stream request creates a user message, runs the full RAG pipeline, and streams the LLM response. On completion, an assistant message is persisted with source citations extracted from the response. A Langfuse trace is created for observability.
Subject to plan limits on message count.
Messages
Messages belong to chats. The primary creation path is through the stream endpoint - these endpoints handle updates and deletion.
| Method | Path | Description |
|---|---|---|
PUT/PATCH |
api/{workspace}/messages/{message} |
Update a message |
DELETE |
api/{workspace}/messages/{message} |
Delete a message |
Update Message
PUT api/{workspace}/messages/{message}
{
"is_upvoted": true
}
When is_upvoted is set, a feedback score is sent to Langfuse for answer quality tracking. Returns a MessageResource.
Agents
Agents are the core configuration unit. Each one defines a purpose-built AI assistant with its own knowledge scope, search strategy, and behavior. This is where most of the interesting tuning happens. See the Agent Configuration Guide for detailed field documentation.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/agents/defaults |
Get default configuration values for new agents |
GET |
api/{workspace}/agents/mcp-servers |
List configured MCP server names |
GET |
api/{workspace}/agents |
List agents (paginated) |
POST |
api/{workspace}/agents |
Create an agent |
GET |
api/{workspace}/agents/{agent} |
Get an agent |
PUT/PATCH |
api/{workspace}/agents/{agent} |
Update an agent |
DELETE |
api/{workspace}/agents/{agent} |
Delete an agent |
POST |
api/{workspace}/agents/{agent}/generate-suggested-queries |
Queue suggested query generation |
POST |
api/{workspace}/agents/{agent}/rotate-embed-token |
Rotate the embed token |
Create Agent
POST api/{workspace}/agents
{
"name": "HR Assistant",
"system_prompt": "You are an HR assistant...",
"knowledgebases": ["uuid-1", "uuid-2"],
"temperature": 0.7,
"max_new_tokens": 1024,
"embed_enabled": false,
"embed_allowed_origins": [],
"is_quick_create": false
}
When is_quick_create is true, a background job auto-configures the agent based on its assigned knowledge bases. Subject to plan limits on agent count.
Returns 201 with an AgentResource.
Generate Suggested Queries
POST api/{workspace}/agents/{agent}/generate-suggested-queries
{
"number_of_queries": 10,
"sample_size": 50
}
Queues an asynchronous job that samples documents from the agent's knowledge bases and generates suggested queries using an LLM. Both fields are optional and default to the values shown above.
Rotate Embed Token
POST api/{workspace}/agents/{agent}/rotate-embed-token
Generates a new random embed token, invalidating the previous one. Any active embed sessions using the old token stop working immediately. Returns the updated AgentResource.
Data Sources
Data sources represent connections to external systems - SharePoint, Confluence, Jira, Email, GitHub, Google Drive, S3, websites, and file uploads. See Data Source Integrations for supported types.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/data-source-types |
List available integration types |
GET |
api/{workspace}/data-sources |
List data sources (paginated, or paginate=false) |
POST |
api/{workspace}/data-sources |
Create a data source |
GET |
api/{workspace}/data-sources/{dataSource} |
Get a data source |
PUT/PATCH |
api/{workspace}/data-sources/{dataSource} |
Update a data source |
DELETE |
api/{workspace}/data-sources/{dataSource} |
Delete a data source |
POST |
api/{workspace}/data-sources/{dataSource}/sync |
Re-sync all documents from source |
POST |
api/{workspace}/data-sources/batch/sync |
Batch sync multiple data sources |
GET |
api/{workspace}/data-sources/{dataSource}/documents |
List documents in a data source (paginated) |
POST |
api/{workspace}/data-sources/{dataSource}/documents |
Upload a document (multipart form) |
Create Data Source
Subject to plan limits on data source count. On creation, a background job collects documents from the external system and begins document processing.
Returns 201 with a DataSourceResource.
Batch Sync
POST api/{workspace}/data-sources/batch/sync
{
"ids": ["uuid-1", "uuid-2", "uuid-3"]
}
Triggers document collection for multiple data sources in a single request. Returns a DataSourceIndexResource collection.
Upload Document
POST api/{workspace}/data-sources/{dataSource}/documents
Content-Type: multipart/form-data
file: (binary)
Only available for data sources that support manual upload. Subject to plan limits on document count. The uploaded file is extracted, split into chunks, and indexed asynchronously.
Returns 201 with a DocumentResource.
Integration-Specific Endpoints
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/data-sources/{dataSource}/confluence/spaces |
List available Confluence spaces |
GET |
api/{workspace}/data-sources/{dataSource}/email/folders |
List mailbox folders |
These endpoints query the connected external system directly and return integration-specific data structures.
Documents
Documents are the individual files and pages within data sources. They go through extraction, chunking, and embedding as part of the document processing pipeline.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/documents |
List documents (paginated, supports per_page) |
GET |
api/{workspace}/documents/{document} |
Get a document |
PUT/PATCH |
api/{workspace}/documents/{document} |
Update a document |
DELETE |
api/{workspace}/documents/{document} |
Delete a document |
POST |
api/{workspace}/documents/{document}/sync |
Re-sync a single document |
POST |
api/{workspace}/documents/batch/sync |
Batch sync multiple documents |
GET |
api/{workspace}/documents/{document}/download |
Download the original file |
GET |
api/{workspace}/documents/{document}/preview |
Preview the document inline |
Update Document
PUT api/{workspace}/documents/{document}
{
"data_source_id": "uuid"
}
Returns a DocumentResource.
Batch Sync Documents
POST api/{workspace}/documents/batch/sync
{
"ids": ["uuid-1", "uuid-2"]
}
Re-downloads and reprocesses multiple documents. Returns a DocumentResource collection.
Download and Preview
download returns the original file as a binary response with the original content type. Only available for locally stored documents.
preview returns an inline-displayable version for supported types (PDF, images, text). Falls back to download for non-previewable types.
Knowledge Bases
Knowledge bases group data sources into logical collections. An agent searches across the knowledge bases assigned to it. This grouping is what makes it possible to build focused agents that only know about relevant content. See Knowledge Bases for the conceptual overview.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/knowledgebases |
List knowledge bases (paginated) |
POST |
api/{workspace}/knowledgebases |
Create a knowledge base |
GET |
api/{workspace}/knowledgebases/{knowledgebase} |
Get a knowledge base |
PUT/PATCH |
api/{workspace}/knowledgebases/{knowledgebase} |
Update a knowledge base |
DELETE |
api/{workspace}/knowledgebases/{knowledgebase} |
Delete a knowledge base |
Create / Update Knowledge Base
POST api/{workspace}/knowledgebases
{
"name": "Engineering Docs",
"description": "All engineering documentation",
"data_sources": ["uuid-1", "uuid-2"]
}
The data_sources array is synced on every update - pass the complete list of data source UUIDs you want associated. Subject to plan limits on knowledge base count.
Returns 201 (create) or 200 (update) with a KnowledgebaseResource.
LLM Management
Knowably is model-agnostic. You bring your own provider keys, and the platform handles the rest. These endpoints manage provider connections, individual models, and usage tracking.
Providers
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/large-language-models/providers |
List supported provider configurations |
Returns a JSON array of provider definitions including name, required configuration fields, and capabilities.
Connections
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/large-language-models/connections |
List connections (paginated, includes models) |
POST |
api/{workspace}/large-language-models/connections |
Create a connection |
GET |
api/{workspace}/large-language-models/connections/{connection} |
Get a connection (auto-syncs models) |
PUT/PATCH |
api/{workspace}/large-language-models/connections/{connection} |
Update a connection |
DELETE |
api/{workspace}/large-language-models/connections/{connection} |
Delete a connection |
POST |
api/{workspace}/large-language-models/connections/{connection}/validate |
Test connectivity |
POST |
api/{workspace}/large-language-models/connections/{connection}/sync-models |
Re-fetch available models from provider |
Create Connection
POST api/{workspace}/large-language-models/connections
{
"name": "OpenAI Production",
"provider": "openai",
"api_key": "sk-...",
"base_url": "https://api.openai.com/v1"
}
Models available through the connection are automatically discovered on creation. Subject to plan limits.
Returns 201 with a LargeLanguageModelConnectionResource.
Validate Connection
POST api/{workspace}/large-language-models/connections/{connection}/validate
Tests the API key and connectivity against the provider. Returns:
{
"valid": true,
"message": "Connection successful"
}
Sync Models
POST api/{workspace}/large-language-models/connections/{connection}/sync-models
Clears the cached model list and re-fetches from the provider. Returns the updated LargeLanguageModelConnectionResource.
Models
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/large-language-models |
List all available models |
POST |
api/{workspace}/large-language-models |
Create a model |
GET |
api/{workspace}/large-language-models/{model} |
Get a model with its connection |
PUT/PATCH |
api/{workspace}/large-language-models/{model} |
Update a model |
Update Model
PUT api/{workspace}/large-language-models/{model}
{
"is_enabled": true,
"is_default": true,
"display_name": "GPT-4o"
}
Disabling a model that is currently the default automatically removes its default status. Returns a LargeLanguageModelResource.
Usage
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/large-language-models/usage |
List usage records (paginated, filterable) |
GET |
api/{workspace}/large-language-models/usage/summary |
Get aggregated usage summary for today |
List Usage Records
Supports query filters: from, to, user_id, large_language_model_id. All filters are optional.
GET api/{workspace}/large-language-models/usage?from=2026-01-01&to=2026-01-31&large_language_model_id=uuid
Returns a paginated LargeLanguageModelUsageResource collection.
Get Usage Summary
GET api/{workspace}/large-language-models/usage/summary
Returns aggregated statistics for the current day:
{
"total_requests": 142,
"total_tokens": 89400,
"total_cost": 1.47,
"avg_response_time": 2.3,
"error_count": 0
}
Scoped to the current user unless the user has permission to view all usage data.
Embed Widget
The embed widget lets you deploy a Knowably-powered chat on any website. These endpoints use session-based authentication instead of Sanctum. See the Embed Widget Setup Guide for integration instructions.
All endpoints are prefixed with api/{workspace}/embed/.
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
api/{workspace}/embed/agents/{embedToken} |
None | Get agent info (public) |
POST |
api/{workspace}/embed/agents/{embedToken}/sessions |
None | Create a session |
POST |
api/{workspace}/embed/chats |
Session | Create a chat |
GET |
api/{workspace}/embed/chats/{chat} |
Session | Get a chat with messages |
POST |
api/{workspace}/embed/chats/{chat}/stream |
Session | Stream a chat response |
Get Agent Info
GET api/{workspace}/embed/agents/{embedToken}
Public endpoint. No authentication required. Returns the agent name, suggested queries, and branding configuration via an EmbedAgentResource.
Create Session
POST api/{workspace}/embed/agents/{embedToken}/sessions
{
"origin": "https://your-website.com"
}
Validates the origin against the agent's allowed origins list. If the origin is not permitted - or no allowed origins are configured - the request is rejected with 403 Forbidden.
Rate limited to 10 requests per minute per IP address.
Returns 201:
{
"data": {
"session_id": "uuid",
"token": "plain-text-session-token"
}
}
Store the token and pass it as the X-Embed-Token header on all subsequent embed requests.
Stream Chat Response (Embed)
POST api/{workspace}/embed/chats/{chat}/stream
{
"message": "How do I reset my password?"
}
Works the same as the authenticated stream endpoint, but uses the workspace's default LLM model instead of a user-selected one. The session token must be valid and the chat must belong to the session.
Rate limited to 20 requests per minute per session. Subject to plan limits on message count.
Returns Content-Type: text/event-stream with the same newline-delimited JSON chunk format.
Dashboard and Analytics
Dashboard endpoints provide workspace-level metrics. All endpoints require the statistics.viewAny permission.
| Method | Path | Description |
|---|---|---|
GET |
api/{workspace}/dashboard |
Get combined overview, trends, and performance data |
GET |
api/{workspace}/dashboard/overview |
Summary counts and key metrics |
GET |
api/{workspace}/dashboard/trends |
Time-series data for charts |
GET |
api/{workspace}/dashboard/performance |
Response time, token usage, and quality metrics |
GET |
api/{workspace}/statistics/storage |
Hourly storage usage data points |
The combined dashboard endpoint returns all three sections (overview, trends, performance) in a single response - useful for initial page loads. The individual endpoints allow partial refreshes.
The storage endpoint returns an array of {date, bytes} data points at hourly granularity.
See Dashboard and Analytics for what each metric means.
Error Responses
The API uses standard HTTP status codes. Error responses follow a consistent format.
| Status | Meaning |
|---|---|
400 |
Bad request - malformed input |
401 |
Unauthorized - missing or invalid authentication token |
403 |
Forbidden - insufficient permissions, plan limit exceeded, or origin not allowed |
404 |
Not found - resource does not exist or does not belong to the current workspace |
422 |
Validation error - request body failed validation |
429 |
Rate limit exceeded (embed endpoints) |
500 |
Unexpected server error |
Validation Errors (422)
Validation errors return the standard Laravel format:
{
"message": "The name field is required.",
"errors": {
"name": ["The name field is required."],
"knowledgebases.0": ["The selected knowledgebases.0 is invalid."]
}
}
Plan Limit Errors (403)
When a create operation exceeds your plan's limits:
{
"message": "You have reached the maximum number of agents for your plan."
}
Rate Limiting
Rate limits vary by endpoint type.
Embed session creation. 10 requests per minute per IP address.
Embed streaming. 20 requests per minute per session.
Main API. Standard Laravel throttle defaults apply.
When a rate limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait.
Plan Limits
Plan limits are enforced on create endpoints for the following resource types:
- Chats
- Messages
- Agents
- Data sources
- Documents
- Knowledge bases
- LLM connections
- LLM models
Each workspace's plan defines the maximum count for each resource. When a limit is reached, the create endpoint returns 403 Forbidden.
Further Reading
- Embed Widget Setup Guide - step-by-step integration for the embeddable chat widget
- Agent Configuration Guide - detailed field reference for agent settings
- How Our RAG Pipeline Works - what happens between a user's question and the streamed response
- Security - authentication, data isolation, and guardrails in detail