API Contract Specification: ScamShield AI
REST API Endpoints & JSON Schemas
Version: 1.0.0
Base URL: https://api.scamshield.example.com/api/v1
Date: January 26, 2026
Protocol: HTTPS
Content-Type: application/json
TABLE OF CONTENTS
AUTHENTICATION
Phase 1: No authentication required (competition testing)
Phase 2: Bearer token authentication
Authorization: Bearer {api_key}
ENDPOINTS
Overview
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /honeypot/engage | Primary scam detection and engagement | No (Phase 1) |
| GET | /honeypot/session/{session_id} | Retrieve conversation history | No (Phase 1) |
| GET | /health | Service health check | No |
| POST | /honeypot/batch | Batch message processing | No (Phase 1) |
1. POST /honeypot/engage
Description: Detect scam messages and engage scammers with AI personas to extract intelligence.
Endpoint: POST /api/v1/honeypot/engage
Request
Headers:
Content-Type: application/json
Accept: application/json
Body Schema:
{
"message": {
"type": "string",
"required": true,
"minLength": 1,
"maxLength": 5000,
"description": "The message to analyze for scam detection"
},
"session_id": {
"type": "string",
"required": false,
"format": "uuid",
"description": "Session ID for multi-turn conversations. Auto-generated if not provided."
},
"language": {
"type": "string",
"required": false,
"enum": ["auto", "en", "hi"],
"default": "auto",
"description": "Message language. 'auto' for automatic detection."
},
"mock_scammer_callback": {
"type": "string",
"required": false,
"format": "uri",
"description": "Competition testing: URL to call with agent responses"
}
}
Request Example:
{
"message": "Congratulations! You have won ₹10 lakh rupees. Share your OTP to claim the prize immediately.",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"language": "auto"
}
Validation Rules:
message: Must not be empty or only whitespacesession_id: Must be valid UUID v4 format (if provided)language: Must be one of: "auto", "en", "hi"mock_scammer_callback: Must be valid HTTP/HTTPS URL (if provided)
Response (Scam Detected)
Status Code: 200 OK
Body Schema:
{
"status": {
"type": "string",
"enum": ["success", "error"],
"description": "Request processing status"
},
"scam_detected": {
"type": "boolean",
"description": "Whether the message was classified as a scam"
},
"confidence": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Scam detection confidence score"
},
"language_detected": {
"type": "string",
"enum": ["en", "hi", "hinglish"],
"description": "Detected language of the message"
},
"session_id": {
"type": "string",
"format": "uuid",
"description": "Session identifier for this conversation"
},
"engagement": {
"type": "object",
"properties": {
"agent_response": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "AI agent's response to the scammer"
},
"turn_count": {
"type": "integer",
"minimum": 1,
"maximum": 20,
"description": "Current conversation turn number"
},
"max_turns_reached": {
"type": "boolean",
"description": "Whether maximum conversation turns reached"
},
"strategy": {
"type": "string",
"enum": ["build_trust", "express_confusion", "probe_details"],
"description": "Current engagement strategy"
},
"persona": {
"type": "string",
"enum": ["elderly", "eager", "confused"],
"description": "Active persona type"
}
},
"required": ["agent_response", "turn_count", "max_turns_reached", "strategy"]
},
"extracted_intelligence": {
"type": "object",
"properties": {
"upi_ids": {
"type": "array",
"items": {"type": "string"},
"description": "Extracted UPI IDs (e.g., user@paytm)"
},
"bank_accounts": {
"type": "array",
"items": {"type": "string"},
"description": "Extracted bank account numbers (9-18 digits)"
},
"ifsc_codes": {
"type": "array",
"items": {"type": "string"},
"description": "Extracted IFSC codes (11 chars, format XXXX0XXXXXX)"
},
"phone_numbers": {
"type": "array",
"items": {"type": "string"},
"description": "Extracted phone numbers (Indian mobile format)"
},
"phishing_links": {
"type": "array",
"items": {"type": "string", "format": "uri"},
"description": "Extracted phishing/suspicious URLs"
},
"extraction_confidence": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Overall confidence in extracted intelligence"
}
},
"required": ["upi_ids", "bank_accounts", "ifsc_codes", "phone_numbers", "phishing_links", "extraction_confidence"]
},
"conversation_history": {
"type": "array",
"items": {
"type": "object",
"properties": {
"turn": {
"type": "integer",
"minimum": 1,
"description": "Turn number in conversation"
},
"sender": {
"type": "string",
"enum": ["scammer", "agent"],
"description": "Message sender"
},
"message": {
"type": "string",
"description": "Message content"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Message timestamp in ISO-8601 format"
}
},
"required": ["turn", "sender", "message", "timestamp"]
},
"description": "Complete conversation history"
},
"metadata": {
"type": "object",
"properties": {
"processing_time_ms": {
"type": "integer",
"description": "Total processing time in milliseconds"
},
"model_version": {
"type": "string",
"description": "System version"
},
"detection_model": {
"type": "string",
"description": "Model used for scam detection"
},
"engagement_model": {
"type": "string",
"description": "Model used for engagement"
}
},
"required": ["processing_time_ms", "model_version"]
}
}
Response Example (Scam Detected):
{
"status": "success",
"scam_detected": true,
"confidence": 0.94,
"language_detected": "en",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"engagement": {
"agent_response": "Oh wonderful! I'm so excited! But I'm not very good with technology. Can you please tell me step by step how to claim this prize?",
"turn_count": 1,
"max_turns_reached": false,
"strategy": "build_trust",
"persona": "elderly"
},
"extracted_intelligence": {
"upi_ids": [],
"bank_accounts": [],
"ifsc_codes": [],
"phone_numbers": [],
"phishing_links": [],
"extraction_confidence": 0.0
},
"conversation_history": [
{
"turn": 1,
"sender": "scammer",
"message": "Congratulations! You have won ₹10 lakh rupees. Share your OTP to claim the prize immediately.",
"timestamp": "2026-01-26T10:30:00.000Z"
},
{
"turn": 1,
"sender": "agent",
"message": "Oh wonderful! I'm so excited! But I'm not very good with technology. Can you please tell me step by step how to claim this prize?",
"timestamp": "2026-01-26T10:30:02.150Z"
}
],
"metadata": {
"processing_time_ms": 1850,
"model_version": "v1.0.0",
"detection_model": "indic-bert",
"engagement_model": "groq-llama-3.1-70b"
}
}
Response (Not Scam)
Status Code: 200 OK
Body Schema:
{
"status": {
"type": "string",
"enum": ["success"],
"description": "Request processing status"
},
"scam_detected": {
"type": "boolean",
"const": false,
"description": "Message classified as legitimate"
},
"confidence": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence that message is NOT a scam"
},
"language_detected": {
"type": "string",
"enum": ["en", "hi", "hinglish"],
"description": "Detected language"
},
"session_id": {
"type": "string",
"format": "uuid",
"description": "Session identifier"
},
"message": {
"type": "string",
"description": "Human-readable response"
}
}
Response Example (Not Scam):
{
"status": "success",
"scam_detected": false,
"confidence": 0.12,
"language_detected": "en",
"session_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"message": "No scam detected. Message appears legitimate."
}
Response (Hindi Scam Example)
Response Example:
{
"status": "success",
"scam_detected": true,
"confidence": 0.96,
"language_detected": "hi",
"session_id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
"engagement": {
"agent_response": "अरे वाह! बहुत अच्छी बात है। लेकिन मुझे समझ नहीं आ रहा, मैं OTP कैसे भेजूं? मेरा फोन बहुत पुराना है।",
"turn_count": 1,
"max_turns_reached": false,
"strategy": "build_trust",
"persona": "elderly"
},
"extracted_intelligence": {
"upi_ids": [],
"bank_accounts": [],
"ifsc_codes": [],
"phone_numbers": [],
"phishing_links": [],
"extraction_confidence": 0.0
},
"conversation_history": [
{
"turn": 1,
"sender": "scammer",
"message": "आप जीत गए हैं 10 लाख रुपये! अपना OTP शेयर करें।",
"timestamp": "2026-01-26T10:35:00.000Z"
},
{
"turn": 1,
"sender": "agent",
"message": "अरे वाह! बहुत अच्छी बात है। लेकिन मुझे समझ नहीं आ रहा, मैं OTP कैसे भेजूं? मेरा फोन बहुत पुराना है।",
"timestamp": "2026-01-26T10:35:01.920Z"
}
],
"metadata": {
"processing_time_ms": 1720,
"model_version": "v1.0.0",
"detection_model": "indic-bert",
"engagement_model": "groq-llama-3.1-70b"
}
}
Response (Intelligence Extracted)
Response Example:
{
"status": "success",
"scam_detected": true,
"confidence": 0.97,
"language_detected": "en",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"engagement": {
"agent_response": "Thank you! I will send the money to scammer@paytm right away. Let me try now.",
"turn_count": 8,
"max_turns_reached": false,
"strategy": "probe_details",
"persona": "eager"
},
"extracted_intelligence": {
"upi_ids": ["scammer@paytm", "fraudster@ybl"],
"bank_accounts": ["1234567890123"],
"ifsc_codes": ["SBIN0001234"],
"phone_numbers": ["+919876543210", "9988776655"],
"phishing_links": ["http://fake-sbi-bank.com/verify"],
"extraction_confidence": 0.89
},
"conversation_history": [
{
"turn": 1,
"sender": "scammer",
"message": "You won a prize. Send OTP.",
"timestamp": "2026-01-26T10:30:00.000Z"
},
{
"turn": 1,
"sender": "agent",
"message": "Really? How do I claim it?",
"timestamp": "2026-01-26T10:30:02.000Z"
},
{
"turn": 2,
"sender": "scammer",
"message": "Pay ₹500 processing fee to scammer@paytm and call +919876543210",
"timestamp": "2026-01-26T10:30:15.000Z"
},
{
"turn": 2,
"sender": "agent",
"message": "Which UPI ID should I use? Can you confirm again?",
"timestamp": "2026-01-26T10:30:17.000Z"
},
{
"turn": 3,
"sender": "scammer",
"message": "Use scammer@paytm or fraudster@ybl. Also send to bank account 1234567890123, IFSC SBIN0001234. Visit http://fake-sbi-bank.com/verify",
"timestamp": "2026-01-26T10:30:30.000Z"
},
{
"turn": 3,
"sender": "agent",
"message": "Thank you! I will send the money to scammer@paytm right away.",
"timestamp": "2026-01-26T10:30:32.000Z"
}
],
"metadata": {
"processing_time_ms": 1950,
"model_version": "v1.0.0",
"detection_model": "indic-bert",
"engagement_model": "groq-llama-3.1-70b"
}
}
2. GET /honeypot/session/{session_id}
Description: Retrieve complete conversation history for a session.
Endpoint: GET /api/v1/honeypot/session/{session_id}
Request
Path Parameters:
{
"session_id": {
"type": "string",
"format": "uuid",
"required": true,
"description": "UUID of the session to retrieve"
}
}
Headers:
Accept: application/json
Request Example:
GET /api/v1/honeypot/session/550e8400-e29b-41d4-a716-446655440000
Accept: application/json
Response (Success)
Status Code: 200 OK
Body Schema:
{
"session_id": {
"type": "string",
"format": "uuid"
},
"language": {
"type": "string",
"enum": ["en", "hi", "hinglish"]
},
"persona": {
"type": "string",
"enum": ["elderly", "eager", "confused"]
},
"scam_confidence": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0
},
"turn_count": {
"type": "integer",
"minimum": 0
},
"conversation_history": {
"type": "array",
"items": {
"type": "object",
"properties": {
"turn": {"type": "integer"},
"sender": {"type": "string", "enum": ["scammer", "agent"]},
"message": {"type": "string"},
"timestamp": {"type": "string", "format": "date-time"}
}
}
},
"extracted_intelligence": {
"type": "object",
"properties": {
"upi_ids": {"type": "array", "items": {"type": "string"}},
"bank_accounts": {"type": "array", "items": {"type": "string"}},
"ifsc_codes": {"type": "array", "items": {"type": "string"}},
"phone_numbers": {"type": "array", "items": {"type": "string"}},
"phishing_links": {"type": "array", "items": {"type": "string"}},
"extraction_confidence": {"type": "number"}
}
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
Response Example:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"language": "en",
"persona": "elderly",
"scam_confidence": 0.94,
"turn_count": 5,
"conversation_history": [
{
"turn": 1,
"sender": "scammer",
"message": "You won 10 lakh!",
"timestamp": "2026-01-26T10:30:00.000Z"
},
{
"turn": 1,
"sender": "agent",
"message": "Really? How?",
"timestamp": "2026-01-26T10:30:02.000Z"
}
],
"extracted_intelligence": {
"upi_ids": ["test@paytm"],
"bank_accounts": [],
"ifsc_codes": [],
"phone_numbers": [],
"phishing_links": [],
"extraction_confidence": 0.65
},
"created_at": "2026-01-26T10:30:00.000Z",
"updated_at": "2026-01-26T10:35:15.000Z"
}
Response (Not Found)
Status Code: 404 Not Found
Body Schema:
{
"status": {
"type": "string",
"const": "error"
},
"error": {
"type": "object",
"properties": {
"code": {"type": "string", "const": "SESSION_NOT_FOUND"},
"message": {"type": "string"},
"session_id": {"type": "string"}
}
}
}
Response Example:
{
"status": "error",
"error": {
"code": "SESSION_NOT_FOUND",
"message": "No conversation found for the provided session ID",
"session_id": "invalid-uuid-12345"
}
}
3. GET /health
Description: Service health check for monitoring and load balancing.
Endpoint: GET /api/v1/health
Request
Headers:
Accept: application/json
Request Example:
GET /api/v1/health
Accept: application/json
Response (Healthy)
Status Code: 200 OK
Body Schema:
{
"status": {
"type": "string",
"enum": ["healthy", "degraded", "unhealthy"]
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+$",
"description": "Semantic version"
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"dependencies": {
"type": "object",
"properties": {
"groq_api": {
"type": "string",
"enum": ["online", "offline"]
},
"postgres": {
"type": "string",
"enum": ["online", "offline"]
},
"redis": {
"type": "string",
"enum": ["online", "offline"]
},
"models_loaded": {
"type": "boolean"
}
}
},
"uptime_seconds": {
"type": "integer",
"minimum": 0
}
}
Response Example (Healthy):
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2026-01-26T10:45:30.000Z",
"dependencies": {
"groq_api": "online",
"postgres": "online",
"redis": "online",
"models_loaded": true
},
"uptime_seconds": 86400
}
Response Example (Degraded):
{
"status": "degraded",
"version": "1.0.0",
"timestamp": "2026-01-26T10:45:30.000Z",
"dependencies": {
"groq_api": "online",
"postgres": "online",
"redis": "offline",
"models_loaded": true
},
"uptime_seconds": 86400
}
Response (Unhealthy)
Status Code: 503 Service Unavailable
Body Schema: Same as healthy response
Response Example:
{
"status": "unhealthy",
"version": "1.0.0",
"timestamp": "2026-01-26T10:45:30.000Z",
"dependencies": {
"groq_api": "offline",
"postgres": "offline",
"redis": "offline",
"models_loaded": false
},
"uptime_seconds": 1200
}
4. POST /honeypot/batch
Description: Process multiple messages in batch mode.
Endpoint: POST /api/v1/honeypot/batch
Request
Headers:
Content-Type: application/json
Accept: application/json
Body Schema:
{
"messages": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Client-provided message ID"
},
"message": {
"type": "string",
"minLength": 1,
"maxLength": 5000
},
"language": {
"type": "string",
"enum": ["auto", "en", "hi"],
"default": "auto"
}
},
"required": ["id", "message"]
}
}
}
Request Example:
{
"messages": [
{
"id": "msg-001",
"message": "You won 10 lakh! Send OTP.",
"language": "auto"
},
{
"id": "msg-002",
"message": "Hi, how are you doing?",
"language": "en"
},
{
"id": "msg-003",
"message": "आप गिरफ्तार हो जाएंगे। पैसे भेजें।",
"language": "hi"
}
]
}
Response
Status Code: 200 OK
Body Schema:
{
"status": {
"type": "string",
"const": "success"
},
"processed": {
"type": "integer",
"description": "Number of messages successfully processed"
},
"failed": {
"type": "integer",
"description": "Number of messages that failed processing"
},
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {"type": "string"},
"status": {"type": "string", "enum": ["success", "error"]},
"scam_detected": {"type": "boolean"},
"confidence": {"type": "number"},
"language_detected": {"type": "string"},
"error": {
"type": "object",
"properties": {
"code": {"type": "string"},
"message": {"type": "string"}
}
}
}
}
},
"processing_time_ms": {
"type": "integer"
}
}
Response Example:
{
"status": "success",
"processed": 3,
"failed": 0,
"results": [
{
"id": "msg-001",
"status": "success",
"scam_detected": true,
"confidence": 0.95,
"language_detected": "en"
},
{
"id": "msg-002",
"status": "success",
"scam_detected": false,
"confidence": 0.08,
"language_detected": "en"
},
{
"id": "msg-003",
"status": "success",
"scam_detected": true,
"confidence": 0.97,
"language_detected": "hi"
}
],
"processing_time_ms": 2350
}
ERROR HANDLING
Error Response Schema
All error responses follow this structure:
{
"status": {
"type": "string",
"const": "error"
},
"error": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Machine-readable error code"
},
"message": {
"type": "string",
"description": "Human-readable error message"
},
"details": {
"type": "object",
"description": "Additional error context"
}
},
"required": ["code", "message"]
}
}
Error Codes
| HTTP Status | Error Code | Description | Resolution |
|---|---|---|---|
| 400 | INVALID_REQUEST | Malformed request body | Check request schema |
| 400 | VALIDATION_ERROR | Field validation failed | Fix invalid fields |
| 400 | MESSAGE_TOO_LONG | Message exceeds 5000 chars | Shorten message |
| 400 | INVALID_SESSION_ID | Session ID format invalid | Provide valid UUID |
| 400 | INVALID_LANGUAGE | Unsupported language code | Use 'auto', 'en', or 'hi' |
| 404 | SESSION_NOT_FOUND | Session does not exist | Check session ID |
| 410 | SESSION_EXPIRED | Session expired (>1 hour old) | Start new session |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests | Wait and retry |
| 500 | INTERNAL_ERROR | Server-side error | Contact support |
| 502 | LLM_API_ERROR | Groq API unavailable | Retry with backoff |
| 503 | SERVICE_UNAVAILABLE | Service temporarily down | Check /health endpoint |
Error Response Examples
400 Bad Request - Validation Error:
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": {
"field": "message",
"issue": "Field is required but was not provided"
}
}
}
400 Bad Request - Message Too Long:
{
"status": "error",
"error": {
"code": "MESSAGE_TOO_LONG",
"message": "Message exceeds maximum length of 5000 characters",
"details": {
"max_length": 5000,
"actual_length": 6543
}
}
}
429 Rate Limit Exceeded:
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit of 100 requests per minute exceeded",
"details": {
"retry_after_seconds": 45,
"limit": 100,
"window_seconds": 60
}
}
}
500 Internal Server Error:
{
"status": "error",
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred while processing your request",
"details": {
"request_id": "req_a1b2c3d4e5",
"timestamp": "2026-01-26T10:50:00.000Z"
}
}
}
502 Bad Gateway - LLM API Error:
{
"status": "error",
"error": {
"code": "LLM_API_ERROR",
"message": "External LLM service (Groq) is currently unavailable",
"details": {
"service": "groq",
"retry_recommended": true,
"retry_after_seconds": 30
}
}
}
RATE LIMITING
Phase 1 Limits:
- 100 requests per minute per IP
- 1000 requests per hour per IP
- No authentication required
Response Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1706270400
Rate Limit Exceeded Response:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706270400
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 45 seconds."
}
}
CURL EXAMPLES
Example 1: Detect English Scam
curl -X POST https://api.scamshield.example.com/api/v1/honeypot/engage \
-H "Content-Type: application/json" \
-d '{
"message": "Congratulations! You won 10 lakh rupees. Send OTP to claim.",
"language": "auto"
}'
Example 2: Continue Conversation
curl -X POST https://api.scamshield.example.com/api/v1/honeypot/engage \
-H "Content-Type: application/json" \
-d '{
"message": "Send money to scammer@paytm immediately!",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"language": "en"
}'
Example 3: Detect Hindi Scam
curl -X POST https://api.scamshield.example.com/api/v1/honeypot/engage \
-H "Content-Type: application/json" \
-d '{
"message": "आप गिरफ्तार हो जाएंगे। तुरंत 10000 रुपये भेजें।",
"language": "hi"
}'
Example 4: Retrieve Session
curl -X GET https://api.scamshield.example.com/api/v1/honeypot/session/550e8400-e29b-41d4-a716-446655440000 \
-H "Accept: application/json"
Example 5: Health Check
curl -X GET https://api.scamshield.example.com/api/v1/health \
-H "Accept: application/json"
Example 6: Batch Processing
curl -X POST https://api.scamshield.example.com/api/v1/honeypot/batch \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"id": "1", "message": "You won a prize!"},
{"id": "2", "message": "Hi, how are you?"}
]
}'
OPENAPI SPECIFICATION
OpenAPI Version: 3.0.3
Complete OpenAPI YAML specification available at:
https://api.scamshield.example.com/openapi.yaml
openapi: 3.0.3
info:
title: ScamShield AI API
version: 1.0.0
description: Agentic Honeypot System for Scam Detection & Intelligence Extraction
servers:
- url: https://api.scamshield.example.com/api/v1
description: Production server
paths:
/honeypot/engage:
post:
summary: Detect and engage with scam messages
operationId: engageHoneypot
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EngageRequest'
responses:
'200':
description: Successful response
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ScamDetectedResponse'
- $ref: '#/components/schemas/NotScamResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/health:
get:
summary: Health check
operationId: healthCheck
responses:
'200':
description: Service is healthy
content:
application/json:
schema:
$ref: '#/components/schemas/HealthResponse'
components:
schemas:
EngageRequest:
type: object
required:
- message
properties:
message:
type: string
minLength: 1
maxLength: 5000
session_id:
type: string
format: uuid
language:
type: string
enum: [auto, en, hi]
default: auto
Document Status: Production Ready
Next Steps: Implement API endpoints as per this contract
Testing: Refer to EVAL_SPEC.md for API testing framework