Skip to content

dotbinio/dotbintask-api

Repository files navigation

Taskwarrior API Server

⚠️ UNDER CONSTRUCTION: This project is currently in active development and is not ready for production use. APIs may change without notice. Use at your own risk.

A headless REST API server for Taskwarrior, providing a clean HTTP interface to interact with your tasks programmatically.

Overview

This server acts as a bridge between Taskwarrior's powerful CLI and modern applications, allowing you to:

  • Build web, mobile, or desktop UIs for Taskwarrior
  • Integrate Taskwarrior with other tools and services
  • Access your tasks from anywhere via HTTP
  • Keep Taskwarrior as the single source of truth (no database duplication)

Key Features

  • CLI-Only Integration: Uses Taskwarrior CLI exclusively - no direct file manipulation
  • RESTful API: Clean, predictable HTTP endpoints
  • Token Authentication: Simple bearer token authentication
  • Sync-Friendly: Compatible with Taskwarrior sync or file syncing (Syncthing, etc.)
  • No State Duplication: All data lives in Taskwarrior

Installation

Prerequisites

  • Go 1.21 or higher
  • Taskwarrior installed and configured (task command available)

Quick Start

# Clone the repository
git clone https://github.com/dotbinio/taskwarrior-api.git
cd taskwarrior-api

# Install dependencies
make install

# Set required environment variable
export TW_API_TOKENS="your-secret-token"

# Build and run
make build
./bin/taskwarrior-api

The server will start on http://localhost:8080

Access Swagger UI: Open http://localhost:8080/swagger/index.html in your browser

Embedded Example UI

A read-only web UI is available for viewing tasks and reports. This is intended as an example/development tool and is enabled by default.

Accessing the UI

Simply start the server and open http://localhost:8080/ in your browser.

Disabling the UI

If you want to disable the UI (e.g., for production):

export TW_API_ENABLE_UI=false
./bin/taskwarrior-api

Features

  • Read-only interface for viewing tasks
  • Dynamic report viewer using Taskwarrior's report configurations
  • Displays tasks using each report's configured columns and labels
  • Clean, minimal styling with Pico CSS
  • No build step required (all dependencies via CDN)

Security Notes

  • Enabled by default - Can be disabled via TW_API_ENABLE_UI=false
  • Requires valid API token (stored in browser session only)
  • Read-only - cannot create, modify, or delete tasks
  • Recommended for development and internal use
  • Consider using a reverse proxy with additional authentication for external access

Building from Source

# Clone the repository
git clone https://github.com/dotbinio/taskwarrior-api.git
cd taskwarrior-api

# Install dependencies
make install

# Build the binary
make build

# The binary will be available at ./bin/taskwarrior-api

Running

# Run directly with Go
make run

# Or run the built binary
./bin/taskwarrior-api

Docker Deployment

Build and Push

# Build
docker build -t taskwarrior-api:latest .

# Tag for your registry
docker tag taskwarrior-api:latest your-registry/taskwarrior-api:latest

# Push
docker push your-registry/taskwarrior-api:latest

Or use the Makefile:

make docker-build
make docker-push  # Shows push instructions

Kubernetes Deployment

Complete Kubernetes manifests are provided in k8s/deployment.yaml.

Quick Deploy

# 1. Create secret with your tokens
kubectl create secret generic taskwarrior-api-secret \
  --from-literal=tokens="your-token-1,token-2" \
  -n taskwarrior

# 2. Update image in k8s/deployment.yaml
# 3. Deploy
kubectl apply -f k8s/deployment.yaml

# 4. Port forward to test
kubectl port-forward -n taskwarrior svc/taskwarrior-api 8080:8080

Or use the Makefile:

make k8s-deploy
make k8s-port-forward

See KUBERNETES.md for complete deployment guide including:

  • Image registry setup
  • Ingress configuration
  • Monitoring and scaling
  • Data persistence options
  • Troubleshooting

Configuration

The server is configured entirely through environment variables.

Required Environment Variables

Variable Description Example
TW_API_TOKENS Comma-separated list of valid auth tokens token1,token2,token3

Optional Environment Variables

Variable Description Default
TW_API_HOST Server host address 0.0.0.0
TW_API_PORT Server port 8080
TW_API_ENABLE_UI Enable embedded example UI true
TW_DATA_LOCATION Path to Taskwarrior data directory ~/.task
TW_API_LOG_LEVEL Log level (debug, info, warn, error) info
TW_API_CORS_ENABLED Enable CORS true
TW_API_CORS_ORIGINS Comma-separated list of allowed origins http://localhost:3000

Example Configuration

export TW_API_TOKENS="my-secret-token-123,another-token-456"
export TW_API_PORT=8080
export TW_DATA_LOCATION="~/.task"
export TW_API_LOG_LEVEL="info"
export TW_API_CORS_ORIGINS="http://localhost:3000,https://mytasks.example.com"

./bin/taskwarrior-api

Or create a .env file (see env.example for template) and source it:

cp env.example .env
# Edit .env with your values
source .env
./bin/taskwarrior-api

API Documentation

All API endpoints require authentication via Bearer token.

Interactive API Documentation (Swagger UI)

Once the server is running, you can access the interactive Swagger UI at:

http://localhost:8080/swagger/index.html

This provides a web interface to:

  • Browse all available endpoints
  • View request/response schemas
  • Test API calls directly from your browser
  • See example requests and responses

Authentication

Include the token in the Authorization header:

curl -H "Authorization: Bearer your-token-here" http://localhost:8080/api/v1/tasks

Endpoints

Health Check

No authentication required

GET /health

Response:

{
  "status": "ok",
  "service": "taskwarrior-api"
}

Tasks

List Tasks

GET /api/v1/tasks

Query parameters:

  • status (default: pending) - Filter by status (pending, completed, deleted, waiting)
  • project - Filter by project name
  • tags - Filter by tags (can be specified multiple times)

Example:

curl -H "Authorization: Bearer token" \
  "http://localhost:8080/api/v1/tasks?status=pending&project=work"

Response:

{
  "tasks": [
    {
      "uuid": "a360fc44-315c-4366-b70c-ea7e7520b749",
      "description": "Complete project documentation",
      "status": "pending",
      "project": "work",
      "tags": ["documentation"],
      "urgency": 8.9,
      "entry": "2026-01-01T10:00:00Z"
    }
  ],
  "count": 1
}

Get Task

GET /api/v1/tasks/:uuid

Example:

curl -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749

Create Task

POST /api/v1/tasks

Request body:

{
  "description": "New task",
  "project": "work",
  "tags": ["important", "urgent"],
  "priority": "H",
  "due": "2026-01-15T00:00:00Z"
}

Required fields:

  • description (string)

Optional fields:

  • project (string)
  • tags (array of strings)
  • priority (string: H, M, L)
  • due (ISO 8601 datetime)
  • wait (ISO 8601 datetime)
  • scheduled (ISO 8601 datetime)
  • depends (array of UUIDs)
  • recur (string: daily, weekly, monthly, etc.)

Example:

curl -X POST -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d '{"description":"Write API documentation","project":"docs","tags":["writing"]}' \
  http://localhost:8080/api/v1/tasks

Update Task

PATCH /api/v1/tasks/:uuid

Request body (all fields optional):

{
  "description": "Updated description",
  "project": "work",
  "priority": "H",
  "due": "2026-01-20T00:00:00Z"
}

Example:

curl -X PATCH -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d '{"priority":"H","project":"urgent"}' \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749

Delete Task

DELETE /api/v1/tasks/:uuid

Example:

curl -X DELETE -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749

Mark Task as Done

POST /api/v1/tasks/:uuid/done

Example:

curl -X POST -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749/done

Start Task

POST /api/v1/tasks/:uuid/start

Example:

curl -X POST -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749/start

Stop Task

POST /api/v1/tasks/:uuid/stop

Example:

curl -X POST -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/tasks/a360fc44-315c-4366-b70c-ea7e7520b749/stop

Reports

Next Report

Get pending tasks sorted by urgency.

GET /api/v1/reports/next

Active Report

Get currently active (started) tasks.

GET /api/v1/reports/active

Completed Report

Get completed tasks.

GET /api/v1/reports/completed

Waiting Report

Get tasks in waiting state.

GET /api/v1/reports/waiting

All Report

Get all tasks regardless of status.

GET /api/v1/reports/all

Example:

curl -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/reports/next

Projects

List Projects

Get all projects with task counts.

GET /api/v1/projects

Response:

{
  "projects": [
    {
      "name": "work",
      "count": 5
    },
    {
      "name": "personal",
      "count": 3
    }
  ],
  "count": 2
}

Get Project Tasks

Get all tasks for a specific project.

GET /api/v1/projects/:name/tasks

Example:

curl -H "Authorization: Bearer token" \
  http://localhost:8080/api/v1/projects/work/tasks

Error Handling

All errors follow a consistent format:

{
  "error": "Human readable error message",
  "code": "ERROR_CODE"
}

Common error codes:

  • MISSING_AUTH_HEADER - No Authorization header provided
  • INVALID_AUTH_FORMAT - Authorization header format is incorrect
  • INVALID_TOKEN - Token is not valid
  • INVALID_UUID - Task UUID format is invalid
  • TASK_NOT_FOUND - Task with given UUID doesn't exist
  • INVALID_REQUEST - Request body is malformed

HTTP status codes:

  • 200 - Success
  • 201 - Created
  • 400 - Bad Request
  • 401 - Unauthorized
  • 404 - Not Found
  • 500 - Internal Server Error

Development

Running Tests

make test

Running with Hot Reload

Install air:

go install github.com/air-verse/air@latest

Then run:

make dev

Code Formatting

make fmt

Architecture

┌─────────────┐
│   Client    │
│ (Web/Mobile)│
└──────┬──────┘
       │ HTTP/REST
       │
┌──────▼──────────────┐
│   API Server (Go)   │
│  - Auth Middleware  │
│  - Route Handlers   │
└──────┬──────────────┘
       │ CLI Commands
       │
┌──────▼──────────────┐
│  Taskwarrior CLI    │
│   - task export     │
│   - task add        │
│   - task modify     │
└──────┬──────────────┘
       │ File I/O
       │
┌──────▼──────────────┐
│   .task/ Files      │
│  (Single Source of  │
│      Truth)         │
└─────────────────────┘

Design Principles

  1. Taskwarrior is the backend - No database, no state duplication
  2. CLI-only integration - Never touch .task/ files directly
  3. Strict separation - Server and UI are completely independent
  4. Safe by default - No arbitrary command execution
  5. Local-first - Works with existing Taskwarrior + sync setups

Security Considerations

  • Token Security: Use strong, randomly generated tokens. Keep them secret.
  • HTTPS: Always use HTTPS in production to protect tokens in transit.
  • Network Access: Consider running behind a reverse proxy (nginx, Caddy) with additional security layers.
  • Local Use: For maximum security, bind to 127.0.0.1 and use SSH tunneling for remote access.

Use Cases

  • Web UI: Build a modern web interface for Taskwarrior
  • Mobile Apps: Create native mobile apps with offline sync
  • Automation: Integrate with tools like Zapier, IFTTT, or custom scripts
  • Team Dashboards: Display team tasks on shared screens
  • Voice Assistants: Add tasks via Alexa, Google Home, etc.

Production Deployment

This project includes production-ready deployment configurations:

  • Docker: Multi-stage build with security best practices
  • Docker Compose: Ready-to-use orchestration
  • CI/CD: GitHub Actions workflows for testing and releases
  • Systemd: Service configuration for Linux servers
  • Reverse Proxy: Examples for Nginx and Caddy

See DEPLOYMENT.md for detailed deployment guides, security considerations, monitoring, and troubleshooting.

Quick Deploy with Docker

export TW_API_TOKENS="$(openssl rand -hex 32)"
docker-compose up -d

Access at: http://localhost:8080/swagger/index.html

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

MIT License - see LICENSE file for details.

Acknowledgments

  • Taskwarrior - The amazing task management tool this API wraps

About

HTTP Apiserver for taskwarrior. Use this to build your own UI for taskwarrior

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages