Admin Endpoints
All admin endpoints require x-user-role: admin (automatically injected from JWT when the authenticated user has the admin role).
GET /admin/api/stats
Dashboard statistics.
Response 200:
{
"data": {
"models": [{ "model": "Product", "table": "products", "count": 42 }],
"users": { "count": 15 },
"files": { "count": 8, "storageMB": 12.5 },
"uptime": 3600,
"ai": {
"connectedLLMs": 2,
"enabledLLMs": 2,
"providers": [{ "id": "openai", "label": "OpenAI", "hasKey": true }],
"agentsCount": 3,
"usage": {
"totalRequests": 120,
"totalInputTokens": 45000,
"totalOutputTokens": 12000,
"byProvider": {
"openai": { "requests": 80, "inputTokens": 30000, "outputTokens": 8000 }
}
}
}
}
}
GET /admin/api/schema
Get all model definitions.
Response 200:
{
"data": {
"Product": {
"tableName": "products",
"fields": [
{ "name": "name", "type": "string", "required": true },
{ "name": "price", "type": "number", "required": false }
]
}
}
}
POST /admin/api/schema
Create a new model. Routes become active immediately — no restart required.
Request Body:
{
"name": "Product",
"fields": {
"name": { "type": "string", "required": true },
"price": "number",
"in_stock": "boolean"
}
}
Response 201:
{
"data": { "name": "Product", "tableName": "products", "fields": [] },
"message": "Model \"Product\" is live. Routes /products are active now."
}
Errors:
| Code | Reason |
|---|---|
400 | Missing name or fields, reserved name used |
409 | Model with that name already exists |
DELETE /admin/api/schema/:name
Remove a model. Routes are deactivated immediately; the DB table is preserved.
Response: 204 No Content
Errors:
| Code | Reason |
|---|---|
400 | Attempt to delete a system model (e.g. User) |
404 | Model not found |
GET /admin/api/logs
Retrieve in-memory server logs.
Query Parameters:
| Parameter | Description |
|---|---|
after | Unix timestamp — only return logs after this time |
level | Filter by level: info, warn, error, debug |
Response 200:
{
"logs": [
{ "ts": 1741258800000, "level": "info", "msg": "GET /api/products 200 12ms" }
]
}
GET /admin/api/env
Read current environment/config values.
Response 200:
{
"data": {
"JWT_SECRET": "***",
"ROTIFEX_PORT": "3000",
"ROTIFEX_CORS_ORIGIN": "*"
}
}
POST /admin/api/env
Write environment variables to .env. Restart required for changes to take effect.
Request Body:
{
"vars": {
"ROTIFEX_PORT": "4000",
"ROTIFEX_CORS_ORIGIN": "https://myapp.com"
}
}
Response 200:
{
"message": "Environment saved. Restart the server for changes to take effect."
}
GET /admin/api/ai/providers
Get all AI providers with masked API keys.
Response 200:
{
"data": [
{
"id": "openai",
"label": "OpenAI",
"enabled": true,
"apiKey": "***abcd",
"hasKey": true,
"models": ["gpt-4o", "gpt-4o-mini"],
"defaultModel": "gpt-4o"
}
]
}
PUT /admin/api/ai/providers/:id
Update a provider's configuration.
Request Body:
{
"enabled": true,
"apiKey": "sk-...",
"defaultModel": "gpt-4o-mini"
}
Response 200:
{
"data": { "id": "openai", "label": "OpenAI", "enabled": true, "hasKey": true },
"message": "Provider \"openai\" updated."
}
Agent Admin Endpoints
GET /admin/api/agents
List all agents with full detail (including system prompt).
GET /admin/api/agents/:id
Get a single agent by ID.
POST /admin/api/agents
Create an agent.
Request Body:
{
"name": "Research Assistant",
"description": "Searches and summarizes web content",
"provider": "openai",
"model": "gpt-4o",
"systemPrompt": "You are a research assistant. Use tools to answer questions accurately.",
"tools": ["web_search", "calculate"],
"temperature": 0.7,
"maxTokens": 2048,
"maxIterations": 10
}
Response 201:
{
"data": { "id": "uuid", "name": "Research Assistant" },
"message": "Agent \"Research Assistant\" created."
}
PUT /admin/api/agents/:id
Update an agent (partial patch). Same body shape as POST.
Response 200:
{
"data": { "id": "uuid", "name": "Research Assistant" },
"message": "Agent \"Research Assistant\" updated."
}
DELETE /admin/api/agents/:id
Delete an agent permanently.
Response: 204 No Content