REST API#
thinkt provides a REST API for programmatic access to AI coding session data. The API is available through the HTTP server and includes interactive Swagger documentation.
Quick Start#
# Start the server (foreground, port 8784)
thinkt server
# Start in background
thinkt server start
# Open web interface (auto-starts server if needed)
thinkt web
# Custom port
thinkt server -p 8080Once running, access the API at http://localhost:8784/api/v1/ (or your configured port).
Server Management#
Starting the Server#
thinkt server # Foreground (default port 8784)
thinkt server -p 8080 # Custom port
thinkt server --no-open # Don't auto-open browser
thinkt server --quiet # Suppress request logging
thinkt server --http-log access.log # Log requests to file
thinkt server --dev http://localhost:8784 # Proxy to frontend dev serverFeatures:
- Full REST API
- Full web interface (thinkt-web) for visual trace exploration
- SPA routing — all non-API paths serve the webapp
- Auto-opens browser on startup
--devmode for co-developing the frontend (proxies non-API routes to a local dev server)
Background Mode#
thinkt server start # Start server in background
thinkt server status # Check server status
thinkt server stop # Stop background serverOpening the Web Interface#
The thinkt web command opens the web interface in your browser. If the server isn’t already running, it starts it in the background automatically.
thinkt web # Open web interface (auto-starts server)
thinkt web lite # Open lightweight debug interfaceThe lite interface (thinkt-web-lite) shows:
- Available sources and status
- Project list with session counts
- Quick links to API endpoints
- Theme preview
OpenAPI Specification#
The API is documented using OpenAPI (Swagger) 2.0. Access the interactive documentation at:
http://localhost:8784/swagger/Download the specification:
- JSON:
http://localhost:8784/swagger/doc.json - YAML: Available in the source at
internal/server/docs/swagger.yaml
API Endpoints#
Base URL: /api/v1
Server Info#
Get Server Info#
Get server identity, version, and runtime metadata.
GET /api/v1/infoResponse:
{
"fingerprint": "22414c5f-cfa8-5d30-8eb4-f1a9c49d355c",
"version": "0.6.0",
"revision": "9834a3d",
"started_at": "2026-02-27T10:30:00Z",
"uptime_seconds": 3600,
"pid": 12345,
"authenticated": true
}Example:
curl http://localhost:8784/api/v1/infoSources#
List Sources#
List available trace sources and their status.
GET /api/v1/sourcesResponse:
{
"sources": [
{
"name": "claude",
"available": true,
"base_path": "/Users/you/.claude/projects"
},
{
"name": "kimi",
"available": true,
"base_path": "/Users/you/.kimi/workspace"
},
{
"name": "gemini",
"available": false,
"base_path": ""
},
{
"name": "copilot",
"available": false,
"base_path": ""
},
{
"name": "codex",
"available": false,
"base_path": ""
},
{
"name": "qwen",
"available": false,
"base_path": ""
}
]
}Example:
curl http://localhost:8784/api/v1/sourcesProjects#
List Projects#
List all projects, optionally filtered by source.
By default, projects where path_exists=false are hidden; set include_deleted=true to include them.
GET /api/v1/projects
GET /api/v1/projects?source=claude
GET /api/v1/projects?include_deleted=trueQuery Parameters:
| Name | Type | Description |
|---|---|---|
source | string | Filter by source (claude, kimi, gemini, copilot, codex, qwen) |
include_deleted | bool | Include projects where path_exists is false (default: false) |
Response:
{
"projects": [
{
"id": "abc123",
"name": "my-project",
"path": "/Users/you/code/my-project",
"display_path": "~/code/my-project",
"session_count": 15,
"source": "claude",
"last_modified": "2024-01-15T10:30:00Z",
"workspace_id": "my-machine"
}
]
}Examples:
# All projects
curl http://localhost:8784/api/v1/projects
# Only Claude projects
curl "http://localhost:8784/api/v1/projects?source=claude"
# Only Kimi projects
curl "http://localhost:8784/api/v1/projects?source=kimi"
# Include projects whose paths no longer exist
curl "http://localhost:8784/api/v1/projects?include_deleted=true"Sessions#
List Sessions for Project#
List all sessions belonging to a project.
GET /api/v1/projects/{projectID}/sessionsPath Parameters:
| Name | Type | Description |
|---|---|---|
projectID | string | URL-encoded project path |
Response:
{
"sessions": [
{
"id": "session-uuid",
"full_path": "/Users/you/.claude/projects/abc123/session.jsonl",
"project_path": "/Users/you/code/my-project",
"created_at": "2024-01-15T10:30:00Z",
"modified_at": "2024-01-15T11:45:00Z",
"entry_count": 42,
"file_size": 125000,
"source": "claude",
"model": "claude-3-opus",
"first_prompt": "Help me refactor the auth module...",
"git_branch": "main"
}
]
}Example:
# URL-encode the project path
curl "http://localhost:8784/api/v1/projects/%2FUsers%2Fyou%2Fcode%2Fmy-project/sessions"Get Session Content#
Get session metadata and conversation entries with optional pagination.
GET /api/v1/sessions/{path}
GET /api/v1/sessions/{path}?limit=10&offset=0Get Session Metadata#
Get session metadata and lightweight previews without loading full entry payloads.
GET /api/v1/sessions/{path}/metadata
GET /api/v1/sessions/{path}/metadata?summary_only=true&limit=5Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
limit | int | 50 | Maximum summaries/previews to return (default 5 when summary_only=true) |
offset | int | 0 | Number of summaries/previews to skip |
exclude_roles | string[] | checkpoint | Roles to exclude (repeat query param or comma-separated list) |
summary_only | bool | false | Return lightweight user-message previews only |
sort_by | string | index | Summary ordering (index or length) |
Path Parameters:
| Name | Type | Description |
|---|---|---|
path | string | URL-encoded session file path |
Query Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
limit | int | 0 (all) | Maximum entries to return |
offset | int | 0 | Number of entries to skip |
Response:
{
"meta": {
"id": "session-uuid",
"full_path": "/path/to/session.jsonl",
"created_at": "2024-01-15T10:30:00Z",
"modified_at": "2024-01-15T11:45:00Z",
"entry_count": 42,
"model": "claude-3-opus",
"source": "claude"
},
"entries": [
{
"uuid": "entry-uuid",
"role": "user",
"timestamp": "2024-01-15T10:30:00Z",
"text": "Help me refactor the authentication module",
"content_blocks": [],
"model": "",
"source": "claude"
},
{
"uuid": "entry-uuid-2",
"role": "assistant",
"timestamp": "2024-01-15T10:30:15Z",
"text": "I'll help you refactor the authentication module...",
"content_blocks": [
{
"type": "thinking",
"thinking": "Let me analyze the current implementation..."
},
{
"type": "tool_use",
"tool_use_id": "tool-123",
"tool_name": "Read",
"tool_input": {"file_path": "/src/auth.ts"}
}
],
"model": "claude-3-opus",
"usage": {
"input_tokens": 1500,
"output_tokens": 800
}
}
],
"has_more": true,
"total": 42
}Examples:
# Get all entries
curl "http://localhost:8784/api/v1/sessions/%2Fpath%2Fto%2Fsession.jsonl"
# Paginate: first 10 entries
curl "http://localhost:8784/api/v1/sessions/%2Fpath%2Fto%2Fsession.jsonl?limit=10"
# Paginate: next 10 entries
curl "http://localhost:8784/api/v1/sessions/%2Fpath%2Fto%2Fsession.jsonl?limit=10&offset=10"Search#
Search Sessions#
Search for text across indexed sessions. Requires thinkt-indexer to be available.
GET /api/v1/search?q=queryQuery Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
q | string | (required) | Search query text |
project | string | Filter by project name (substring match) | |
source | string | Filter by source (claude, kimi, gemini, copilot, codex, qwen) | |
limit | int | 50 | Maximum total matches |
limit_per_session | int | 2 | Maximum matches per session (0 for no limit) |
case_sensitive | bool | false | Enable case-sensitive matching |
regex | bool | false | Treat query as a regular expression (Go RE2 syntax) |
Response:
{
"sessions": [
{
"session_id": "abc-123",
"project_name": "my-project",
"source": "claude",
"path": "/Users/you/.claude/projects/abc123/session.jsonl",
"matches": [
{
"line_num": 42,
"preview": "...Help me refactor the authentication module...",
"role": "user"
}
]
}
],
"total_matches": 5
}Examples:
# Basic search (case-insensitive)
curl "http://localhost:8784/api/v1/search?q=authentication"
# Case-sensitive search
curl "http://localhost:8784/api/v1/search?q=AuthManager&case_sensitive=true"
# Regex search
curl "http://localhost:8784/api/v1/search?q=func\s%2BTest\w%2B®ex=true"
# Filter by project
curl "http://localhost:8784/api/v1/search?q=error&project=my-app"Semantic Search#
Search sessions by meaning using on-device embeddings. Requires embeddings to be enabled.
GET /api/v1/semantic-search?q=queryQuery Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
q | string | (required) | Natural language search query |
project | string | Filter by project name (substring match) | |
source | string | Filter by source | |
limit | int | 20 | Maximum results |
max_distance | float | Cosine distance threshold (0-2, lower is more similar) | |
diversity | bool | false | Spread results across different sessions |
Example:
curl "http://localhost:8784/api/v1/semantic-search?q=database+migration"Get Usage Statistics#
Get aggregate usage statistics from the index.
GET /api/v1/statsResponse:
{
"total_projects": 12,
"total_sessions": 156,
"total_entries": 4200,
"total_tokens": 1250000,
"top_tools": [
{"name": "Read", "count": 450},
{"name": "Edit", "count": 280},
{"name": "Bash", "count": 190}
]
}Indexer Health#
Check whether the indexer is available and the database is accessible.
GET /api/v1/indexer/healthResponse:
{
"available": true,
"path": "/usr/local/bin/thinkt-indexer",
"database_accessible": true,
"indexed_projects": 12,
"indexed_sessions": 156
}Indexer Status#
Get live indexer server status including sync and embedding progress.
GET /api/v1/indexer/statusResponse:
{
"running": true,
"state": "idle",
"uptime_seconds": 3600,
"watching": true,
"model": "nomic-embed-text-v1.5",
"model_dim": 768
}Teams#
List Teams#
List all discovered agent teams (Claude Code).
GET /api/v1/teamsResponse:
{
"teams": [
{
"name": "my-project",
"members": [...],
"created_at": "2024-01-15T10:30:00Z"
}
]
}Example:
curl http://localhost:8784/api/v1/teamsGet Team Details#
Get a specific team with resolved member-to-session mappings.
GET /api/v1/teams/{teamName}Path Parameters:
| Name | Type | Description |
|---|---|---|
teamName | string | Team name |
Example:
curl http://localhost:8784/api/v1/teams/my-projectList Team Tasks#
Get the shared task board for a team.
GET /api/v1/teams/{teamName}/tasksResponse:
{
"tasks": [
{
"id": "1",
"subject": "Implement feature X",
"status": "completed",
"owner": "researcher"
}
]
}Example:
curl http://localhost:8784/api/v1/teams/my-project/tasksList Team Member Messages#
Get inbox messages for a specific team member.
GET /api/v1/teams/{teamName}/members/{memberName}/messagesPath Parameters:
| Name | Type | Description |
|---|---|---|
teamName | string | Team name |
memberName | string | Member name |
Example:
curl http://localhost:8784/api/v1/teams/my-project/members/researcher/messagesThemes#
List Themes#
Get all available themes with their color definitions.
GET /api/v1/themesResponse:
{
"themes": [
{
"name": "dark",
"description": "Default dark theme",
"embedded": true,
"active": true,
"colors": {
"accent": "#7c3aed",
"border_active": "#7c3aed",
"border_inactive": "#404040",
"user_block": {"fg": "#ffffff", "bg": "#1e1e1e"},
"user_label": {"fg": "#60a5fa", "bold": true},
"assistant_block": {"fg": "#ffffff", "bg": "#1e1e1e"},
"assistant_label": {"fg": "#34d399", "bold": true},
"thinking_block": {"fg": "#9ca3af", "bg": "#1e1e1e", "italic": true},
"thinking_label": {"fg": "#f472b6", "bold": true},
"tool_call_block": {"fg": "#fbbf24", "bg": "#1e1e1e"},
"tool_label": {"fg": "#fbbf24", "bold": true},
"tool_result_block": {"fg": "#9ca3af", "bg": "#1e1e1e"},
"text_primary": {"fg": "#ffffff"},
"text_secondary": {"fg": "#9ca3af"},
"text_muted": {"fg": "#6b7280"}
}
}
],
"active": "dark"
}Open-In#
Open paths in external applications (Finder, VS Code, etc.).
List Allowed Apps#
Get the list of enabled applications for the open-in feature.
GET /api/v1/open-in/appsResponse:
{
"apps": [
{"id": "finder", "name": "Finder", "enabled": true, "terminal": false},
{"id": "terminal", "name": "Terminal", "enabled": true, "terminal": true},
{"id": "vscode", "name": "VS Code", "enabled": true, "terminal": false}
],
"default_terminal": "terminal"
}Open Path#
Open a path in a specified application.
POST /api/v1/open-inRequest Body:
{
"app": "vscode",
"path": "/Users/you/code/my-project"
}Response:
{
"success": true,
"message": "Opened in VS Code"
}Example:
curl -X POST http://localhost:8784/api/v1/open-in \
-H "Content-Type: application/json" \
-d '{"app": "vscode", "path": "/Users/you/code/my-project"}'**Security:** Only applications explicitly enabled in the configuration can be used. Requests for disabled apps return `403 Forbidden`.
Data Types#
Entry Roles#
| Role | Description |
|---|---|
user | User messages |
assistant | AI assistant responses |
tool | Tool execution messages |
system | System messages |
summary | Conversation summaries |
progress | Progress indicators |
checkpoint | State recovery markers |
Content Block Types#
| Type | Description |
|---|---|
text | Plain text content |
thinking | AI thinking/reasoning blocks |
tool_use | Tool invocation with name and input |
tool_result | Tool execution result |
Sources#
| Source | Description |
|---|---|
claude | Claude Code |
kimi | Kimi Code |
gemini | Gemini CLI |
copilot | GitHub Copilot CLI |
codex | Codex CLI |
qwen | Qwen Code |
Authentication#
Both the REST API server and MCP server support Bearer token authentication.
Generate a Token#
thinkt server token
# Output: thinkt_20260205_cd3bf36d6e1fc71e9bf033a7131f77cbUsing Authentication#
# Environment variable
export THINKT_API_TOKEN=$(thinkt server token)
thinkt server
# Command-line flag
thinkt server --token thinkt_20260205_...
# Client request
curl -H "Authorization: Bearer thinkt_20260205_..." http://localhost:8784/api/v1/sourcesWhen authentication is enabled, all API endpoints require a valid Bearer token. Unauthenticated requests receive a 401 Unauthorized response with a WWW-Authenticate header.
Error Handling#
All endpoints return errors in a consistent format:
{
"error": "error_code",
"message": "Human-readable error description"
}HTTP Status Codes:
| Code | Description |
|---|---|
200 | Success |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or missing token |
403 | Forbidden - Action not allowed |
404 | Not Found - Resource doesn’t exist |
500 | Internal Server Error |
CORS#
The API enables CORS for local development, allowing browser-based applications to access the API from different origins.
Examples#
List All Sessions Across Projects#
# Get all projects
projects=$(curl -s http://localhost:8784/api/v1/projects | jq -r '.projects[].id')
# For each project, list sessions
for proj in $projects; do
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$proj', safe=''))")
curl -s "http://localhost:8784/api/v1/projects/$encoded/sessions"
doneExport Session to JSON#
session_path="/Users/you/.claude/projects/abc123/session.jsonl"
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$session_path', safe=''))")
curl -s "http://localhost:8784/api/v1/sessions/$encoded" | jq . > session_export.jsonFilter Sessions by Model#
curl -s "http://localhost:8784/api/v1/sessions/$encoded" | \
jq '.entries[] | select(.model == "claude-3-opus")'See Also#
- thinkt server - Server command reference
- thinkt web - Web interface command reference
- MCP Server - Model Context Protocol integration
- CLI Guide - Command line interface guide