API Reference
February 7, 2026 ยท View on GitHub
AI Eval exposes a REST API under the /api prefix.
Starting the Server
The server listens on :8080 by default and supports:
-addr(default:8080)-config(defaultconfigs/config.yaml)
For local development, explicitly disable API auth:
AI_EVAL_DISABLE_AUTH=true go run ./cmd/server -addr :8080
Or build a standalone binary:
go build -o eval-server ./cmd/server
AI_EVAL_DISABLE_AUTH=true ./eval-server -addr :8080
Note: the API reads/writes prompts/ and tests/ relative to the process working directory.
Authentication
The API server requires one of the following at startup:
- Set
AI_EVAL_API_KEYto enable API key auth (sendX-API-Key: <key>on requests) - Or set
AI_EVAL_DISABLE_AUTH=trueto explicitly disable authentication (recommended only for local/trusted environments)
If neither is set, the server refuses to start.
Unauthorized requests return:
{"error":"unauthorized"}
CORS
CORS headers are disabled by default. Enable them by setting AI_EVAL_CORS_ORIGINS:
- Allow any origin:
AI_EVAL_CORS_ORIGINS="*" - Allow a fixed list (comma-separated):
AI_EVAL_CORS_ORIGINS="http://localhost:3000, https://example.com"
When enabled, the server allows:
- Methods:
GET,POST,DELETE,OPTIONS - Headers:
Content-Type, X-API-Key
Error Responses
All API errors use this format:
{"error":"<message>"}
JSON Field Naming
Some endpoints return Go structs without explicit json tags, so response keys are exported Go field names
(e.g. Name, Suite, StartedAt).
Endpoints
Health
GET /api/health
Response:
{"status":"ok","time":"2026-02-07T05:08:34Z"}
Prompts
List prompts:
GET /api/prompts
Optional query parameters:
name: case-insensitive exact match filter
Get one prompt:
GET /api/prompts/{name}
Upsert a prompt (writes prompts/<name>.yaml):
POST /api/prompts
Request Body (keys are case-insensitive):
{
"name": "example",
"version": "v1",
"description": "example prompt",
"template": "hello"
}
Delete a prompt:
DELETE /api/prompts/{name}
Returns 204 No Content on success.
Tests
List test suites:
GET /api/tests
Optional query parameters:
prompt: case-insensitive exact match filter
Get one suite:
GET /api/tests/{suite}
Responses are TestSuite objects (including Cases).
Runs
Start a run (runs suites from tests/ against prompts in prompts/):
POST /api/runs
Request Body:
{"prompt":"example","trials":3,"threshold":0.8,"concurrency":4}
Or run all prompts:
{"all":true}
Response: 201 Created
{
"run": {
"ID": "run_20260207T050834Z_deadbeef...",
"StartedAt": "2026-02-07T05:08:34Z",
"FinishedAt": "2026-02-07T05:08:40Z",
"TotalSuites": 1,
"PassedSuites": 1,
"FailedSuites": 0,
"Config": {"trials":3,"threshold":0.8,"concurrency":4,"all":false,"prompts":["example"]}
},
"summary": {
"total_suites": 1,
"total_cases": 10,
"passed_cases": 10,
"failed_cases": 0,
"total_latency_ms": 12345,
"total_tokens": 6789
}
}
List runs:
GET /api/runs
Query parameters:
limit(default20, must be> 0)since/until: RFC3339 orYYYY-MM-DDprompt/version: filters
Get one run:
GET /api/runs/{id}
Get suite results for a run:
GET /api/runs/{id}/results
History
GET /api/history/{prompt}
Optional query parameters:
limit(default20, must be> 0)
Returns a list of SuiteRecord entries.
Compare
POST /api/compare
Request Body:
{"prompt":"example","v1":"v1","v2":"v2"}
Returns a VersionComparison object.
Leaderboard
Get leaderboard entries:
GET /api/leaderboard?dataset=mmlu&limit=20
Query parameters:
dataset(required)limit(optional, default20, max100)
Returns a JSON array of entries.
Get model history:
GET /api/leaderboard/history?model=m1&dataset=gsm8k
Optimize
POST /api/optimize
Request Body:
{"prompt_content":"...","prompt_name":"example","num_cases":5}
Returns fields like analysis, suggestions, eval_results, optimized_prompt, changes,
and optimization_summary.
Diagnose
POST /api/diagnose
Request Body:
{"prompt_content":"...","tests_yaml":"<YAML>","max_suggestions":5}
Returns suites (summary) and diagnosis (details).
Example: cURL
# No auth (only if AI_EVAL_DISABLE_AUTH=true)
curl "http://localhost:8080/api/health"
# API key auth (only if AI_EVAL_API_KEY is set on the server)
curl "http://localhost:8080/api/health" -H "X-API-Key: $AI_EVAL_API_KEY"
# Start a run
curl -X POST "http://localhost:8080/api/runs" \
-H "Content-Type: application/json" \
-H "X-API-Key: $AI_EVAL_API_KEY" \
-d '{"prompt":"example","trials":3,"threshold":0.8,"concurrency":4}'