# Creating doot tasks as an agent For a Claude instance with no access to this repo or the database. Everything goes through the agent API on `https://doot.terst.org`. ## The one thing to know first **A human approves every session, in a logged-in browser, and the session lasts one hour.** There is no API key and no auto-approval — trust levels change how the prompt is labelled, not whether it appears. Ask for a session when you are ready to use it, not at the start of a long task, because the approval request itself expires in **5 minutes**. ## Getting a session ```bash # 1. Ask. `name` is shown to the human approving; make it say who you are. curl -sX POST https://doot.terst.org/agent/auth/request \ -H 'Content-Type: application/json' \ -d '{"name":"Claude (groceries)","agent_id":"claude-cli-1"}' # -> {"request_token":"...","status":"pending"} # 2. The human approves in the browser. Tell them to expect it. # 3. Poll until it flips. Statuses: pending, approved, denied, expired. curl -s "https://doot.terst.org/agent/auth/poll?token=$REQUEST_TOKEN" # -> {"status":"approved","session_token":"...","expires_at":"..."} ``` Send the session token on every later call as `Authorization: Bearer `. On a 401, the hour is up: request a new session rather than retrying. ## Creating a task ```bash curl -sX POST https://doot.terst.org/agent/tasks \ -H "Authorization: Bearer $SESSION_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"title":"Renew the boat registration","source":"doot","due_date":"2026-11-20T00:00:00Z","priority":2}' # -> {"status":"success"} ``` `title` and `source` are required. `source` is either: - **`doot`** — a native task. Takes `due_date`, `priority`, `project_id`. - **`trello`** — a Trello card. **Requires `list_id`**; `project_id` and `priority` are ignored. `priority` defaults to 1 when omitted or 0. `due_date` is RFC 3339, or omit it for no due date. ### What this endpoint will not do These fields exist on a doot task and **cannot be set here**. They are not rejected — they are silently ignored, so a task created with them arrives without them: - `description` - `labels` - `estimated_minutes` - `project_name` (use `project_id`) If a task needs any of those, create it and tell the human it needs editing, or use the web UI. The response is `{"status":"success"}` with **no task id**, so you cannot chain a create into an update. Read the task back from `/agent/context` if you need its id. ## Seeing what is already there ```bash curl -s https://doot.terst.org/agent/context -H "Authorization: Bearer $SESSION_TOKEN" ``` Do this before creating anything. doot pulls from several sources and a task that looks missing is often already there under a different wording. ## The other write operations | | | |---|---| | `POST /agent/tasks/{id}/complete` | mark done | | `POST /agent/tasks/{id}/uncomplete` | undo that | | `PATCH /agent/tasks/{id}/due` | change the due date only | | `PATCH /agent/tasks/{id}` | change the task | | `POST /agent/shopping` | `{"name":..., "store":...}`, both required | ## If you only have a browser `GET /agent/web/request`, `/agent/web/status` and `/agent/web/context` are the same flow in HTML, for agents that cannot POST. They are read-only — there is no browser path that creates a task. ## Errors Plain text with the status, not JSON. `400` means the body was wrong (most often a missing `title`, `source`, or `list_id` on a Trello task); `401` means the session expired; `500` means doot accepted the request and failed to carry it out, so check before retrying — it may have half-succeeded.