Complete reference for the Taskdog REST API.
The Taskdog API server provides a comprehensive REST API built with FastAPI. All endpoints return JSON and follow REST conventions.
taskdog-server # Default: http://127.0.0.1:8000
taskdog-server --host 0.0.0.0 # Bind to all interfaces
taskdog-server --port 3000 # Custom port
taskdog-server --reload # Auto-reload for developmentOnce the server is running, access interactive API documentation:
- Swagger UI:
http://localhost:8000/docs- Interactive API explorer - ReDoc:
http://localhost:8000/redoc- Alternative documentation format
Taskdog API supports optional API key authentication. When enabled, all HTTP endpoints and WebSocket connections require authentication.
Authentication is configured in server.toml:
# ~/.config/taskdog/server.toml
[auth]
enabled = true # Enable/disable authentication (default: true)
[[auth.api_keys]]
key = "your-secret-key"
name = "my-tui" # Friendly name (shown in WebSocket broadcasts)See examples/server.toml for a complete example.
Send API key via X-Api-Key header:
curl -H "X-Api-Key: your-secret-key" http://localhost:8000/api/v1/tasks/Send API key via query parameter:
const ws = new WebSocket('ws://localhost:8000/ws?token=your-secret-key');Configure API key in cli.toml or environment variable:
# ~/.config/taskdog/cli.toml
[api]
api_key = "your-secret-key"export TASKDOG_API_KEY=your-secret-keyFor local development or trusted networks, you can disable authentication:
# ~/.config/taskdog/server.toml
[auth]
enabled = falseWarning: Only disable authentication in trusted environments.
Default base URL: http://127.0.0.1:8000
All API endpoints are prefixed with /api/v1/ unless otherwise noted.
{
"id": 1,
"name": "Task name",
"status": "pending",
...
}{
"detail": "Error message describing what went wrong"
}HTTP status codes follow REST conventions:
200- Success201- Created204- No Content (successful deletion)400- Bad Request (validation error)404- Not Found422- Unprocessable Entity (validation error)500- Internal Server Error
Interactive Swagger UI documentation
Alternative ReDoc documentation
Health check endpoint
Response:
{
"status": "ok"
}Base path: /api/v1/tasks/
List tasks with filtering
Query Parameters:
status(string, optional) - Filter by status: pending, in_progress, completed, canceledtags(string[], optional) - Filter by tags (OR logic)start_date(string, optional) - Filter by planned start date (YYYY-MM-DD)end_date(string, optional) - Filter by planned end date (YYYY-MM-DD)include_archived(boolean, optional) - Include archived tasks (default: false)sort_by(string, optional) - Sort field: id, priority, deadline, name, status, planned_startreverse(boolean, optional) - Reverse sort order (default: false)
Response:
[
{
"id": 1,
"name": "Task name",
"priority": 100,
"status": "pending",
"planned_start": "2025-10-22T09:00:00",
"planned_end": "2025-10-22T17:00:00",
"deadline": "2025-10-25T18:00:00",
"estimated_duration": 16.0,
"actual_start": null,
"actual_end": null,
"is_fixed": false,
"depends_on": [],
"daily_allocations": {},
"tags": ["backend", "api"],
"is_archived": false
}
]Create a new task
Request Body:
{
"name": "Task name",
"priority": 100,
"estimated_duration": 16.0,
"deadline": "2025-10-25T18:00:00",
"is_fixed": false,
"depends_on": [1, 2],
"tags": ["backend"]
}Required fields: name
Response: 201 Created with task object
Get task details
Response: Task object (same structure as list)
Update task fields
Request Body:
{
"name": "Updated name",
"priority": 150,
"deadline": "2025-10-30T18:00:00"
}Response: Updated task object
Delete task
Query Parameters:
hard(boolean, optional) - Permanent deletion if true, soft delete if false (default: false)
Response: 204 No Content
Base path: /api/v1/tasks/{task_id}/
Start a task
Records actual start time and changes status to IN_PROGRESS.
Response: Updated task object
Complete a task
Records actual end time and changes status to COMPLETED.
Response: Updated task object
Pause a task
Resets status to PENDING and clears timestamps.
Response: Updated task object
Cancel a task
Changes status to CANCELED.
Response: Updated task object
Reopen a completed or canceled task
Resets status to PENDING.
Response: Updated task object
Archive a task (soft delete)
Sets is_archived to true. Task can be restored later.
Response: 204 No Content
Restore an archived task
Sets is_archived to false.
Response: Updated task object
Base path: /api/v1/tasks/{task_id}/
Add a dependency
Request Body:
{
"depends_on_id": 2
}Creates a dependency: task {task_id} depends on task {depends_on_id}.
Response: Updated task object
Error: 400 if circular dependency detected
Remove a dependency
Response: Updated task object
Set task tags (replaces existing)
Request Body:
{
"tags": ["backend", "api", "urgent"]
}Response: Updated task object
Base path: /api/v1/tasks/{task_id}/notes/
Get task notes
Response:
{
"content": "# Notes\n\nMarkdown content here..."
}Update task notes
Request Body:
{
"content": "# Updated Notes\n\nNew markdown content..."
}Response: 204 No Content
Delete task notes
Response: 204 No Content
Base path: /api/v1/
Get task statistics
Query Parameters:
period(string, optional) - all, 7d, 30d (default: all)focus(string, optional) - all, basic, time, estimation, deadline, priority, trends (default: all)
Response:
{
"total_tasks": 10,
"by_status": {
"pending": 5,
"in_progress": 2,
"completed": 3,
"canceled": 0
},
"average_duration": 12.5,
...
}Get Gantt chart data
Query Parameters:
- Same filtering options as GET /api/v1/tasks/
start_date(string, optional) - Chart start dateend_date(string, optional) - Chart end date
Response:
{
"tasks": [...],
"date_range": {
"start": "2025-10-20",
"end": "2025-10-30"
},
"workload_summary": {
"2025-10-22": 8.0,
"2025-10-23": 6.5
}
}Get tag statistics
Response:
{
"backend": 5,
"api": 3,
"urgent": 1
}Base path: /api/v1/
Run schedule optimization
Request Body:
{
"start_date": "2025-10-22",
"max_hours_per_day": 8.0,
"algorithm": "greedy",
"force_override": false
}Fields:
algorithm- Algorithm to use (required)max_hours_per_day- Daily hour limit (required)start_date- Optimization start date (optional, default: today)force_override- Whether to override existing schedules for non-fixed tasks (optional, default: true)
Available algorithms:
greedy- Schedule highest priority tasks firstbalanced- Distribute workload evenlybackward- Schedule from deadline backwardspriority_first- Strict priority orderingearliest_deadline- Deadline-based schedulinground_robin- Minimize context switchingdependency_aware- Prioritize blocking tasksgenetic- Genetic algorithm optimizationmonte_carlo- Monte Carlo simulation
Response:
{
"scheduled_count": 8,
"failed_count": 0,
"workload_summary": {
"2025-10-22": 8.0,
"2025-10-23": 6.5
},
"failures": []
}List available optimization algorithms
Response:
{
"algorithms": [
{
"name": "greedy",
"description": "Schedule highest priority tasks first"
},
...
]
}Real-time task notifications
Connect to WebSocket endpoint for real-time updates:
// With authentication
const ws = new WebSocket('ws://localhost:8000/ws?token=your-api-key');
// Without authentication (if auth.enabled = false)
const ws = new WebSocket('ws://localhost:8000/ws');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Event:', data.type); // task_created, task_updated, task_deleted, task_status_changed
console.log('Task ID:', data.task_id);
console.log('Source User:', data.source_user_name); // Who triggered the event
};Event types:
task_created- New task createdtask_updated- Task fields updatedtask_deleted- Task deletedtask_status_changed- Task status changedschedule_optimized- Schedule optimization completed
Event payload:
All events include source_user_name to identify who triggered the event (from API key name).
# 1. Create task
curl -X POST http://localhost:8000/api/v1/tasks/ \
-H "Content-Type: application/json" \
-d '{
"name": "Implement feature X",
"priority": 150,
"estimated_duration": 16.0,
"deadline": "2025-10-30T18:00:00",
"tags": ["backend", "feature"]
}'
# 2. Add dependency
curl -X POST http://localhost:8000/api/v1/tasks/2/dependencies \
-H "Content-Type: application/json" \
-d '{"depends_on_id": 1}'
# 3. Run optimization
curl -X POST http://localhost:8000/api/v1/optimize \
-H "Content-Type: application/json" \
-d '{
"start_date": "2025-10-22",
"max_hours_per_day": 8.0,
"algorithm": "balanced"
}'
# 4. Start task
curl -X POST http://localhost:8000/api/v1/tasks/1/start
# 5. Complete task
curl -X POST http://localhost:8000/api/v1/tasks/1/complete# Get pending tasks with "backend" tag
curl "http://localhost:8000/api/v1/tasks/?status=pending&tags=backend"
# Get tasks in date range
curl "http://localhost:8000/api/v1/tasks/?start_date=2025-10-20&end_date=2025-10-30"
# Get tasks sorted by priority (descending)
curl "http://localhost:8000/api/v1/tasks/?sort_by=priority&reverse=true"
# Include archived tasks
curl "http://localhost:8000/api/v1/tasks/?include_archived=true"# Get multiple tasks and perform operations
TASK_IDS=(1 2 3)
for id in "${TASK_IDS[@]}"; do
curl -X POST "http://localhost:8000/api/v1/tasks/$id/start"
done404 Not Found
{
"detail": "Task with ID 999 not found"
}400 Bad Request
{
"detail": "Cannot start task: Task is already completed"
}422 Validation Error
{
"detail": [
{
"loc": ["body", "priority"],
"msg": "value must be greater than 0",
"type": "value_error"
}
]
}- Check task existence before performing operations
- Validate status before state transitions
- Handle circular dependencies when adding dependencies
- Use appropriate HTTP methods (GET for reads, POST/PATCH for writes, DELETE for removal)
- Include error handling in client code
- Use query parameters for filtering and sorting instead of client-side filtering
- Leverage WebSocket for real-time updates in interactive applications
Currently, Taskdog API does not implement rate limiting as it's designed for local use. For production deployments, consider adding rate limiting middleware.