# TaskOS TaskOS is an AI-operable task-management SaaS for humans and AI agents. Canonical site: https://task.infinitatech.com Agent guide: https://task.infinitatech.com/api/docs OpenAPI 3.1: https://task.infinitatech.com/openapi.json REST base URL: https://task.infinitatech.com/api/v1 Authentication uses a user-created TaskOS token: Authorization: Bearer The API supports tasks, projects, Inbox, Today, Upcoming, next-task recommendation, completion, reopening, recurring tasks, bulk task updates, subtasks, task dependencies, time estimates and tracking, tags, per-task comments, activity history, and daily summaries. The authenticated user is always derived from the token. Never send a user_id. Recurring tasks: set a task's recurrence to { freq: "daily"|"weekly"|"monthly"|"yearly", interval: 1-365 } (needs a due_date or scheduled_date to shift from). Completing it creates the next occurrence automatically, returned in meta.spawned_task. Bulk updates: PATCH /tasks/bulk with { ids: [...up to 100], patch: {...} } applies one patch to every listed task in a single call; an unknown, deleted, or foreign id rejects the whole batch with 422 and changes nothing. Subtasks: set parent_task_id to break a large task into steps instead of listing them in the description. Nesting is exactly one level deep — a subtask cannot take subtasks of its own. GET /tasks/{taskId}/subtasks lists one task's children; GET /tasks?parent_task_id=none lists only top-level tasks. Dependencies: set blocked_by_task_id when a task genuinely cannot start until another finishes. Such a task reports is_blocked: true, is excluded from GET /today (counted in meta.blocked_count), and is never returned by GET /next-task, so it should never be recommended as the thing to work on. Dependency cycles are rejected. Time: estimated_minutes and time_spent_minutes are first-class integer fields in minutes — never write durations into the description. GET /today returns meta.estimated_minutes for the day's workload, and GET /daily-summary returns estimated_minutes_remaining and time_spent_minutes_logged. Tags: a flat vocabulary that cuts across projects. Send tags: ["sales", "quick win"] on create or update to replace a task's whole tag set ([] or null clears it); tags are normalized to lowercase. Filter with GET /tasks?tags=a,b (a task must carry every tag listed), and call GET /tags first for the tags already in use with their counts, so you reuse them rather than inventing near-duplicates. Comments: POST /tasks/{taskId}/comments with { body } appends a timestamped note; GET the same path reads the log oldest first, and DELETE /tasks/{taskId}/comments/{commentId} removes one. Use these for follow-ups instead of appending to description, which would destroy the original intent.