Articles Developers

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