Service API
The WackyTracky backend exposes a Connect RPC API. The web app uses this API for all operations (lists, tasks, search, metadata, and more). You can call it from scripts, other applications, or a CLI using HTTP and JSON.
Base URL
When the server is running (e.g. on port 8080), the API base URL is:
http://<host>:<port>/api
Example: http://localhost:8080/api
Each RPC has a procedure path under this base. The full URL for a procedure is:
<base>/wackytracky.clientapi.v1.WackyTrackyClientService/<MethodName>
Protocol
The service uses the Connect protocol (HTTP/JSON):
-
Method:
POST -
Request:
Content-Type: application/json, body is a JSON object with the request message fields (empty{}for empty requests). -
Response:
Content-Type: application/json, body is a JSON object with the response message fields. -
Errors: On failure, the server returns an appropriate HTTP status (e.g. 4xx/5xx) and a Connect error payload in JSON.
Authentication uses a session cookie (wacky-tracky-sid) for the web
UI, or Authorization: Bearer <api-key> for scripts. See
Authentication.
Quick start
Version (no arguments)
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/Version' \
-H "Content-Type: application/json" \
-d '{}'
Example response:
{"version":"1.9.0","commit":"abc123","date":"2025-01-15T12:00:00Z"}
Get lists
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/GetLists' \
-H "Content-Type: application/json" \
-d '{}'
Example response:
{"lists":[{"id":"list-id-1","title":"Inbox","countItems":5}]}
Create a task
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/CreateTask' \
-H "Content-Type: application/json" \
-d '{"content":"Buy milk #errands @home","parentListId":"<list-id>"}'
Use the list ID from GetLists. Omit parentListId to use the default
list (implementation-dependent). Use parentTaskId to create a subtask.
Search tasks
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/SearchTasks' \
-H "Content-Type: application/json" \
-d '{"query":"#work -#done"}'
Query syntax is backend-dependent; the todo.txt backend supports plain
terms, #tag, @context, and -term to exclude. See
Search (SearchTasks) for details.
Reference
The full list of RPCs and request/response message types is in the API reference.
Machine-readable spec (OpenAPI)
A generated OpenAPI 3.1 description of every procedure and message is
available at openapi.yaml. When the server is
running, the same spec is also served at GET /openapi on your
instance (e.g. http://localhost:8080/openapi). It is produced from the
Protocol Buffers definition, so it always matches the running API. Use
it to:
-
Feed the API to tools like Swagger UI, Redoc, or Postman.
-
Let an LLM or code generator discover endpoints, request/response shapes, and field types without reading prose.
Regenerate it with make in the protocol/ directory.
LLM discovery (llms.txt)
Running servers expose GET /llms.txt
(e.g. http://localhost:8080/llms.txt) with a short guide for LLMs and
automation: where to find the OpenAPI spec, how to call the HTTP API,
and how to use the MCP server.
MCP server (for LLM assistants)
To let an LLM assistant (Claude Desktop, Cursor, etc.) read and manage
your tasks directly, WackyTracky exposes an MCP server.
When the HTTP server is running, connect at /mcp (Streamable HTTP).
For local subprocess clients, use wt mcp over stdio.
Code generation
The API is defined with Protocol Buffers in
protocol/wacky-tracky/clientapi/v1/wt.proto. You can generate client
code using:
-
Connect: connectrpc.com (Go, TypeScript/JavaScript, etc.)
-
buf: buf.build with the Connect plugins
The web frontend uses the generated Connect-Web client; the Go server implements the same service.