REST API Reference¶
Complete HTTP REST API documentation for Sekha Controller.
Base URL¶
All API endpoints are prefixed with /api/v1 unless otherwise specified.
Authentication¶
All requests (except /health and /metrics) require Bearer token authentication:
Setting API Key¶
Configure in config.toml:
Or via environment variable:
Endpoints Overview¶
Sekha Controller provides 19 total endpoints:
Conversation Management (9 endpoints)¶
POST /api/v1/conversations- Create conversationGET /api/v1/conversations/{id}- Get conversation by IDGET /api/v1/conversations- List conversations with filtersPUT /api/v1/conversations/{id}/label- Update label/folderPUT /api/v1/conversations/{id}/folder- Update folderPUT /api/v1/conversations/{id}/pin- Pin conversation (importance=10)PUT /api/v1/conversations/{id}/archive- Archive conversationDELETE /api/v1/conversations/{id}- Delete conversationGET /api/v1/conversations/count- Count conversations
Search & Query (3 endpoints)¶
POST /api/v1/query- Semantic search (vector similarity)POST /api/v1/search/fts- Full-text search (SQLite FTS5)POST /api/v1/rebuild-embeddings- Rebuild vector index
Memory Orchestration (5 endpoints)¶
POST /api/v1/context/assemble- Intelligent context assemblyPOST /api/v1/summarize- Generate hierarchical summariesPOST /api/v1/prune/dry-run- Get pruning suggestionsPOST /api/v1/prune/execute- Execute pruningPOST /api/v1/labels/suggest- AI-powered label suggestions
System (2 endpoints)¶
GET /health- Health checkGET /metrics- Prometheus metrics
Conversation Management¶
Create Conversation¶
Store a new conversation with messages and automatic embedding generation.
Request Body:
{
"label": "API Design Discussion",
"folder": "/work/backend",
"messages": [
{
"role": "user",
"content": "Let's design the authentication API"
},
{
"role": "assistant",
"content": "Great! I recommend OAuth 2.0 with JWT tokens..."
}
]
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Human-readable conversation label |
folder | string | Yes | Folder path (e.g., /work/backend) |
messages | array | Yes | Array of message objects |
messages[].role | string | Yes | "user" or "assistant" |
messages[].content | string | Yes | Message text content |
Response (201 Created):
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"label": "API Design Discussion",
"folder": "/work/backend",
"status": "active",
"message_count": 2,
"created_at": "2026-01-25T20:30:00"
}
Notes:
- Embeddings are generated asynchronously via LLM Bridge
- Word count and importance score (default: 5) are auto-calculated
- Conversation ID is a UUID v4
Get Conversation¶
Retrieve a specific conversation by ID.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | UUID | Conversation UUID |
Response (200 OK):
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"label": "API Design Discussion",
"folder": "/work/backend",
"status": "active",
"message_count": 2,
"created_at": "2026-01-25T20:30:00"
}
Response (404 Not Found):
List Conversations¶
List conversations with optional filtering and pagination.
GET /api/v1/conversations?page=1&page_size=50&folder=/work&label=API+Design
Authorization: Bearer YOUR_API_KEY
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-indexed) |
page_size | integer | 50 | Results per page |
label | string | - | Filter by label |
folder | string | - | Filter by folder |
pinned | boolean | - | Filter by pinned status |
archived | boolean | - | Filter by archived status |
Response (200 OK):
{
"results": [
{
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"message_id": "00000000-0000-0000-0000-000000000000",
"score": 1.0,
"content": "API Design Discussion",
"metadata": {
"folder": "/work/backend",
"status": "active",
"importance_score": 7
},
"label": "API Design Discussion",
"folder": "/work/backend",
"timestamp": "2026-01-25T20:30:00"
}
],
"total": 42,
"page": 1,
"page_size": 50
}
Update Conversation Label¶
Update the label and/or folder for a conversation.
PUT /api/v1/conversations/{id}/label
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
Request Body:
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | New label |
folder | string | Yes | New folder path |
Response (200 OK): Empty body
Response (404 Not Found):
Update Conversation Folder¶
Update only the folder for a conversation.
PUT /api/v1/conversations/{id}/folder
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
Request Body:
Response (200 OK): Empty body
Pin Conversation¶
Pin a conversation by setting its importance score to 10.
No request body required.
Response (200 OK): Empty body
Effect: Sets importance_score = 10, which:
- Prioritizes this conversation in context assembly
- Protects from pruning suggestions
- Boosts in search rankings
Archive Conversation¶
Archive a conversation (sets status to "archived").
No request body required.
Response (200 OK): Empty body
Effect: Changes status from "active" to "archived"
Delete Conversation¶
Permanently delete a conversation and all its messages.
Response (200 OK): Empty body
Response (404 Not Found):
Irreversible Operation
This permanently deletes the conversation and all associated messages and embeddings. Cannot be undone.
Count Conversations¶
Count conversations globally or filtered by label/folder.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
label | string | Count conversations with this label |
folder | string | Count conversations in this folder |
Constraints: Cannot specify both label and folder simultaneously.
Response (200 OK):
Global Count (no parameters):
Search & Query¶
Semantic Search¶
Search conversations using vector similarity (powered by ChromaDB).
Request Body:
{
"query": "What did we discuss about OAuth implementation?",
"limit": 10,
"offset": 0,
"filters": {
"folder": "/work"
}
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | - | Natural language search query |
limit | integer | No | 10 | Max results to return |
offset | integer | No | 0 | Pagination offset |
filters | object | No | null | Optional JSON filters |
Response (200 OK):
{
"results": [
{
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"message_id": "789e4567-e89b-12d3-a456-426614174111",
"score": 0.92,
"content": "We decided to use OAuth 2.0 with JWT tokens for stateless authentication...",
"metadata": {},
"label": "API Design Discussion",
"folder": "/work/backend",
"timestamp": "2026-01-20T15:30:00"
}
],
"total": 3,
"page": 1,
"page_size": 10
}
How It Works:
- Query text is embedded via LLM Bridge (nomic-embed-text)
- ChromaDB performs cosine similarity search
- Results sorted by similarity score (0.0-1.0)
- Message content and metadata fetched from SQLite
Full-Text Search¶
Fast exact phrase matching using SQLite FTS5.
Request Body:
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | - | Exact phrase or keywords |
limit | integer | No | 10 | Max results |
Response (200 OK):
{
"results": [
{
"id": "789e4567-e89b-12d3-a456-426614174111",
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"role": "assistant",
"content": "OAuth 2.0 uses JWT tokens for authentication...",
"timestamp": "2026-01-20T15:30:00",
"embedding_id": "chroma-vector-id",
"metadata": {}
}
],
"total": 5
}
Use Cases:
- ✅ Exact keyword matching
- ✅ Fast searches (< 10ms)
- ✅ Boolean operators (AND, OR, NOT)
- ❌ Not semantic (won't find synonyms)
Rebuild Embeddings¶
Trigger asynchronous rebuild of all vector embeddings.
No request body required.
Response (202 Accepted): Empty body
When to Use:
- After changing embedding model
- After importing large dataset
- To fix corrupted vector index
Process:
- Background job spawned
- Fetches all messages from SQLite
- Generates embeddings via LLM Bridge
- Upserts to ChromaDB
- Logs completion
Memory Orchestration¶
Assemble Context¶
Intelligent 4-phase context assembly for optimal LLM input.
Request Body:
{
"query": "Continue our API authentication discussion",
"preferred_labels": ["API Design", "Security"],
"context_budget": 4000,
"excluded_folders": ["/personal"]
}
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | Yes | - | User's current goal/question |
preferred_labels | array | No | [] | Boost conversations with these labels |
context_budget | integer | No | 4000 | Max tokens to return |
excluded_folders | array | No | [] | Exclude these folders |
Response (200 OK):
[
{
"id": "789e4567-e89b-12d3-a456-426614174111",
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"role": "assistant",
"content": "OAuth 2.0 uses JWT tokens...",
"timestamp": "2026-01-20T15:30:00",
"embedding_id": "chroma-id",
"metadata": {
"label": "API Design Discussion",
"folder": "/work/backend",
"relevance_score": 0.95
}
}
]
4-Phase Algorithm:
- Recall - Semantic search (top 200) + pinned + recent labeled
- Ranking -
score = 50% importance + 30% recency + 20% label_match - Assembly - Greedy packing within token budget
- Enhancement - Add metadata citations
Generate Summary¶
Generate hierarchical summaries (daily/weekly/monthly).
Request Body:
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | UUID | Yes | Conversation to summarize |
level | string | Yes | "daily", "weekly", or "monthly" |
Response (200 OK):
{
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"level": "daily",
"summary": "Today's discussions focused on OAuth 2.0 implementation...",
"generated_at": "2026-01-25T20:30:00"
}
Summary Levels:
- Daily: Last 24 hours (≈200 words)
- Weekly: Aggregates 7 daily summaries (≈500 words)
- Monthly: Aggregates 4 weekly summaries (≈1000 words)
Prune (Dry Run)¶
Get intelligent suggestions for archiving old/low-value conversations.
Request Body:
Parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
threshold_days | integer | No | 30 | Consider conversations older than X days |
Response (200 OK):
{
"suggestions": [
{
"conversation_id": "old-conv-uuid",
"conversation_label": "Random Chat",
"last_accessed": "2025-10-15T10:00:00",
"message_count": 15,
"token_estimate": 2500,
"importance_score": 3.0,
"preview": "First 100 chars of conversation...",
"recommendation": "archive"
}
],
"total": 8
}
Recommendation Types:
"archive"- Low importance, old, inactive"keep"- High importance or recent activity"delete"- (Future) Very low value
Execute Pruning¶
Archive conversations based on IDs.
Request Body:
{
"conversation_ids": [
"123e4567-e89b-12d3-a456-426614174000",
"234e5678-e89b-12d3-a456-426614174001"
]
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
conversation_ids | array | Yes | UUIDs to archive |
Response (200 OK): Empty body
Effect: Sets status = "archived" for all provided IDs.
Suggest Labels¶
AI-powered label suggestions for a conversation.
Request Body:
Response (200 OK):
{
"conversation_id": "123e4567-e89b-12d3-a456-426614174000",
"suggestions": [
{
"label": "API Design",
"confidence": 0.95,
"is_existing": true,
"reason": "Conversation contains detailed API architecture discussion"
},
{
"label": "OAuth Implementation",
"confidence": 0.87,
"is_existing": false,
"reason": "Focus on OAuth 2.0 authentication flow"
}
]
}
How It Works:
- Extracts entities from conversation messages
- Analyzes topics and themes
- Checks existing labels in database
- Returns ranked suggestions with confidence scores
System Endpoints¶
Health Check¶
Check system health and component status.
No authentication required.
Response (200 OK):
{
"status": "healthy",
"timestamp": "2026-01-25T20:30:00Z",
"checks": {
"database": {"status": "ok"},
"chroma": {"status": "ok"}
}
}
Response (503 Service Unavailable):
{
"status": "unhealthy",
"timestamp": "2026-01-25T20:30:00Z",
"checks": {
"database": {"status": "ok"},
"chroma": {
"status": "error",
"error": "Connection refused"
}
}
}
Use Cases:
- Docker health checks
- Load balancer monitoring
- Deployment verification
Prometheus Metrics¶
Expose metrics in Prometheus format.
No authentication required.
Response (200 OK):
# HELP sekha_conversations_total Total number of conversations
# TYPE sekha_conversations_total gauge
sekha_conversations_total 247
# HELP sekha_messages_total Total number of messages
# TYPE sekha_messages_total gauge
sekha_messages_total 1843
# Future metrics planned:
# - Request latency histogram
# - Error rates
# - Vector search performance
Error Responses¶
All errors follow this standard format:
HTTP Status Codes¶
| Code | Meaning | Common Causes |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Conversation created successfully |
202 | Accepted | Async operation started |
400 | Bad Request | Invalid JSON or missing required fields |
401 | Unauthorized | Missing or invalid API key |
404 | Not Found | Conversation ID doesn't exist |
500 | Internal Server Error | Database error, ChromaDB unavailable |
503 | Service Unavailable | System unhealthy (health check failed) |
Common Errors¶
Invalid API Key:
Conversation Not Found:
Database Error:
Rate Limiting¶
Default Limits:
- 100 requests/second per API key
- 200 burst capacity
Rate Limit Headers:
429 Too Many Requests Response:
Configuration:
Adjust in config.toml:
SDKs & Libraries¶
Official SDKs handle authentication, retries, and provide typed interfaces:
- Python SDK -
pip install sekha - JavaScript SDK -
npm install sekha
Example with Python SDK¶
from sekha import SekhaClient
client = SekhaClient(api_key="your-key", base_url="http://localhost:8080")
# Create conversation
conv = client.conversations.create(
label="Python Discussion",
folder="/work/python",
messages=[
{"role": "user", "content": "Explain type hints"},
{"role": "assistant", "content": "Type hints in Python..."}
]
)
# Semantic search
results = client.query("type hints", limit=5)
# Context assembly
context = client.assemble_context("Continue Python discussion", context_budget=4000)
Related Documentation¶
- MCP Tools - Claude Desktop integration (7 tools)
- Architecture - How the API works internally
- Deployment - Running Sekha in production
- Configuration - Complete config reference
Documentation updated: January 2026 | Sekha Controller v1.0