Skip to content

REST Endpoints

Debug API

MethodPathDescription
GET/debug/api/List all debug entries (summaries)
GET/debug/api/summary/{id}Single entry summary
GET/debug/api/view/{id}Full entry data (optionally filtered by collector)
GET/debug/api/dump/{id}Dump objects for entry
GET/debug/api/object/{id}/{objectId}Specific object from dump
GET/debug/api/settingsDebug settings (path mapping)

Example: List entries

GET /debug/api/
json
{
    "id": null,
    "data": [
        {
            "id": "abc123",
            "collectors": ["request", "log", "event"],
            "url": "/api/users",
            "method": "GET",
            "status": 200,
            "time": 1234567890
        }
    ],
    "error": null,
    "success": true
}

Example: View entry

GET /debug/api/view/abc123?collector=log

Returns full collected data for the specified entry, optionally filtered to a single collector.

OTLP Trace Ingestion

MethodPathDescription
POST/debug/api/otlp/v1/tracesIngest OpenTelemetry traces in OTLP format

LLM API

All LLM endpoints share the same settings stored in .llm-settings.json. Both the debug panel and the toolbar use these endpoints — configure once, use everywhere.

See the AI Chat guide for user-facing documentation.

LLM Providers

ProviderAuthHow it works
openrouterAPI key or OAuthHTTP calls to OpenRouter API (default)
anthropicAPI key or OAuth tokenHTTP calls to Anthropic Messages API
openaiAPI keyHTTP calls to OpenAI Chat Completions API
acpNone (local agent)Spawns agent (e.g. Claude Code) as subprocess via Agent Client Protocol

Connection

MethodPathDescription
GET/debug/api/llm/statusConnection status, provider, model, timeout, custom prompt
POST/debug/api/llm/connectConnect with API key or ACP agent
POST/debug/api/llm/disconnectClear stored credentials

Status

GET /debug/api/llm/status
json
{
    "data": {
        "connected": true,
        "provider": "openrouter",
        "model": "anthropic/claude-sonnet-4",
        "timeout": 30,
        "customPrompt": "Reply in English. Be concise and actionable..."
    }
}

Connect with API Key

POST /debug/api/llm/connect
Content-Type: application/json

{"provider": "anthropic", "apiKey": "sk-ant-..."}

Supported providers: openrouter, anthropic, openai.

Connect with ACP

The ACP provider uses the Agent Client Protocol to communicate with local AI agents over stdio. ADP runs a persistent daemon process that manages multiple agent subprocesses — one per browser tab (session).

POST /debug/api/llm/connect
Content-Type: application/json
X-Acp-Session: <uuid>

{
  "provider": "acp",
  "acpCommand": "npx",
  "acpArgs": ["@agentclientprotocol/claude-agent-acp"]
}
  • acpCommand — Executable to run (default: npx). Must be on system PATH.
  • acpArgs — Arguments passed to the command (default: ["@agentclientprotocol/claude-agent-acp"]).
  • acpEnv — Environment variables merged into the agent's environment.

Required header: X-Acp-Session — a UUID identifying the browser tab. Generated via crypto.randomUUID() and stored in sessionStorage. The frontend SDK injects this header automatically on all LLM API requests.

Connect flow:

  1. Start daemon (if not running, or restart if protocol version mismatch)
  2. Start agent session for the given X-Acp-Session UUID
  3. Save settings only after both steps succeed

Response:

json
{
  "data": {
    "connected": true,
    "provider": "acp",
    "acpCommand": "npx",
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "agentName": "Claude",
    "agentVersion": "1.0.0"
  }
}

ACP adapters bridge the protocol to specific agents. Known adapters:

  • @agentclientprotocol/claude-agent-acp — Claude Code (default)
  • @anthropic-ai/gemini-agent-acp — Gemini CLI
  • @anthropic-ai/codex-agent-acp — Codex CLI

Daemon architecture:

The daemon (acp-daemon-runner.php) is a standalone PHP process that listens on a Unix socket at /tmp/adp-acp-{hash}.sock. It manages agent subprocesses via an internal protocol:

ActionDescription
pingHealth check, returns {ok, protocol, sessions}
session-startSpawn agent subprocess, perform ACP initialize handshake
session-stopTerminate a specific agent
session-statusCheck if a session's agent is alive
promptRoute session/new + session/prompt to the correct agent
shutdownStop all sessions and exit

Limits: max 10 concurrent sessions, 30-minute idle timeout per session.

Protocol lifecycle per chat request: initialize (on session start) → session/newsession/prompt (with streaming session/update notifications) → response.

OAuth (OpenRouter)

MethodPathDescription
POST/debug/api/llm/oauth/initiateStart OAuth PKCE flow, returns authUrl and codeVerifier
POST/debug/api/llm/oauth/exchangeExchange authorization code + codeVerifier for API key

Initiate

POST /debug/api/llm/oauth/initiate
Content-Type: application/json

{"callbackUrl": "https://localhost:5173/debug/llm/callback"}
json
{
    "data": {
        "authUrl": "https://openrouter.ai/auth?...",
        "codeVerifier": "..."
    }
}

Open authUrl in a popup. After user approval, OpenRouter redirects to callbackUrl?code=.... Exchange the code:

POST /debug/api/llm/oauth/exchange
Content-Type: application/json

{"code": "...", "codeVerifier": "..."}

Settings

MethodPathDescription
GET/debug/api/llm/modelsList available models for the connected provider
POST/debug/api/llm/modelSet active model: {"model": "anthropic/claude-sonnet-4"}
POST/debug/api/llm/timeoutSet timeout in seconds (5–300): {"timeout": 60}
POST/debug/api/llm/custom-promptSet system prompt: {"customPrompt": "..."}

All settings endpoints return the updated LlmStatus object (same shape as GET /status).

Chat & Analysis

MethodPathDescription
POST/debug/api/llm/chatSend chat completion request
POST/debug/api/llm/analyzeAnalyze debug entry data with AI

Chat

POST /debug/api/llm/chat
Content-Type: application/json

{
    "messages": [
        {"role": "user", "content": "Why is my /api/users endpoint slow?"}
    ],
    "model": "anthropic/claude-sonnet-4",
    "temperature": 0.7
}
json
{
    "data": {
        "choices": [{"message": {"role": "assistant", "content": "Based on..."}}],
        "model": "anthropic/claude-sonnet-4",
        "usage": {"prompt_tokens": 50, "completion_tokens": 200}
    }
}

The custom prompt (if set) is automatically prepended as a system message. All responses are normalized to the OpenAI-compatible format regardless of provider.

Analyze

POST /debug/api/llm/analyze
Content-Type: application/json

{
    "context": {"request": {"method": "GET", "path": "/api/users"}, "db": {"queries": {"total": 47}}},
    "prompt": "Why are there so many queries?"
}

Context is truncated to 12,000 characters. Returns {"data": {"analysis": "...", "model": "..."}}.

History

MethodPathDescription
GET/debug/api/llm/historyGet all history entries (max 100, FIFO)
POST/debug/api/llm/historyAdd entry: {query, response, timestamp, error?}
DELETE/debug/api/llm/history/{index}Delete entry by index
DELETE/debug/api/llm/historyClear all history

History is shared between the panel and toolbar — entries added from either appear in both.

Ingestion API

MethodPathDescription
POST/debug/api/ingest/Ingest single debug entry
POST/debug/api/ingest/batchIngest multiple entries
POST/debug/api/ingest/logShorthand: ingest a single log entry
GET/debug/api/ingest/openapi.jsonOpenAPI 3.1 specification

Service Registry API

MethodPathDescription
POST/debug/api/services/registerRegister an external service
POST/debug/api/services/heartbeatKeep service online
GET/debug/api/services/List registered services
DELETE/debug/api/services/{service}Deregister a service

Released under the MIT License.