Complete REST API documentation for Agent-Loop.
The fastest way to explore the API is to use the interactive Swagger UI:
- Start the API server:
uv run python api.py - Open http://localhost:8000/docs
- Try out endpoints directly in your browser
http://localhost:8000/api/v1
When api_keys is enabled in config.json, include your API key in the header:
curl -H "X-API-Key: your-api-key" http://localhost:8000/api/v1/tasksGET /health
Check API server health status.
curl http://localhost:8000/healthResponse:
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2026-03-08T10:00:00Z"
}GET /tasks
List all tasks with optional filtering.
curl http://localhost:8000/api/v1/tasksQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status (pending, in_progress, completed, failed) |
limit |
int | Maximum number of tasks to return |
offset |
int | Offset for pagination |
Response:
{
"tasks": [
{
"id": "feat-001",
"name": "Task Name",
"description": "Task description",
"priority": 1,
"status": "pending",
"passes": false,
"created_at": "2026-03-08",
"updated_at": "2026-03-08"
}
],
"total": 10
}GET /tasks/{task_id}
Get a specific task by ID.
curl http://localhost:8000/api/v1/tasks/feat-001Response:
{
"id": "feat-001",
"name": "Task Name",
"description": "Task description",
"priority": 1,
"status": "pending",
"passes": false,
"verify_command": "cat README.md",
"context_files": ["CLAUDE.md"],
"created_at": "2026-03-08",
"updated_at": "2026-03-08"
}POST /tasks
Create a new task.
curl -X POST http://localhost:8000/api/v1/tasks \
-H "Content-Type: application/json" \
-d '{
"name": "New Task",
"description": "Task description",
"priority": 1
}'Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Task name |
description |
string | No | Task description |
priority |
int | No | Priority (1 = highest, default: 3) |
verify_command |
string | No | Verification command |
context_files |
string[] | No | Files to include in context |
Response:
{
"id": "feat-002",
"name": "New Task",
"description": "Task description",
"priority": 1,
"status": "pending",
"passes": false,
"created_at": "2026-03-08",
"updated_at": "2026-03-08"
}PATCH /tasks/{task_id}
Update an existing task.
curl -X PATCH http://localhost:8000/api/v1/tasks/feat-001 \
-H "Content-Type: application/json" \
-d '{
"status": "completed",
"passes": true
}'Request Body:
| Field | Type | Description |
|---|---|---|
name |
string | Task name |
description |
string | Task description |
priority |
int | Priority (1-5) |
status |
string | Status (pending, in_progress, completed, failed) |
passes |
boolean | Pass status |
DELETE /tasks/{task_id}
Delete a task.
curl -X DELETE http://localhost:8000/api/v1/tasks/feat-001POST /run
Start agent execution.
curl -X POST http://localhost:8000/api/v1/run \
-H "Content-Type: application/json" \
-d '{
"iterations": 3
}'Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
iterations |
int | No | Number of iterations (default: 10) |
task_id |
string | No | Specific task ID to run |
Response:
{
"session_id": "sess-abc123",
"status": "started",
"iterations": 3,
"message": "Agent execution started"
}GET /status
Get current project status.
curl http://localhost:8000/api/v1/statusResponse:
{
"project_name": "my-project",
"current_task": "feat-001",
"total_tasks": 10,
"pending_tasks": 5,
"completed_tasks": 3,
"failed_tasks": 2,
"last_run": "2026-03-08T10:00:00Z"
}GET /session/history
Get session history.
curl http://localhost:8000/api/v1/session/historyQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
limit |
int | Number of sessions to return |
offset |
int | Offset for pagination |
Response:
{
"sessions": [
{
"session_id": "sess-abc123",
"started_at": "2026-03-08T10:00:00Z",
"ended_at": "2026-03-08T10:30:00Z",
"iterations": 5,
"tasks_completed": 3,
"status": "completed"
}
],
"total": 10
}POST /webhook/test
Test webhook configuration.
curl -X POST http://localhost:8000/api/v1/webhook/test \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"secret": "your-secret"
}'POST /email/test
Test email configuration.
curl -X POST http://localhost:8000/api/v1/email/test \
-H "Content-Type: application/json" \
-d '{
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"smtp_user": "your-email@gmail.com",
"smtp_password": "app-password",
"to_emails": ["test@example.com"]
}'GET /metrics
Get Prometheus metrics.
curl http://localhost:8000/metricsWebSocket /ws/stream
Real-time agent output streaming.
const ws = new WebSocket('ws://localhost:8000/api/v1/ws/stream');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data.type, data.content);
};All endpoints return standard HTTP status codes:
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request |
| 401 | Unauthorized |
| 404 | Not Found |
| 429 | Rate Limited |
| 500 | Internal Server Error |
Error response format:
{
"error": "Error message",
"code": "ERROR_CODE",
"details": {}
}When rate limiting is enabled, responses include headers:
X-RateLimit-Limit: Maximum requests per windowX-RateLimit-Remaining: Requests remaining in windowX-RateLimit-Reset: Unix timestamp when limit resets