Complete REST API specification for Claude Escalate v4.0.0. All endpoints require no authentication for local deployment, support JSON request/response format, and follow HTTP conventions.
http://localhost:9000/api
Returns service health status.
Response (200 OK):
{
"status": "healthy",
"uptime_seconds": 3600,
"version": "4.0.0",
"timestamp": "2026-04-26T12:00:00Z"
}Submit a batch of requests for processing (50% cost reduction).
Request:
{
"requests": [
{"query": "Analyze file1.go for security"},
{"query": "Analyze file2.go for security"},
{"query": "Analyze file3.go for security"}
]
}Response (202 Accepted):
{
"job_id": "batch_abc123xyz789",
"status": "queued",
"request_count": 3,
"submitted_at": "2026-04-27T10:30:00Z",
"estimated_completion": "2026-04-27T11:30:00Z"
}Check status of batch job.
Response (200 OK):
{
"job_id": "batch_abc123xyz789",
"status": "processing",
"request_count": 3,
"completed_count": 1,
"failed_count": 0,
"progress_percent": 33,
"submitted_at": "2026-04-27T10:30:00Z",
"started_at": "2026-04-27T10:35:00Z",
"estimated_completion": "2026-04-27T11:30:00Z"
}Status Values:
queued— Batch submitted, waiting to startprocessing— Requests being processedcompleted— All requests processed (check results)failed— Batch failed (check error)
Retrieve results from completed batch.
Response (200 OK):
{
"job_id": "batch_abc123xyz789",
"status": "completed",
"request_count": 3,
"responses": [
{
"query": "Analyze file1.go for security",
"response": "Security analysis of file1.go...",
"tokens_used": 2450,
"cost": "$0.00735"
},
{
"query": "Analyze file2.go for security",
"response": "Security analysis of file2.go...",
"tokens_used": 2380,
"cost": "$0.00714"
},
{
"query": "Analyze file3.go for security",
"error": "Rate limit exceeded",
"status": "failed"
}
],
"total_tokens": 7230,
"total_cost": "$0.02161",
"cost_without_batch": "$0.04322",
"savings": "50%"
}Cancel a queued batch (cannot cancel if already processing).
Response (200 OK):
{
"job_id": "batch_abc123xyz789",
"status": "cancelled",
"message": "Batch cancelled successfully"
}List all active batch jobs.
Response (200 OK):
{
"jobs": [
{
"job_id": "batch_abc123xyz789",
"status": "processing",
"progress": "45/100",
"submitted_at": "2026-04-27T10:00:00Z"
},
{
"job_id": "batch_xyz789abc123",
"status": "queued",
"progress": "0/50",
"submitted_at": "2026-04-27T10:15:00Z"
}
],
"total_active": 2
}Classify a prompt into a task type using ML embeddings.
Request:
{
"prompt": "race condition deadlock concurrent",
"use_fallback": false
}Response (200 OK):
{
"task_type": "concurrency",
"confidence": 0.92,
"embedding_dims": 384,
"fallback_used": false
}Status Codes:
- 200: Successfully classified
- 400: Invalid prompt (empty or >10000 chars)
- 500: Internal error
Retrieve time-series metrics for a specific bucket.
Query Parameters:
bucket(string, required): "hourly", "daily", or "weekly"days(integer, optional): Days to look back (default: 7)
Response (200 OK):
[
{
"timestamp": "2026-04-26T00:00:00Z",
"bucket": "daily",
"total_requests": 1000,
"cache_hits": 400,
"cache_misses": 600,
"batch_queued": 150,
"direct_requests": 250,
"total_cost_usd": 15.50,
"success_rate": 0.95,
"avg_latency_ms": 125.3,
"p50_latency_ms": 100.0,
"p95_latency_ms": 250.5,
"p99_latency_ms": 500.0
}
]Example:
curl "http://localhost:9000/api/analytics/timeseries?bucket=daily&days=30"Retrieve latency percentile distributions.
Query Parameters:
bucket(string, optional): "hourly" or "daily" (default: "daily")days(integer, optional): Days to look back (default: 7)
Response (200 OK):
{
"overall": {
"p50": 100.5,
"p75": 150.3,
"p90": 250.0,
"p95": 400.5,
"p99": 750.0,
"min": 10.0,
"max": 2000.0,
"mean": 175.0,
"std_dev": 250.0,
"sample_count": 10000
},
"by_model": {
"haiku": { "p50": 50.0, "p95": 200.0, ... },
"sonnet": { "p50": 100.0, "p95": 300.0, ... },
"opus": { "p50": 150.0, "p95": 500.0, ... }
},
"by_task": {
"concurrency": { "p50": 120.0, "p95": 350.0, ... },
"parsing": { "p50": 80.0, "p95": 150.0, ... }
}
}Generate cost forecast with confidence intervals.
Query Parameters:
metric(string, optional): "total_cost_usd" (default)days(integer, optional): Days to forecast (default: 7)
Response (200 OK):
{
"metric": "total_cost_usd",
"forecasts": [
{
"timestamp": "2026-04-27T00:00:00Z",
"point": 16.50,
"lower_bound": 14.20,
"upper_bound": 18.80
},
{
"timestamp": "2026-04-28T00:00:00Z",
"point": 17.25,
"lower_bound": 14.75,
"upper_bound": 19.75
}
],
"model_quality": {
"rmse": 0.85,
"r_squared": 0.92,
"slope": 0.75,
"intercept": 10.5
}
}Retrieve per-task-per-model accuracy metrics.
Query Parameters:
days(integer, optional): Days to look back (default: 30)min_samples(integer, optional): Minimum samples required (default: 5)
Response (200 OK):
[
{
"task_type": "concurrency",
"model": "sonnet",
"success_count": 95,
"total_count": 100,
"success_rate": 0.95,
"avg_token_error": 0.08,
"avg_latency_ms": 125.5
},
{
"task_type": "parsing",
"model": "haiku",
"success_count": 88,
"total_count": 100,
"success_rate": 0.88,
"avg_token_error": 0.12,
"avg_latency_ms": 75.3
}
]Sorting: Results sorted by task_type then success_rate descending
Analyze statistical correlations between metrics.
Response (200 OK):
[
{
"variable1": "success_rate",
"variable2": "latency_ms",
"coefficient": -0.45,
"p_value": 0.001,
"significant": true
},
{
"variable1": "cache_hits",
"variable2": "actual_cost_usd",
"coefficient": -0.89,
"p_value": 0.0001,
"significant": true
}
]Note: Only significant correlations (p < 0.05) returned
Retrieve current configuration.
Response (200 OK):
{
"cache": {
"enabled": true,
"ttl_seconds": 604800,
"similarity_threshold": 0.85,
"max_entries": 10000
},
"batch": {
"enabled": true,
"strategy": "auto",
"min_size": 3,
"max_wait_seconds": 300,
"min_savings_percent": 5.0
},
"budgets": {
"daily_limit": 10.00,
"weekly_limit": 50.00,
"monthly_limit": 200.00
},
"observability": {
"prometheus": {
"enabled": true,
"port": 9090,
"path": "/metrics"
},
"otel": {
"enabled": true,
"endpoint": "http://otel-collector:4317",
"interval_seconds": 60
}
}
}Update configuration.
Request:
{
"budgets": {
"daily_limit": 15.00,
"weekly_limit": 75.00
}
}Response (200 OK):
{
"status": "config_updated",
"affected_fields": ["budgets.daily_limit", "budgets.weekly_limit"]
}Validation:
- daily_limit: 0.01 - 10000.00
- weekly_limit: 0.01 - 50000.00
- monthly_limit: 0.01 - 500000.00
Get budget status and usage.
Response (200 OK):
{
"daily": {
"limit": 10.00,
"used": 7.25,
"remaining": 2.75,
"percentage": 72.5,
"reset_at": "2026-04-27T00:00:00Z"
},
"weekly": {
"limit": 50.00,
"used": 35.80,
"remaining": 14.20,
"percentage": 71.6,
"reset_at": "2026-05-03T00:00:00Z"
},
"monthly": {
"limit": 200.00,
"used": 120.50,
"remaining": 79.50,
"percentage": 60.25,
"reset_at": "2026-05-26T00:00:00Z"
}
}Set budget limit.
Request:
{
"type": "daily",
"limit": 12.50
}Response (200 OK):
{
"type": "daily",
"limit": 12.50,
"previous_limit": 10.00
}Export metrics in Prometheus text format.
Response (200 OK, text/plain):
# HELP claude_escalate_requests_total Total number of requests processed
# TYPE claude_escalate_requests_total counter
claude_escalate_requests_total 15234
# HELP claude_escalate_cache_hits_total Total cache hits
# TYPE claude_escalate_cache_hits_total counter
claude_escalate_cache_hits_total 6093
# HELP claude_escalate_model_usage_total Total requests per model
# TYPE claude_escalate_model_usage_total counter
claude_escalate_model_usage_total{model="haiku"} 9140
claude_escalate_model_usage_total{model="sonnet"} 4321
claude_escalate_model_usage_total{model="opus"} 1773
# HELP claude_escalate_cache_hit_rate Cache hit rate
# TYPE claude_escalate_cache_hit_rate gauge
claude_escalate_cache_hit_rate 0.399
Format: Prometheus Exposition Format
Get metrics as JSON snapshot.
Response (200 OK):
{
"total_requests": 15234,
"cache_hits": 6093,
"cache_hit_rate": 0.399,
"batch_queued": 2341,
"model_switches": 156,
"cache_size": 2150,
"queue_size": 0,
"cost_this_month": 847.32,
"cost_per_request": 0.0556,
"active_sessions": 3,
"model_usage": {
"haiku": 9140,
"sonnet": 4321,
"opus": 1773
},
"latency_p50": 125.0,
"latency_p95": 350.5,
"latency_p99": 750.0
}{
"error": "invalid_parameter",
"message": "Parameter 'days' must be between 1 and 365",
"status": 400
}{
"error": "resource_not_found",
"message": "No data available for requested period",
"status": 404
}{
"error": "internal_error",
"message": "Database connection failed",
"status": 500,
"trace_id": "abc123def456"
}- Default: 1000 requests/minute per client IP
- Burst: 100 requests/second
- Response Header:
X-RateLimit-Remaining: 999
Current API version: v1 (implicit in base URL)
Future versions will use /api/v2, /api/v3, etc.
File: docs/openapi.yaml
openapi: 3.0.0
info:
title: Claude Escalate API
version: 4.0.0
description: Cost optimization API for Claude deployments
servers:
- url: http://localhost:9000/api
description: Local development
paths:
/health:
get:
summary: Health check
responses:
'200':
description: Service healthy
/classify/predict:
post:
summary: Classify prompt into task type
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
prompt:
type: string
responses:
'200':
description: Classification successful
/analytics/timeseries:
get:
summary: Get time-series metrics
parameters:
- name: bucket
in: query
schema:
type: string
enum: [hourly, daily, weekly]
- name: days
in: query
schema:
type: integer
responses:
'200':
description: Time-series data
# ... additional pathsList all configured tools with health status.
Response (200 OK):
{
"tools": [
{
"name": "my_script",
"type": "cli",
"path": "/usr/local/bin/my_script",
"health": "ok",
"settings": {}
},
{
"name": "custom_mcp",
"type": "mcp",
"path": "~/.sockets/custom.sock",
"health": "ok",
"settings": {"timeout": 30}
}
]
}Add a new custom tool (CLI, MCP, REST, Database, or Binary).
Request:
{
"name": "new_tool",
"type": "cli",
"path": "/usr/local/bin/new_tool",
"settings": {}
}Response (200 OK):
{
"status": "created",
"message": "Tool added successfully",
"tool": {
"name": "new_tool",
"type": "cli",
"path": "/usr/local/bin/new_tool",
"health": "ok",
"settings": {}
}
}Validation:
- Tool name: alphanumeric + underscore only
- Path must exist for CLI tools
- Type must be one of: cli, mcp, rest, database, binary
- Duplicate tool names are rejected
Update existing tool configuration.
Request:
{
"path": "/new/path/to/tool",
"settings": {"timeout": 60}
}Response (200 OK):
{
"status": "updated",
"message": "Tool updated successfully"
}Remove a tool from configuration.
Response (200 OK):
{
"status": "deleted",
"message": "Tool removed successfully"
}Test tool connectivity and health status.
Response (200 OK - Healthy):
{
"status": "healthy",
"message": "Tool is responding"
}Response (200 OK - Unhealthy):
{
"status": "unhealthy",
"error": "Connection refused on socket"
}List available tool types and descriptions.
Response (200 OK):
{
"types": [
{"type": "cli", "description": "Shell command or script"},
{"type": "mcp", "description": "MCP (Model Context Protocol) server"},
{"type": "rest", "description": "HTTP REST API"},
{"type": "database", "description": "SQL database"},
{"type": "binary", "description": "Standalone executable"}
]
}import "github.com/szibis/claude-escalate/sdk"
client := sdk.NewClient("http://localhost:9000")
metrics, err := client.Analytics.GetTimeseries("daily", 7)from claude_escalate import Client
client = Client("http://localhost:9000")
metrics = client.analytics.get_timeseries("daily", days=7)See web/src/api.js for reference implementation.
Last Updated: 2026-04-27
Status: Stable (v0.8.0)
Next Review: 2026-06-27