Evaluations API Reference¶
Overview¶
The Evaluations API provides comprehensive capabilities for assessing the quality of AI-generated content. The system supports multiple evaluation types including summarization quality (G-Eval), RAG system evaluation, and various text matching strategies.
Base URL: http://localhost:8000
API Version: v1
API Prefix: /api/v1
Authentication: See Authentication section
Authentication¶
All API requests require authentication. In single-user mode use X-API-KEY or a Bearer token; in multi-user use JWT Bearer tokens.
Single-User Mode (Development)¶
X-API-KEY: YOUR_SINGLE_USER_API_KEY
or
Authorization: Bearer YOUR_SINGLE_USER_API_KEY
Multi-User Mode (Production)¶
Authorization: Bearer YOUR_PERSONAL_API_KEY
Configuration: Authentication mode is set in tldw_Server_API/Config_Files/config.txt or via environment variables:
- AUTH_MODE: "single_user" or "multi_user"
- SINGLE_USER_API_KEY: API key for single-user mode
- JWT_SECRET_KEY: Secret for JWT tokens in multi-user mode
Endpoints¶
Evaluations¶
Create Evaluation¶
POST /api/v1/evaluations
Creates a new evaluation definition.
Request Body:
{
"name": "string", // Required, unique name for the evaluation
"description": "string", // Optional description
"eval_type": "string", // Required: "model_graded" | "exact_match" | "fuzzy_match" | "includes"
"eval_spec": { // Required, evaluation configuration
// For model_graded evaluations:
"sub_type": "string", // Required for model_graded: "summarization" | "rag" | "response_quality"
"evaluator_model": "string", // Model to use (default: "gpt-4")
"metrics": ["string"], // Metrics to evaluate (type-specific)
"threshold": 0.7, // Pass/fail threshold (0-1, default: 0.7)
"scoring_prompt": "string", // Optional custom scoring prompt
"custom_criteria": {} // Optional custom evaluation criteria
},
// Must provide EITHER dataset OR dataset_id, not both:
"dataset": [ // Option 1: Inline dataset
{
"input": {}, // Input data for evaluation
"expected": {} // Expected output (format varies by eval_type)
}
],
"dataset_id": "string", // Option 2: Reference to existing dataset
"metadata": { // Optional metadata
"author": "string",
"tags": ["string"],
"version": "string",
"custom_fields": {}
}
}
Response (201 Created):
{
"id": "eval_xxxxxxxxxxxx", // Unique evaluation ID
"object": "evaluation",
"created": 1234567890, // Unix timestamp
"name": "string",
"description": "string",
"eval_type": "string",
"eval_spec": {},
"dataset_id": "string",
"metadata": {}
}
Error Responses:
- 400 Bad Request - Invalid request body or missing required fields
- 401 Unauthorized - Missing or invalid API key
- 409 Conflict - Evaluation name already exists
- 422 Unprocessable Entity - Validation error (e.g., invalid eval_type)
Important Notes:
- You MUST provide either dataset (inline data) or dataset_id (reference), but not both
- The sub_type field is REQUIRED when eval_type is "model_graded"
- All scores and thresholds use a 0-1 scale where 1 is best
List Evaluations¶
GET /api/v1/evaluations
Lists evaluations with pagination support.
Query Parameters:
- limit (integer, 1-100, default: 20) - Number of items per page
- after (string) - Cursor for pagination (use last_id from previous response)
- order (string, "asc" | "desc", default: "desc") - Sort order by creation time
- eval_type (string) - Filter by evaluation type
Response (200 OK):
{
"object": "list",
"data": [
{
"id": "eval_xxxxxxxxxxxx",
"object": "evaluation",
"created": 1234567890,
"name": "string",
"description": "string",
"eval_type": "string",
"eval_spec": {},
"dataset_id": "string",
"metadata": {}
}
],
"has_more": false, // More results available
"first_id": "eval_xxxxxxxxxxxx",
"last_id": "eval_yyyyyyyyyyyy"
}
Error Responses:
- 401 Unauthorized - Invalid API key
Get Evaluation¶
GET /api/v1/evaluations/{eval_id}
Retrieves a specific evaluation by ID.
Path Parameters:
- eval_id (string) - Evaluation ID (format: eval_xxxxxxxxxxxx)
Response (200 OK):
{
"id": "eval_xxxxxxxxxxxx",
"object": "evaluation",
"created": 1234567890,
"name": "string",
"description": "string",
"eval_type": "string",
"eval_spec": {},
"dataset_id": "string",
"metadata": {}
}
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Evaluation not found
Update Evaluation¶
PATCH /api/v1/evaluations/{eval_id}
Updates an existing evaluation. Only provided fields are updated.
Path Parameters:
- eval_id (string) - Evaluation ID
Request Body:
{
"name": "string", // Optional
"description": "string", // Optional
"eval_spec": {}, // Optional, partial updates supported
"dataset_id": "string", // Optional
"metadata": {} // Optional, replaces entire metadata
}
Response (200 OK): Updated evaluation object
Error Responses:
- 400 Bad Request - Invalid update data
- 401 Unauthorized - Invalid API key
- 404 Not Found - Evaluation not found
Delete Evaluation¶
DELETE /api/v1/evaluations/{eval_id}
Soft deletes an evaluation (may be recoverable).
Path Parameters:
- eval_id (string) - Evaluation ID
Response (204 No Content): Empty response on success
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Evaluation not found
Evaluation Runs¶
Create Run¶
POST /api/v1/evaluations/{eval_id}/runs
Starts an asynchronous evaluation run.
Path Parameters:
- eval_id (string) - Evaluation ID
Request Body:
{
"target_model": "string", // Optional, model being evaluated
"dataset_override": { // Optional, override evaluation's dataset
"samples": [
{
"input": {},
"expected": {}
}
]
},
"config": { // Run configuration
"temperature": 0.0, // LLM temperature (0-2, default: 0)
"max_workers": 4, // Parallel workers (1-16, default: 4)
"timeout_seconds": 300, // Timeout per sample (default: 300)
"batch_size": 10 // Batch size (1-100, default: 10)
},
"webhook_url": "string" // Optional webhook for completion notification
}
Response (202 Accepted):
{
"id": "run_xxxxxxxxxxxx",
"object": "evaluation.run",
"created": 1234567890,
"eval_id": "eval_xxxxxxxxxxxx",
"status": "pending", // "pending" | "running" | "completed" | "failed" | "cancelled"
"target_model": "string",
"progress": {
"total_samples": 0,
"completed_samples": 0,
"failed_samples": 0,
"current_batch": 0,
"percent_complete": 0.0
},
"estimated_completion": null,
"error_message": null,
"metadata": {}
}
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Evaluation not found
- 429 Too Many Requests - Rate limit exceeded (50/minute default)
List Runs¶
GET /api/v1/evaluations/{eval_id}/runs
Lists runs for a specific evaluation.
Path Parameters:
- eval_id (string) - Evaluation ID
Query Parameters:
- limit (integer, 1-100, default: 20) - Results per page
- after (string) - Cursor for pagination
- status (string) - Filter by status: "pending" | "running" | "completed" | "failed" | "cancelled"
Response (200 OK): List of run objects
Get Run Status¶
GET /api/v1/evaluations/runs/{run_id}
Gets current status and progress of a run.
Path Parameters:
- run_id (string) - Run ID (format: run_xxxxxxxxxxxx)
Response (200 OK):
{
"id": "run_xxxxxxxxxxxx",
"object": "evaluation.run",
"created": 1234567890,
"eval_id": "eval_xxxxxxxxxxxx",
"status": "running",
"target_model": "string",
"progress": {
"total_samples": 100,
"completed_samples": 45,
"failed_samples": 2,
"current_batch": 5,
"percent_complete": 45.0
},
"estimated_completion": 1234567950, // Unix timestamp
"error_message": null,
"metadata": {}
}
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Run not found
Get Run Results¶
GET /api/v1/evaluations/runs/{run_id}/results
Gets complete results for a finished run.
Path Parameters:
- run_id (string) - Run ID
Response (200 OK):
{
"id": "run_xxxxxxxxxxxx",
"object": "evaluation.run.result",
"eval_id": "eval_xxxxxxxxxxxx",
"status": "completed",
"started_at": 1234567890,
"completed_at": 1234567920,
"results": {
"aggregate": {
"mean_score": 0.85, // Average score (0-1)
"std_dev": 0.12, // Standard deviation
"min_score": 0.60, // Minimum score
"max_score": 0.98, // Maximum score
"pass_rate": 0.75, // Percentage passing threshold (0-1)
"total_samples": 100,
"failed_samples": 25
},
"by_metric": { // Breakdown by metric (if applicable)
"fluency": {
"mean": 0.88,
"std": 0.10,
"min": 0.65,
"max": 0.98,
"median": 0.89
},
"relevance": {
"mean": 0.82,
"std": 0.15,
"min": 0.55,
"max": 0.96,
"median": 0.84
}
},
"sample_results": [ // Individual sample results
{
"sample_id": "sample_0001",
"scores": {
"fluency": 0.85,
"relevance": 0.90
},
"passed": true, // Met threshold
"error": null
}
],
"failed_samples": [] // Samples that failed to evaluate
},
"usage": { // Token usage (for LLM evaluations)
"total_tokens": 15000,
"prompt_tokens": 10000,
"completion_tokens": 5000,
"cost_estimate": 0.45 // Estimated cost in USD
},
"duration_seconds": 30
}
Error Responses:
- 400 Bad Request - Run not completed yet
- 401 Unauthorized - Invalid API key
- 404 Not Found - Run not found
Cancel Run¶
POST /api/v1/evaluations/runs/{run_id}/cancel
Cancels a running evaluation.
Path Parameters:
- run_id (string) - Run ID
Response (200 OK):
{
"id": "run_xxxxxxxxxxxx",
"status": "cancelled" // or "cancelling" if still processing
}
Error Responses:
- 400 Bad Request - Run already completed or failed
- 401 Unauthorized - Invalid API key
- 404 Not Found - Run not found
Stream Run Progress¶
Not currently available on the unified router. Poll GET /api/v1/evaluations/runs/{run_id} for status updates.
Datasets¶
Create Dataset¶
POST /api/v1/evaluations/datasets
Creates a reusable dataset for evaluations.
Request Body:
{
"name": "string", // Required, unique name
"description": "string", // Optional description
"samples": [ // Required, dataset samples
{
"input": {}, // Input data (format depends on eval_type)
"expected": {} // Expected output
}
],
"metadata": {} // Optional metadata
}
Response (201 Created):
{
"id": "dataset_xxxxxxxxxxxx",
"object": "dataset",
"created": 1234567890,
"name": "string",
"description": "string",
"sample_count": 100,
"samples": [...], // Full sample data
"metadata": {}
}
Error Responses:
- 400 Bad Request - Invalid dataset format
- 401 Unauthorized - Invalid API key
- 409 Conflict - Dataset name already exists
List Datasets¶
GET /api/v1/evaluations/datasets
Lists available datasets.
Query Parameters:
- limit (integer, 1-100, default: 20)
- after (string) - Cursor for pagination
Response (200 OK):
{
"object": "list",
"data": [
{
"id": "dataset_xxxxxxxxxxxx",
"object": "dataset",
"created": 1234567890,
"name": "string",
"description": "string",
"sample_count": 100,
"samples": null, // Samples omitted in list view
"metadata": {}
}
],
"has_more": false,
"first_id": "dataset_xxxxxxxxxxxx",
"last_id": "dataset_yyyyyyyyyyyy"
}
Get Dataset¶
GET /api/v1/evaluations/datasets/{dataset_id}
Gets a specific dataset including all samples.
Path Parameters:
- dataset_id (string) - Dataset ID
Response (200 OK): Full dataset object with samples
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Dataset not found
Delete Dataset¶
DELETE /api/v1/evaluations/datasets/{dataset_id}
Permanently deletes a dataset.
Path Parameters:
- dataset_id (string) - Dataset ID
Response (204 No Content): Empty response on success
Error Responses:
- 401 Unauthorized - Invalid API key
- 404 Not Found - Dataset not found
Evaluation Types & Formats¶
model_graded¶
Uses an LLM to evaluate outputs. Requires sub_type specification.
summarization (G-Eval)¶
Evaluates text summarization quality.
eval_spec:
{
"sub_type": "summarization",
"evaluator_model": "gpt-4", // or "anthropic", "groq", etc.
"metrics": ["fluency", "consistency", "relevance", "coherence"],
"threshold": 0.7
}
Sample Format:
{
"input": {
"source_text": "Original document text to be summarized",
"summary": "The summary to evaluate"
}
}
Metrics:
- fluency: Grammar and readability (0-1)
- consistency: Factual alignment with source (0-1)
- relevance: Information selection quality (0-1)
- coherence: Logical flow and structure (0-1)
rag¶
Evaluates Retrieval-Augmented Generation systems.
eval_spec:
{
"sub_type": "rag",
"evaluator_model": "gpt-4",
"metrics": ["relevance", "faithfulness", "answer_similarity", "context_precision", "context_recall", "claim_faithfulness"],
"threshold": 0.75
}
Sample Format:
{
"input": {
"query": "User's question",
"contexts": ["Retrieved context 1", "Retrieved context 2"],
"response": "Generated response"
},
"expected": {
"answer": "Ground truth answer (optional)"
}
}
Metrics:
- relevance: Response relevance to query (0-1)
- faithfulness: Grounding in provided contexts (0-1)
- answer_similarity: Similarity to ground truth (0-1)
- context_precision: Precision of retrieved contexts (0-1)
- context_recall: Recall of relevant information (0-1)
- claim_faithfulness: Fraction of extracted claims supported by contexts (0-1)
response_quality¶
General response quality evaluation with custom criteria.
eval_spec:
{
"sub_type": "response_quality",
"evaluator_model": "gpt-4",
"custom_criteria": {
"helpfulness": "How helpful is the response?",
"accuracy": "Is the information accurate?",
"completeness": "Does it fully address the prompt?"
},
"threshold": 0.8
}
Sample Format:
{
"input": {
"prompt": "User's prompt",
"response": "Generated response",
"expected_format": "Expected response format (optional)"
}
}
exact_match¶
Checks for exact string match (case-insensitive).
eval_spec:
{
"threshold": 1.0 // Usually 1.0 for exact match
}
Sample Format:
{
"input": {"output": "Generated text"},
"expected": {"output": "Expected exact text"}
}
Scoring: 1.0 if exact match (case-insensitive), 0.0 otherwise
fuzzy_match¶
Uses string similarity algorithms (e.g., Levenshtein distance).
eval_spec:
{
"threshold": 0.85 // Similarity threshold (0-1)
}
Sample Format:
{
"input": {"output": "Generated text"},
"expected": {"output": "Similar expected text"}
}
Scoring: Similarity score from 0 (completely different) to 1 (identical)
includes¶
Checks if output contains all expected items.
eval_spec:
{
"threshold": 0.8 // Percentage of items that must be present (0-1)
}
Sample Format:
{
"input": {"output": "The generated text to check"},
"expected": {"includes": ["keyword1", "keyword2", "phrase to find"]}
}
Scoring: Percentage of expected items found in output (0-1)
Error Response Format¶
All error responses follow a consistent format:
{
"error": {
"message": "Human-readable error description",
"type": "error_type", // See error types below
"param": "parameter_name", // Optional, which parameter caused the error
"code": "error_code" // Optional, specific error code
}
}
Note: Some error responses may wrap the error object in a detail field:
{
"detail": {
"error": {
"message": "...",
"type": "...",
"code": "..."
}
}
}
Error Types:
- invalid_request_error - Invalid request parameters or body
- authentication_error - Invalid or missing API key
- permission_error - Insufficient permissions
- not_found_error - Resource not found
- rate_limit_error - Rate limit exceeded
- server_error - Internal server error
HTTP Status Codes:
- 200 OK - Successful GET/PATCH request
- 201 Created - Successful POST creating new resource
- 202 Accepted - Request accepted for async processing
- 204 No Content - Successful DELETE
- 400 Bad Request - Invalid request format or parameters
- 401 Unauthorized - Authentication required or failed
- 404 Not Found - Resource not found
- 409 Conflict - Resource already exists
- 422 Unprocessable Entity - Validation error
- 429 Too Many Requests - Rate limit exceeded
- 500 Internal Server Error - Server error
Rate Limits¶
Rate limits (route-specific for evaluations): - Standard evaluation requests: 60 requests/minute - Run operations: 10 requests/minute - Batch operations: 5 requests/minute - Burst protection: 10 requests/second
Webhooks¶
When webhook_url is provided in a run request, the following payload is sent upon completion:
{
"event": "run.completed", // or "run.failed" | "run.cancelled"
"run_id": "run_xxxxxxxxxxxx",
"eval_id": "eval_xxxxxxxxxxxx",
"status": "completed",
"completed_at": 1234567890,
"results_url": "/api/v1/evaluations/runs/run_xxxxxxxxxxxx/results",
"summary": {
"mean_score": 0.85,
"pass_rate": 0.75,
"total_samples": 100,
"duration_seconds": 30
},
"error": null // Error message if failed
}
Webhook Requirements: - Must accept POST requests - Should respond with 2xx status code - Timeout: 10 seconds - Retries: 3 attempts with exponential backoff
Code Examples¶
⚠️ Generate a strong API key (new format) and set it via
SINGLE_USER_API_KEYbefore running these examples:Replacepython -m tldw_Server_API.app.core.AuthNZ.initialize # Copy SINGLE_USER_API_KEY into your environmentYOUR_API_KEYbelow with that value (or load it from your environment at runtime).
Python¶
import json
from urllib.request import Request, urlopen
# Configuration
API_KEY = "YOUR_API_KEY"
BASE_URL = "http://localhost:8000"
headers = {"Authorization": f"Bearer {API_KEY}"}
def request_json(method, url, payload=None, headers=None):
data = json.dumps(payload).encode("utf-8") if payload is not None else None
hdrs = {"Content-Type": "application/json"}
if headers:
hdrs.update(headers)
req = Request(url, data=data, headers=hdrs, method=method)
with urlopen(req) as resp:
return json.loads(resp.read().decode("utf-8"))
# Create evaluation
eval_request = {
"name": "my_evaluation",
"eval_type": "exact_match",
"eval_spec": {"threshold": 1.0},
"dataset": [
{"input": {"output": "test"}, "expected": {"output": "test"}}
]
}
eval_response = request_json(
"POST",
f"{BASE_URL}/api/v1/evaluations",
payload=eval_request,
headers=headers,
)
eval_id = eval_response["id"]
# Run evaluation
run_request = {"config": {"temperature": 0}}
run_response = request_json(
"POST",
f"{BASE_URL}/api/v1/evaluations/{eval_id}/runs",
payload=run_request,
headers=headers,
)
run_id = run_response["id"]
# Get results
results = request_json(
"GET",
f"{BASE_URL}/api/v1/evaluations/runs/{run_id}/results",
headers=headers,
)
print(results)
cURL¶
# Set API key
export API_KEY="YOUR_API_KEY"
# Create evaluation
curl -X POST http://localhost:8000/api/v1/evaluations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "test_eval",
"eval_type": "exact_match",
"eval_spec": {"threshold": 1.0},
"dataset": [
{"input": {"output": "test"}, "expected": {"output": "test"}}
]
}'
# Run evaluation
curl -X POST http://localhost:8000/api/v1/evaluations/eval_xxx/runs \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"config": {"temperature": 0}}'
# Get results
curl http://localhost:8000/api/v1/evaluations/runs/run_xxx/results \
-H "Authorization: Bearer $API_KEY"
JavaScript/TypeScript¶
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'http://localhost:8000';
// Create evaluation
const evalResponse = await fetch(`${BASE_URL}/api/v1/evaluations`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'js_eval',
eval_type: 'exact_match',
eval_spec: { threshold: 1.0 },
dataset: [
{ input: { output: 'test' }, expected: { output: 'test' } }
]
})
});
const { id: evalId } = await evalResponse.json();
// Run evaluation
const runResponse = await fetch(`${BASE_URL}/api/v1/evaluations/${evalId}/runs`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ config: { temperature: 0 } })
});
const { id: runId } = await runResponse.json();
// Get results (after waiting)
const resultsResponse = await fetch(`${BASE_URL}/api/v1/evaluations/runs/${runId}/results`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
const results = await resultsResponse.json();
console.log(results);
API Specification¶
The complete OpenAPI 3.0 specification is available at:
- JSON: http://localhost:8000/openapi.json
- Interactive Docs (Swagger UI): http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Configuration¶
LLM Provider Configuration¶
Configure LLM providers in tldw_Server_API/Config_Files/config.txt:
[API]
# OpenAI
openai_api_key = sk-...
openai_model = gpt-4
# Anthropic
anthropic_api_key = sk-ant-...
anthropic_model = claude-opus-4-20250514
# Google
google_api_key = ...
google_model = gemini-pro
# Groq
groq_api_key = gsk_...
groq_model = mixtral-8x7b-32768
# Other providers...
Supported LLM Providers¶
- OpenAI (GPT-4o family, etc.)
- Anthropic (Claude models)
- Google (Gemini models)
- Groq (Mixtral, Llama, etc.)
- Cohere
- Mistral
- DeepSeek
- HuggingFace
- OpenRouter
- Local models (via Ollama, llama.cpp, etc.)
Important Notes¶
-
Dataset Requirement: Every evaluation MUST have either an inline
datasetor reference adataset_id. The API will return a 422 error if neither is provided. -
Score Interpretation: All scores use a 0-1 scale where 1 is best. The
thresholddetermines pass/fail. -
Async Processing: Evaluation runs are processed asynchronously. Use polling or SSE streaming to monitor progress.
-
Rate Limiting: Default rate limits apply unless
TESTING=trueis set. Plan accordingly for large evaluations. -
Error Handling: Always check for both
erroranddetail.errorformats when handling error responses. -
API Path: All endpoints use the
/api/v1/prefix. Using/v1/alone will result in 404 errors.
Support¶
- Documentation: See Quick Start Guide and User Guide
- Issues: Report at https://github.com/rmusser01/tldw_server/issues
- API Status: Check
/healthendpoint