Themis Framework exposes a REST API for orchestrating multi-agent legal workflows.
- Default:
http://localhost:8000
Methods:
- Header:
Authorization: Bearer {your-api-key} - Header:
X-API-Key: {your-api-key}
Development Mode:
- No authentication required when
THEMIS_API_KEYenvironment variable is not set - Production deployment: Set
THEMIS_API_KEYin.envfile
Key Rotation:
- Supports primary and previous API keys
- Set
THEMIS_API_KEY_PREVIOUSfor graceful key rotation - Both keys remain valid during rotation period
Create an execution plan from a matter payload.
Rate Limit: 20 requests/minute
Request Body:
{
"matter": {
"summary": "Brief case description",
"parties": ["Party 1", "Party 2"],
"documents": [
{
"title": "Document Title",
"content": "Document text...",
"date": "2024-01-15"
}
],
"events": [
{
"date": "2024-01-15",
"description": "Event description"
}
],
"goals": {
"settlement": "Desired outcome"
}
}
}Response:
{
"plan_id": "plan_abc123",
"status": "planned",
"tasks": [
{
"agent": "lda",
"phase": "INTAKE_FACTS",
"description": "Extract facts and build timeline"
}
],
"created_at": "2024-01-15T10:30:00Z"
}Status Codes:
200 OK- Plan created successfully400 Bad Request- Invalid matter payload401 Unauthorized- Missing or invalid API key422 Unprocessable Entity- Validation error429 Too Many Requests- Rate limit exceeded
Execute a workflow with a plan ID or matter payload.
Rate Limit: 10 requests/minute
Request Body (with plan_id):
{
"plan_id": "plan_abc123"
}Request Body (with matter):
{
"matter": {
"summary": "Case description",
"parties": ["Party 1", "Party 2"],
...
}
}Response:
{
"plan_id": "plan_abc123",
"status": "completed",
"artifacts": {
"timeline": "2024-01-15,Incident occurred\n...",
"demand_letter": "Dear Counsel,\n\n...",
"legal_analysis": "The following issues were identified..."
},
"execution_time": 12.34,
"agents_executed": ["lda", "dea", "lsa"]
}Status Codes:
200 OK- Execution completed successfully400 Bad Request- Invalid request (missing plan_id or matter)401 Unauthorized- Missing or invalid API key404 Not Found- Plan ID not found422 Unprocessable Entity- Validation error429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Execution failed
Retrieve a stored execution plan.
Rate Limit: 60 requests/minute
Path Parameters:
plan_id(string, required) - The plan identifier
Response:
{
"plan_id": "plan_abc123",
"status": "planned",
"tasks": [...],
"created_at": "2024-01-15T10:30:00Z"
}Status Codes:
200 OK- Plan retrieved successfully401 Unauthorized- Missing or invalid API key404 Not Found- Plan not found429 Too Many Requests- Rate limit exceeded
Retrieve execution results and artifacts.
Rate Limit: 60 requests/minute
Path Parameters:
plan_id(string, required) - The plan identifier
Response:
{
"plan_id": "plan_abc123",
"status": "completed",
"artifacts": {
"timeline": "CSV content...",
"demand_letter": "Letter content...",
"legal_analysis": "Analysis content..."
},
"execution_time": 12.34,
"completed_at": "2024-01-15T10:35:00Z"
}Status Codes:
200 OK- Artifacts retrieved successfully401 Unauthorized- Missing or invalid API key404 Not Found- Plan not found or not executed429 Too Many Requests- Rate limit exceeded
Health check and readiness probe.
Rate Limit: None
Response:
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00Z"
}Status Codes:
200 OK- Service is healthy
Prometheus-format metrics for monitoring.
Rate Limit: None
Response:
# HELP themis_agent_run_seconds Agent execution time
# TYPE themis_agent_run_seconds histogram
themis_agent_run_seconds_bucket{agent="lda",le="0.5"} 10
themis_agent_run_seconds_bucket{agent="lda",le="1.0"} 25
...
# HELP themis_agent_tool_invocations_total Total tool invocations
# TYPE themis_agent_tool_invocations_total counter
themis_agent_tool_invocations_total{agent="lda"} 150
themis_agent_tool_invocations_total{agent="dea"} 200
...
# HELP themis_agent_run_errors_total Total agent execution errors
# TYPE themis_agent_run_errors_total counter
themis_agent_run_errors_total{agent="lsa"} 3
Status Codes:
200 OK- Metrics retrieved successfully
All error responses follow a consistent format:
{
"detail": "Error message describing what went wrong"
}Common Errors:
400 Bad Request:
{
"detail": "Request must include either 'plan_id' or 'matter'"
}401 Unauthorized:
{
"detail": "Invalid API key"
}422 Validation Error:
{
"detail": [
{
"loc": ["body", "matter", "summary"],
"msg": "field required",
"type": "value_error.missing"
}
]
}429 Rate Limit:
{
"detail": "Rate limit exceeded. Try again in 60 seconds."
}Rate limits are applied per API key:
| Endpoint | Limit | Window |
|---|---|---|
/orchestrator/plan |
20 requests | 1 minute |
/orchestrator/execute |
10 requests | 1 minute |
/orchestrator/plans/* |
60 requests | 1 minute |
/orchestrator/artifacts/* |
60 requests | 1 minute |
/health |
Unlimited | - |
/metrics |
Unlimited | - |
Rate Limit Headers:
X-RateLimit-Limit- Maximum requests allowedX-RateLimit-Remaining- Requests remaining in current windowX-RateLimit-Reset- Timestamp when limit resets
Request Headers:
Authorization: Bearer {token}- API authenticationX-API-Key: {key}- Alternative API authenticationContent-Type: application/json- Required for POST requests
Response Headers:
X-Request-ID- Unique request identifier for debuggingX-Response-Time-Ms- Server processing time in millisecondsContent-Type: application/json- JSON response format
- Maximum request body size: 10 MB
- Request timeout: 120 seconds (2 minutes)
- Field limits:
- String fields: 10,000 characters
- Array fields: 1,000 items
Create and execute a plan:
# Create plan
curl -X POST http://localhost:8000/orchestrator/plan \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d @matter.json
# Execute plan
curl -X POST http://localhost:8000/orchestrator/execute \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"plan_id": "plan_abc123"}'
# Get artifacts
curl http://localhost:8000/orchestrator/artifacts/plan_abc123 \
-H "X-API-Key: your-api-key"import httpx
import json
API_KEY = "your-api-key"
BASE_URL = "http://localhost:8000"
async def execute_legal_workflow():
headers = {"X-API-Key": API_KEY}
# Load matter
with open("matter.json") as f:
matter = json.load(f)
async with httpx.AsyncClient() as client:
# Create plan
plan_resp = await client.post(
f"{BASE_URL}/orchestrator/plan",
json={"matter": matter},
headers=headers
)
plan_resp.raise_for_status()
plan = plan_resp.json()
# Execute
exec_resp = await client.post(
f"{BASE_URL}/orchestrator/execute",
json={"plan_id": plan["plan_id"]},
headers=headers
)
exec_resp.raise_for_status()
result = exec_resp.json()
print(f"Status: {result['status']}")
print(f"Artifacts: {list(result['artifacts'].keys())}")
return resultconst API_KEY = "your-api-key";
const BASE_URL = "http://localhost:8000";
async function executeLegalWorkflow(matter) {
const headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
};
// Create plan
const planResp = await fetch(`${BASE_URL}/orchestrator/plan`, {
method: "POST",
headers,
body: JSON.stringify({ matter })
});
const plan = await planResp.json();
// Execute
const execResp = await fetch(`${BASE_URL}/orchestrator/execute`, {
method: "POST",
headers,
body: JSON.stringify({ plan_id: plan.plan_id })
});
const result = await execResp.json();
console.log(`Status: ${result.status}`);
console.log(`Artifacts: ${Object.keys(result.artifacts)}`);
return result;
}Interactive API documentation is available when the server is running:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
The interactive documentation allows you to:
- Browse all endpoints and schemas
- Try API requests directly from your browser
- View example requests and responses
- Download the OpenAPI specification
- Quick Start Guide - Get started with Themis
- Deployment Guide - Production deployment instructions