{"openapi":"3.1.0","info":{"title":"Hourtick API","version":"1.0.0","description":"The Hourtick REST API. Authenticate with a personal API token: create one in **Settings → API tokens**, then send `Authorization: Bearer ht_…`.\n\nAll timer changes go through **POST /api/v1/commands**, the same endpoint the web and Mac apps use. Commands are idempotent per `commandId` (use a new UUID per action, reuse it to retry safely).\n\nEvery response carries a `Server-Time` header (epoch ms). Errors use RFC 9457 problem details."},"servers":[{"url":"https://hourtick.com"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"ht_… personal API token"}},"schemas":{"TimeEntry":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workspaceId":{"type":"string","format":"uuid"},"userId":{"type":"string"},"projectId":{"type":"string","format":"uuid"},"taskId":{"type":"string","format":"uuid","description":"Task type"},"workItemId":{"type":["string","null"],"format":"uuid","description":"The task this time is for, if any"},"notes":{"type":"string"},"spentDate":{"type":"string","format":"date","description":"The day the time belongs to (user's time zone)."},"timezone":{"type":"string","examples":["Europe/Copenhagen"]},"accumulatedSeconds":{"type":"integer","description":"Seconds banked from completed runs."},"timerStartedAt":{"type":["integer","null"],"description":"Epoch ms when the current run started; null when stopped."},"billable":{"type":"boolean"},"lockedReason":{"type":["string","null"],"enum":[null,"invoiced","approved","submitted"]},"version":{"type":"integer"},"deletedAt":{"type":["integer","null"]},"createdAt":{"type":"integer"},"updatedAt":{"type":"integer"}},"description":"Live duration = accumulatedSeconds + (now − timerStartedAt)/1000 while running."},"WorkItem":{"type":"object","description":"A task. Status: todo | in_progress | review | done. Priority: 0 none … 4 urgent. `description` (in the detail and in writes) is Markdown, including `- [ ]` checklists.","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":"integer","description":"Short number shown as #12"},"title":{"type":"string"},"status":{"type":"string","enum":["todo","in_progress","review","done"]},"priority":{"type":"integer","minimum":0,"maximum":4},"projectId":{"type":["string","null"]},"clientId":{"type":["string","null"]},"dueDate":{"type":["string","null"],"format":"date"},"estimateSeconds":{"type":["integer","null"]},"labels":{"type":"array","items":{"type":"string"}},"position":{"type":"number"},"assigneeIds":{"type":"array","items":{"type":"string"}},"trackedSeconds":{"type":"integer"},"runningUserIds":{"type":"array","items":{"type":"string"}},"commentCount":{"type":"integer"},"attachmentCount":{"type":"integer"},"checklistDone":{"type":"integer"},"checklistTotal":{"type":"integer"}}},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"entry":{"$ref":"#/components/schemas/TimeEntry"},"conflicts":{"type":"array","description":"Bulk edits: entries that blocked the change.","items":{"type":"object","properties":{"id":{"type":"string"},"reason":{"type":"string"}}}}}}}},"tags":[{"name":"Account","description":"Who you are and what you can track on."},{"name":"Notes and files","description":"Documents and files on a client or a project. Everyone in the workspace can read and add them; the author or a manager deletes. Notes are Tiptap JSON with a plain-text copy (`text`); saves carry a `version` and a stale one answers 409."},{"name":"Time","description":"Timers and time entries. Link time to a task with `workItemId` on start, create or edit."},{"name":"Tasks","description":"The task board: tasks (work items), checklist, chat and files. Any member can create and edit."},{"name":"Integrations","description":"Your own accounts in Linear, Notion, Teamwork and Asana. Connecting needs a person's browser (OAuth); AI agents can't connect or link, and never post through a person's connection. Tokens are stored encrypted and never returned."},{"name":"Reports","description":"Aggregated time and CSV."},{"name":"Billing","description":"Usage (stored data plus data in and out this month) and extra usage. Every plan has unlimited people."},{"name":"Invoices","description":"Invoices through the workspace's own Stripe account (Stripe Connect). An admin connects Stripe in Settings; Stripe Invoicing issues, emails and collects each invoice; Hourtick takes no fee (Stripe's own fees apply). Lines come from billable time not invoiced yet, and sent time is locked as invoiced. Agents send on their own only inside an invoice mandate; otherwise the invoice waits for an admin's approval. Writes take an `idempotencyKey` (body) or `Idempotency-Key` header."},{"name":"Team","description":"Approvals, invoicing and members (role-gated)."},{"name":"Catalog","description":"Clients, projects and task types (admins)."},{"name":"Chat","description":"Channels, DMs, threads, reactions, files and search. Message bodies are Markdown; reference things with links: `[#12 Title](hourtick://task/)`, `hourtick://project/`, `hourtick://client/`, `hourtick://entry/`, and mention with `[@Name](hourtick://user/)` or `hourtick://agent/`. `[@all](hourtick://user/all)` mentions everyone in a channel (not in DMs; managers and admins only beyond 50 people; people can mute it per channel; it never starts agents). Pages come with `refs`: live data for every referenced task, project, client and time entry."},{"name":"Agents","description":"AI agents are workspace members with their own token. Mention one in chat, DM it, or hand it a task, and a session is queued. The agent takes work over MCP (`agent_wait_for_work`), posts progress (`agent_log`), asks (`agent_ask`) and answers (`agent_reply`). It logs the time it worked with `log_time`: billable like anyone's, reported and invoiced as the agent (`userId=agent:` in reports), never on a person's timesheet. Agents don't run timers."}],"paths":{"/api/v1/bootstrap":{"get":{"tags":["Account"],"summary":"Current user, workspace, projects and task types","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"user, workspace, profile, clients, projects (with task types and billable flags), tasks, recent"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/time-entries":{"get":{"tags":["Time"],"summary":"Your time entries in a date range, plus the running entry","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/TimeEntry"}},"running":{"oneOf":[{"$ref":"#/components/schemas/TimeEntry"},{"type":"null"}]}}}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["Team"],"summary":"Edit one or many entries (managers and up)","description":"Applies one `patch` to every listed entry: notes, project and task type (billable follows them), date, duration, or `userId` to move time to another person. Pass each entry's current `version`. All or nothing: running, invoiced, submitted or approved entries, stale versions and days in the new person's submitted weeks return 409 with `conflicts`. Up to 500 entries per request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"entries":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"version":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["id","version"]}},"patch":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"taskId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"notes":{"type":"string","maxLength":5000},"spentDate":{"type":"string"},"durationSeconds":{"type":"integer","minimum":0,"maximum":86400},"userId":{"type":"string","minLength":1,"maxLength":100}},"additionalProperties":false}},"required":["entries","patch"]},"example":{"entries":[{"id":"0192f0c4-7d1e-7abc-9def-0123456789ab","version":3}],"patch":{"notes":"Sprint review","durationSeconds":5400}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/TimeEntry"}}}}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Members can't edit other people's time"},"409":{"description":"Nothing changed; see `conflicts`","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/commands":{"post":{"tags":["Time"],"summary":"Start, stop, continue, create, edit, delete or restore time","description":"`command.type`: `start` (stops any running timer), `restart` (continue an entry on its own date), `stop`, `create` (finished entry with a duration), `edit` (needs `expectedVersion`), `delete`, `restore`. Locked entries return 423; stale versions return 409 with the current entry.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"commandId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"command":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"start"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"spentDate":{"type":"string"},"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"taskId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"workItemId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"notes":{"type":"string","maxLength":5000},"billable":{"type":"boolean"}},"required":["type","entryId","projectId","taskId","notes","billable"]},{"type":"object","properties":{"type":{"type":"string","const":"restart"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type","entryId"]},{"type":"object","properties":{"type":{"type":"string","const":"stop"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type","entryId"]},{"type":"object","properties":{"type":{"type":"string","const":"edit"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expectedVersion":{"type":"integer","minimum":1,"maximum":9007199254740991},"patch":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"taskId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"workItemId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"notes":{"type":"string","maxLength":5000},"billable":{"type":"boolean"},"spentDate":{"type":"string"},"durationSeconds":{"type":"integer","minimum":0,"maximum":86400}},"additionalProperties":false}},"required":["type","entryId","expectedVersion","patch"]},{"type":"object","properties":{"type":{"type":"string","const":"delete"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expectedVersion":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["type","entryId","expectedVersion"]},{"type":"object","properties":{"type":{"type":"string","const":"restore"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type","entryId"]},{"type":"object","properties":{"type":{"type":"string","const":"create"},"entryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"spentDate":{"type":"string"},"durationSeconds":{"type":"integer","minimum":0,"maximum":86400},"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"taskId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"workItemId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"notes":{"type":"string","maxLength":5000},"billable":{"type":"boolean"}},"required":["type","entryId","spentDate","durationSeconds","projectId","taskId","notes","billable"]}]},"clientTime":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["commandId","command"]},"example":{"commandId":"0192f1a0-7c1e-7cc0-9b8e-2f5f0b0a1c11","command":{"type":"start","entryId":"0192f1a0-7c1e-7cc0-9b8e-2f5f0b0a1c12","projectId":"","taskId":"","notes":"Homepage copy","billable":true}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/TimeEntry"}},"noop":{"type":"boolean"}}}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Version conflict (response includes the current entry)"},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"423":{"description":"Entry or day is locked (invoiced, submitted or approved)"}}}},"/api/v1/reports":{"get":{"tags":["Reports"],"summary":"Totals, groups and entries for a period (team scope for managers). For admins, totals and groups also carry the P&L: `peopleCostMinor` (hours × each person's cost rate on that day), `agentCostMinor` (agents' reported cost, converted from USD at ECB rates), `costMinor`, `profitMinor` (billable amount − cost) and `uncostedSeconds`; `pnl` gives the currency","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"groupBy","in":"query","schema":{"type":"string","enum":["client","project","task","user","work_item"],"default":"project"},"description":"`task` groups by task type, `work_item` by task"},{"name":"userId","in":"query","schema":{"type":"string"}},{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"taskId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Task type"},{"name":"workItemId","in":"query","schema":{"type":"string"},"description":"Task id, or `none` for time without a task"},{"name":"billable","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"invoiced","in":"query","schema":{"type":"string","enum":["true","false"]}},{"name":"format","in":"query","schema":{"type":"string","enum":["csv"]},"description":"Return CSV instead of JSON"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"scope, totals, groups, entries, truncated"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/stream":{"get":{"tags":["Time"],"summary":"Server-Sent Events: live entry changes for your account and task changes in the workspace","responses":{"200":{"description":"text/event-stream with `hello`, `entries`, `work_items` (`workItemId`), `chat` (`channelId`, `messageId`, `parentId`, `change`: message, edit, delete, reaction, read, channel, typing or agent) and `presence` events. Private channels and DMs only reach their members"}}}},"/api/v1/timesheets":{"get":{"tags":["Team"],"summary":"Your status for a week","parameters":[{"name":"weekStart","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Team"],"summary":"Submit or withdraw your week","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"weekStart":{"type":"string"},"action":{"type":"string","enum":["submit","withdraw"]}},"required":["weekStart","action"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Wrong state"}}}},"/api/v1/approvals":{"get":{"tags":["Team"],"summary":"Weeks waiting for approval (managers)","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["submitted","approved"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Managers only"}}},"post":{"tags":["Team"],"summary":"Approve, send back or reopen a week (managers)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userId":{"type":"string","minLength":1,"maxLength":100},"weekStart":{"type":"string"},"action":{"type":"string","enum":["approve","reject","reopen"]}},"required":["userId","weekStart","action"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/invoicing":{"post":{"tags":["Team"],"summary":"Mark entries as invoiced or not (admins; locks entries)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"entryIds":{"minItems":1,"maxItems":5000,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"invoiced":{"type":"boolean"}},"required":["entryIds","invoiced"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"integer"}}}}}}}}},"/api/v1/members":{"get":{"tags":["Team"],"summary":"Workspace members (managers)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/cost-rates":{"get":{"tags":["Team"],"summary":"Every member's hourly cost rates, newest first (admins)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ rates: [{ userId, hourlyCostMinor, validFrom }] }"}}}},"403":{"description":"Admins only"}}}},"/api/v1/members/{userId}/cost-rate":{"put":{"tags":["Team"],"summary":"Set what an hour of a member costs, from a day on (admins). Effective-dated: time is costed at the rate valid on its day","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"hourlyCost":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}],"description":"What an hour of this person costs, in the workspace currency; null removes the rate that starts on validFrom"},"validFrom":{"description":"Applies to time spent on or after this day; leave out to apply to all time","type":"string"}},"required":["hourlyCost"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Admins only"},"404":{"description":"Not a member"}}}},"/api/v1/agent-costs":{"get":{"tags":["Agents"],"summary":"Agent cost ledger for a period: an agent's own rows, or all for admins (`agentId` narrows it)","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"agentId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Agents"],"summary":"Report what a piece of work cost (agent token: its own; admins: give agentId). Counts toward the agent's budget and the P&L. Report each cost once (here, MCP log_time usage, or session usage)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"costUsd":{"description":"What the work cost in US dollars (model and tool spend)","type":"number","minimum":0,"maximum":10000},"model":{"type":"string","maxLength":80},"inputTokens":{"type":"integer","minimum":0,"maximum":9007199254740991},"outputTokens":{"type":"integer","minimum":0,"maximum":9007199254740991},"agentId":{"description":"Admins only: the agent the cost is for. Agents always report their own","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"workItemId":{"description":"The task the cost belongs to; its project is used","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"taskId":{"description":"Task type","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"timeEntryId":{"description":"One of the agent's time entries; its project, task type, task and day are used","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"spentDate":{"description":"Defaults to today","type":"string"},"note":{"type":"string","maxLength":2000}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Not the agent or an admin, or outside the agent's scope"},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/ai-providers":{"get":{"tags":["Agents"],"summary":"AI provider connections for verified agent cost (admins). Keys are never returned, only their last 4 characters","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ connections }"}}}}}},"post":{"tags":["Agents"],"summary":"Connect Anthropic (Admin API key), OpenAI (admin key) or OpenRouter (management key) to read what they billed (admins). The key is checked against the provider, then stored encrypted","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"provider":{"type":"string","enum":["anthropic","openai","openrouter"]},"key":{"type":"string","minLength":8,"maxLength":500,"description":"Anthropic Admin API key, OpenAI admin key, or OpenRouter management key. Stored encrypted, never returned"},"label":{"type":"string","maxLength":80},"fillGaps":{"description":"Add what the provider billed beyond what agents reported to the cost ledger (default true)","type":"boolean"}},"required":["provider","key"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"The provider rejected the key"},"503":{"description":"INTEGRATIONS_ENCRYPTION_KEY not set"}}}},"/api/v1/ai-providers/{id}":{"patch":{"tags":["Agents"],"summary":"Rename, or turn filling in from bills on or off (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"label":{"type":"string","maxLength":80},"fillGaps":{"type":"boolean"}}}}}},"responses":{"204":{"description":"Saved"}}},"delete":{"tags":["Agents"],"summary":"Remove the key, its synced bills and the cost it filled in (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed"}}}},"/api/v1/ai-providers/{id}/scopes":{"get":{"tags":["Agents"],"summary":"What the key can see (Anthropic workspaces, OpenAI projects and API keys, OpenRouter keys) and which agent each is mapped to (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"put":{"tags":["Agents"],"summary":"Map a scope to an agent, or clear it with agentId null. A scope belongs to one agent (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"scopeType":{"type":"string","enum":["workspace","project","api_key","key"]},"scopeId":{"type":"string","minLength":1,"maxLength":200},"name":{"type":"string","maxLength":200},"agentId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}],"description":"The agent this bill belongs to; null removes the mapping"}},"required":["scopeType","scopeId","agentId"]}}}},"responses":{"204":{"description":"Saved"},"409":{"description":"OpenAI: an agent maps to projects or API keys, not both"}}}},"/api/v1/ai-providers/{id}/sync":{"post":{"tags":["Agents"],"summary":"Read the last 30 days of bills now and reconcile (admins). Runs every 6 hours on its own","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"integer"}}}}}}}}},"/api/v1/reports/cost-reconciliation":{"get":{"tags":["Reports","Agents"],"summary":"Agent cost as reported vs as billed by the providers, per agent and UTC month, with what was filled in (source `provider` in the cost ledger) (admins)","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/reports/agent-outcomes":{"get":{"tags":["Reports","Agents"],"summary":"Agent outcomes: tasks with agent work done in the period, with the agent's time and cost plus people's time before (briefing) and after (review and rework) the agent delivered, how often work was sent back, and who approved it. Admins also get money (full cost, revenue, margin); managers hours; an agent only its own tasks","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"agentId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ currency, from, to, totals, agents[], tasks[] }"}}}},"403":{"description":"Managers, admins and agents"}}}},"/api/v1/client-ai-reports/preview":{"get":{"tags":["Reports"],"summary":"Client AI work report without sharing it: people's and agents' hours, agents and models, and whether a person reviewed each piece of agent work. No rates, costs or notes (managers)","parameters":[{"name":"clientId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"namePeople","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ report }"}}}}}}},"/api/v1/client-ai-reports":{"get":{"tags":["Reports"],"summary":"Shared client AI work reports, newest first (managers). Links are not listed","parameters":[{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Reports"],"summary":"Freeze a client AI work report and get a share link (admins). The link (`link.url`) is only in this response; the page is /ai-report/{token} and its JSON /api/ai-reports/{token}, with a SHA-256 fingerprint of the canonical JSON","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"clientId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"projectId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"from":{"type":"string"},"to":{"type":"string"},"namePeople":{"description":"Show people's names (who worked, who approved). Off by default","type":"boolean"}},"required":["clientId","from","to"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ link, report }"}}}},"403":{"description":"Admins only"}}}},"/api/v1/client-ai-reports/{id}":{"delete":{"tags":["Reports"],"summary":"Revoke a shared report: its link stops working at once (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Revoked"}}}},"/api/ai-reports/{token}":{"get":{"tags":["Reports"],"summary":"A shared client AI work report as JSON, no account needed (the link is the credential). CORS open","security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ report, fingerprint, createdAt, fingerprintMethod }"}}}},"404":{"description":"Unknown or revoked"}}}},"/api/v1/agent-costs/{id}":{"delete":{"tags":["Agents"],"summary":"Remove a wrong cost row (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/integrations":{"get":{"tags":["Integrations"],"summary":"Linear, Notion, Teamwork and Asana: whether each is available and whether you are connected","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ integrations: [{ id, label, available, asks, connection: { accountName, connectedAt } | null }] }"}}}},"401":{"description":"Missing or invalid token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/integrations/{provider}":{"post":{"tags":["Integrations"],"summary":"Start connecting: returns the vendor's approval address to open in a browser","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["linear","notion","teamwork","asana"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"403":{"description":"AI agents can't connect accounts"},"404":{"description":"Unknown or not set up on this server"}}},"delete":{"tags":["Integrations"],"summary":"Disconnect: forgets the tokens and asks the vendor to revoke them where it supports that","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["linear","notion","teamwork","asana"]}}],"responses":{"204":{"description":"Disconnected"}}}},"/api/v1/work-items/{id}/links":{"get":{"tags":["Integrations"],"summary":"Items linked to a task, with their current title and status (re-read when older than 5 minutes)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ links: [{ id, provider, label, url, title, status }] }"}}}},"404":{"description":"No such task"}}},"post":{"tags":["Integrations"],"summary":"Link a Linear issue, Notion page, Teamwork task or Asana task by its address","description":"The provider is recognised from the address (a Linear identifier such as `ENG-123` also works). You must be connected to it first (409 otherwise). One link per provider per task: a new one replaces the old. Time tracked on a Teamwork-linked task is sent to Teamwork; Linear, Notion and Asana get one comment with the total when the task is done.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ link }"}}}},"403":{"description":"AI agents can't link"},"409":{"description":"Not connected to that provider"},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/work-items/{id}/links/{linkId}":{"delete":{"tags":["Integrations"],"summary":"Remove a link. Time already sent to Teamwork stays there","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"linkId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed"}}}},"/api/v1/notes":{"get":{"tags":["Notes and files"],"summary":"Notes on a project (`projectId`) or client (`clientId`): titles and previews, newest edit first","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ notes: [{ id, title, preview, updatedAt, updatedBy, createdBy }] }"}}},"post":{"tags":["Notes and files"],"summary":"Create a note on a project or client","description":"Send the document as `markdown` (easiest; headings, marks, links, lists, checklists, tables, quotes, code) or as Tiptap JSON in `content`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"clientId":{"type":"string","format":"uuid"},"title":{"type":"string","maxLength":200},"markdown":{"type":"string"},"content":{"type":"object","description":"Tiptap JSON (type: doc)"}}}}}},"responses":{"201":{"description":"{ note }"}}}},"/api/v1/notes/{id}":{"get":{"tags":["Notes and files"],"summary":"One note: title, Tiptap `content`, `markdown`, plain `text` and `version`","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ note }"}}},"patch":{"tags":["Notes and files"],"summary":"Save a note","description":"Replace the title and/or the document (`markdown` or `content`) with the `version` you started from. If someone saved since, 409 `notes/conflict` returns their `note`; resend with `force: true` to keep yours. `appendMarkdown` adds to the end of the current document and needs no version. Links other than http(s) and mailto are removed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"markdown":{"type":"string"},"appendMarkdown":{"type":"string"},"content":{"type":"object"},"version":{"type":"integer"},"force":{"type":"boolean"}}}}}},"responses":{"200":{"description":"{ note }"},"409":{"description":"Changed by someone else"}}},"delete":{"tags":["Notes and files"],"summary":"Delete a note (its creator or a manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/files":{"get":{"tags":["Notes and files"],"summary":"Files on a project (`projectId`) or client (`clientId`), newest first","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ files: Attachment[] }"}}},"post":{"tags":["Notes and files"],"summary":"Upload a file to a project or client (multipart: file, projectId or clientId; up to 25 MB; counts toward usage)","responses":{"201":{"description":"{ file }"},"402":{"description":"Usage limit reached: uploads are paused"}}}},"/api/v1/files/{id}":{"get":{"tags":["Notes and files"],"summary":"Open a file: redirects to a short-lived signed URL (`?download=1` to download, `?format=json` for `{ url }`)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"302":{"description":"Signed URL"}}},"delete":{"tags":["Notes and files"],"summary":"Delete a file (its uploader or a manager)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/records/counts":{"get":{"tags":["Notes and files"],"summary":"Notes and files per project and client","responses":{"200":{"description":"{ projects: { [id]: { notes, files } }, clients: { … } }"}}}},"/api/v1/clients":{"get":{"tags":["Catalog"],"summary":"Clients with VAT numbers and active project counts","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Catalog"],"summary":"Create a client (admins, or an agent an admin allowed), optionally with a VAT number. Records who added it","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"vatNumber":{"type":"string","maxLength":40}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/payments":{"get":{"tags":["Invoices"],"summary":"The workspace's Stripe connection: connected, ready to send invoices, and (admins) account, VAT and payment-term settings","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"patch":{"tags":["Invoices"],"summary":"VAT rate (basis points) and label, and default days until due (admins)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"vatRateBps":{"anyOf":[{"type":"integer","minimum":0,"maximum":10000},{"type":"null"}]},"vatLabel":{"type":"string","minLength":1,"maxLength":30},"defaultDueDays":{"type":"integer","minimum":0,"maximum":365}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Stripe isn't connected"}}},"delete":{"tags":["Invoices"],"summary":"Stop sending invoices through the account (admins). The Stripe account, its money and sent invoices stay the business's","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/payments/connect":{"post":{"tags":["Invoices"],"summary":"Start or resume Stripe-hosted onboarding and get its one-time URL (admins, people only). The first time it needs `country`, where the business is registered","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":2}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"422":{"description":"Country missing"}}}},"/api/v1/invoices/preview":{"post":{"tags":["Invoices"],"summary":"What an invoice would contain: lines, VAT, total, and anything that stops sending (admins; agents for their clients). Changes nothing","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"clientId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"projectIds":{"maxItems":200,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"from":{"type":"string"},"to":{"type":"string"},"groupBy":{"description":"How lines are grouped: project_task (default), person, day or entry","type":"string","enum":["project_task","person","day","entry"]},"dueDays":{"type":"integer","minimum":0,"maximum":365},"memo":{"type":"string","maxLength":500},"idempotencyKey":{"type":"string","minLength":8,"maxLength":100}},"required":["clientId"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ preview }"}}}}}}},"/api/v1/invoices":{"get":{"tags":["Invoices"],"summary":"Invoices, newest first (admins; agents see their clients')","parameters":[{"name":"clientId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending_approval","draft","open","paid","void","uncollectible"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ invoices }"}}}}}},"post":{"tags":["Invoices"],"summary":"Create an invoice from a client's billable time not invoiced yet and send it through Stripe. The time is locked as invoiced. An agent outside its mandate gets status `pending_approval`","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"clientId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"projectIds":{"maxItems":200,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"from":{"type":"string"},"to":{"type":"string"},"groupBy":{"description":"How lines are grouped: project_task (default), person, day or entry","type":"string","enum":["project_task","person","day","entry"]},"dueDays":{"type":"integer","minimum":0,"maximum":365},"memo":{"type":"string","maxLength":500},"idempotencyKey":{"type":"string","minLength":8,"maxLength":100}},"required":["clientId"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ invoice }"}}}},"409":{"description":"Stripe not connected, or the time changed or is already on another invoice"},"422":{"description":"Not ready: e.g. no billing email or nothing to bill"},"502":{"description":"Stripe refused it; the invoice stays as not sent and can be retried"}}}},"/api/v1/invoices/{id}":{"get":{"tags":["Invoices"],"summary":"One invoice with its lines, payment page and timesheet link","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ invoice }"}}}}}}},"/api/v1/invoices/{id}/approve":{"post":{"tags":["Invoices"],"summary":"Approve an agent's invoice waiting outside its mandate, and send it (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/invoices/{id}/retry":{"post":{"tags":["Invoices"],"summary":"Send an invoice again that didn't reach Stripe (admins). Nothing is created twice","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/invoices/{id}/void":{"post":{"tags":["Invoices"],"summary":"Void an invoice (or discard one not sent); its time becomes billable again (admins). A paid invoice is refunded in Stripe instead","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Already paid"}}}},"/api/v1/invoice-mandates":{"get":{"tags":["Invoices","Agents"],"summary":"What agents may invoice without approval (admins; an agent sees its own)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"{ mandates }"}}}}}},"post":{"tags":["Invoices","Agents"],"summary":"Let an agent send invoices on its own: clients (empty: any it works on), most per invoice (minor units, workspace currency), expiry (admins)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"agentId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"clientIds":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"maxTotalMinor":{"type":"integer","minimum":1,"maximum":100000000000},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]}},"required":["agentId","maxTotalMinor"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/invoice-mandates/{id}":{"delete":{"tags":["Invoices","Agents"],"summary":"Stop an invoice mandate; the agent's invoices wait for approval again (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/clients/{id}":{"patch":{"tags":["Catalog"],"summary":"Rename a client, set or clear its VAT number, set its billing details for invoices (email, address, country, language, VAT treatment; people only), or archive it (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"vatNumber":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"archived":{"type":"boolean"},"billingEmail":{"anyOf":[{"type":"string","maxLength":200,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"billingAddress":{"anyOf":[{"type":"object","properties":{"line1":{"type":"string","maxLength":200},"line2":{"type":"string","maxLength":200},"postalCode":{"type":"string","maxLength":20},"city":{"type":"string","maxLength":100}}},{"type":"null"}]},"country":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}]},"invoiceLanguage":{"anyOf":[{"type":"string","enum":["en","da","de","sv","nb","nl","fr","es","fi","it"]},{"type":"null"}]},"vatTreatment":{"type":"string","enum":["auto","standard","reverse_charge","none"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Name already used"}}}},"/api/v1/projects":{"post":{"tags":["Catalog"],"summary":"Create a project (admins, or an agent an admin allowed). Records who added it","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"clientId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string","maxLength":50},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"billingType":{"type":"string","enum":["time_materials","fixed_fee","non_billable"]},"budgetHours":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]},"hourlyRate":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]}},"required":["name","clientId","color","billingType"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/projects/{id}":{"patch":{"tags":["Catalog"],"summary":"Update a project (admins): billing, budget, rate, task types, archive, and memberIds (the team; empty means everyone can track on it)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"color":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"billingType":{"type":"string","enum":["time_materials","fixed_fee","non_billable"]},"budgetHours":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]},"hourlyRate":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]},"repriceUninvoiced":{"type":"boolean"},"archived":{"type":"boolean"},"taskIds":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"memberIds":{"maxItems":1000,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/work-items":{"get":{"tags":["Tasks"],"summary":"Tasks on the board: open ones plus done in the last 14 days (`done=all` for everything)","parameters":[{"name":"done","in":"query","schema":{"type":"string","enum":["recent","all"],"default":"recent"}},{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"assigneeId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkItem"}},"truncated":{"type":"boolean"},"serverTime":{"type":"integer"}}}}}}}},"post":{"tags":["Tasks"],"summary":"Create a task (any member)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":20000},"status":{"type":"string","enum":["todo","in_progress","review","done"]},"priority":{"type":"integer","minimum":0,"maximum":4},"projectId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"clientId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"dueDate":{"type":["string","null"]},"estimateSeconds":{"anyOf":[{"type":"integer","minimum":0,"maximum":36000000},{"type":"null"}]},"parentId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"labels":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"assigneeIds":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}}},"required":["title"],"additionalProperties":false},"example":{"title":"Design the pricing page","projectId":"…","assigneeIds":["…"],"priority":3,"dueDate":"2026-10-01","labels":["Design"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/WorkItem"}}}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/work-items/{id}":{"get":{"tags":["Tasks"],"summary":"A task with description, checklist, timeline (comments, files, events) and time per person","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found"}}},"patch":{"tags":["Tasks"],"summary":"Update a task. Moving between columns: send `status` (and `position` to place it; lower is higher up)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":20000},"status":{"type":"string","enum":["todo","in_progress","review","done"]},"priority":{"type":"integer","minimum":0,"maximum":4},"projectId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"clientId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"dueDate":{"type":["string","null"]},"estimateSeconds":{"anyOf":[{"type":"integer","minimum":0,"maximum":36000000},{"type":"null"}]},"parentId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"labels":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"assigneeIds":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"position":{"type":"number"}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/WorkItem"}}}}}}}},"delete":{"tags":["Tasks"],"summary":"Delete a task with its comments and files (creator or managers). Tracked time is kept","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/work-items/{id}/comments":{"get":{"tags":["Tasks"],"summary":"The task's comments, oldest first, with their files (an agent's comment has `meta.agentId`)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found"}}},"post":{"tags":["Tasks"],"summary":"Post in the task's chat; `attachmentIds` links files you uploaded","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"body":{"type":"string","maxLength":10000},"attachmentIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"mentionIds":{"default":[],"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}}},"required":["body"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/work-items/{id}/comments/{commentId}":{"patch":{"tags":["Tasks"],"summary":"Edit your comment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":10000}},"required":["body"]}}}},"responses":{"204":{"description":"Saved"}}},"delete":{"tags":["Tasks"],"summary":"Delete a comment and its files (author or managers)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/work-items/{id}/checklist":{"post":{"tags":["Tasks"],"summary":"Add a checklist item","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500}},"required":["title"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/work-items/{id}/checklist/{itemId}":{"patch":{"tags":["Tasks"],"summary":"Tick, rename or move a checklist item","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"done":{"type":"boolean"},"position":{"type":"number"}}}}}},"responses":{"204":{"description":"Saved"}}},"delete":{"tags":["Tasks"],"summary":"Remove a checklist item","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/work-items/{id}/attachments":{"post":{"tags":["Tasks"],"summary":"Upload a file (multipart/form-data, field `file`, up to 25 MB). Link it by posting a comment with its id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"402":{"description":"This month's usage is used up; uploads pause until the 1st"},"413":{"description":"File too large"}}}},"/api/v1/attachments/{id}":{"get":{"tags":["Tasks"],"summary":"Redirects to a 5-minute signed URL. Images, PDFs, video, audio and text preview inline; everything else downloads. `?download=1` forces a download","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"302":{"description":"Signed URL"}}},"delete":{"tags":["Tasks"],"summary":"Delete a file (uploader or managers)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/task-views":{"get":{"tags":["Tasks"],"summary":"Your saved Tasks views (personal)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Tasks"],"summary":"Save a view: people, agents, projects, clients and labels (any-of; `none` for unset), search and layout","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"filters":{"type":"object","properties":{"people":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"agents":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"projects":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"clients":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"labels":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":40}},"q":{"type":"string","maxLength":200},"layout":{"type":"string","enum":["board","list"]}},"additionalProperties":false}},"required":["name","filters"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/task-views/{id}":{"patch":{"tags":["Tasks"],"summary":"Rename, move or update a view's filters","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"filters":{"type":"object","properties":{"people":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"agents":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"projects":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"clients":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"labels":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":40}},"q":{"type":"string","maxLength":200},"layout":{"type":"string","enum":["board","list"]}},"additionalProperties":false},"position":{"type":"number"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"tags":["Tasks"],"summary":"Delete a view","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/usage":{"get":{"tags":["Billing"],"summary":"Usage this month and the plan's limit, in bytes (1 GB = 10^9): stored data (database share and files) plus data in and out since the 1st","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"dbBytes":{"type":"integer"},"fileBytes":{"type":"integer"},"usedBytes":{"type":"integer"},"limitBytes":{"type":"integer"},"measuredAt":{"type":["integer","null"]}}}}}}}}},"/api/v1/billing/storage":{"put":{"tags":["Billing"],"summary":"Set extra GB on Pro ($10/GB per month; admins). More is charged pro rata right away","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"extraGb":{"type":"integer","minimum":0,"maximum":1000}},"required":["extraGb"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Not on Pro"}}}},"/api/v1/chat/channels":{"get":{"tags":["Chat"],"summary":"Your channels and DMs with unread and mention counts. `?browse` adds public channels you haven't joined","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Chat"],"summary":"Create a channel (name is slugged; private channels need `memberIds`)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"topic":{"type":"string","maxLength":250},"isPrivate":{"type":"boolean"},"memberIds":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"description":"Name taken"}}}},"/api/v1/chat/channels/{id}":{"patch":{"tags":["Chat"],"summary":"Rename, set the topic or archive","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"topic":{"type":"string","maxLength":250},"archived":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"204":{"description":"Saved"}}}},"/api/v1/chat/channels/{id}/join":{"post":{"tags":["Chat"],"summary":"Join a public channel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Joined"}}}},"/api/v1/search":{"get":{"tags":["Account"],"summary":"Search the workspace (the ⌘K palette)","description":"Tasks (by number, e.g. `#12`, or title), your own time entries (notes, project, task type), projects, clients, people and the channels you can see. A few of each, best matches first.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"{ tasks, entries, projects, clients, people, channels }"}}}},"/api/v1/gifs":{"get":{"tags":["Chat"],"summary":"GIFs for the chat picker (Powered by GIPHY)","description":"Trending when `q` is empty, otherwise a search (rated G). Post one as a message body of `![title](url#WxH)`; only GIPHY media URLs render as images. 503 when the server has no GIPHY key.","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Up to 24 GIFs: id, title, preview (+ size), url (+ width, height)"},"503":{"description":"GIFs aren't set up"}}}},"/api/v1/chat/channels/{id}/preferences":{"patch":{"tags":["Chat"],"summary":"Your preferences for a channel","description":"`muteAll: true` stops `@all` from mentioning you in this channel. Direct mentions still reach you.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["muteAll"],"properties":{"muteAll":{"type":"boolean"}}}}}},"responses":{"204":{"description":"Saved"}}}},"/api/v1/chat/channels/{id}/leave":{"post":{"tags":["Chat"],"summary":"Leave a channel","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Left"}}}},"/api/v1/chat/channels/{id}/members":{"post":{"tags":["Chat"],"summary":"Add people and agents","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userIds":{"default":[],"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"agentIds":{"default":[],"maxItems":50,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}}}}}},"responses":{"204":{"description":"Added"}}}},"/api/v1/chat/channels/{id}/read":{"post":{"tags":["Chat"],"summary":"Mark the channel read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Read"}}}},"/api/v1/chat/channels/{id}/messages":{"get":{"tags":["Chat"],"summary":"50 top-level messages, newest last, with `refs`. `?before=` pages back; `?thread=` returns a whole thread","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"before","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"thread","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Chat"],"summary":"Post a message (`parentId` replies in a thread; `attachmentIds` links uploaded files). Mentioning an agent queues a session","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"body":{"type":"string","maxLength":20000},"parentId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"attachmentIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["body"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/chat/channels/{id}/files":{"post":{"tags":["Chat"],"summary":"Upload a file (multipart/form-data, field `file`, up to 25 MB), then send its id in `attachmentIds`","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"402":{"description":"This month's usage is used up; uploads pause until the 1st"},"413":{"description":"File too large"}}}},"/api/v1/chat/files/{id}":{"get":{"tags":["Chat"],"summary":"Redirects to a 5-minute signed URL; `?download=1` forces a download","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"302":{"description":"Signed URL"}}}},"/api/v1/chat/dms":{"post":{"tags":["Chat"],"summary":"Open (or reuse) a DM with one or more people and agents","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"userIds":{"default":[],"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"agentIds":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/chat/messages/{id}":{"patch":{"tags":["Chat"],"summary":"Edit your message","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":20000}},"required":["body"]}}}},"responses":{"204":{"description":"Saved"}}},"delete":{"tags":["Chat"],"summary":"Delete a message and its files (author or managers)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted"}}}},"/api/v1/chat/messages/{id}/reactions":{"post":{"tags":["Chat"],"summary":"Toggle an emoji reaction","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"emoji":{"type":"string","minLength":1,"maxLength":16}},"required":["emoji"]}}}},"responses":{"204":{"description":"Toggled"}}}},"/api/v1/chat/messages/{id}/task":{"post":{"tags":["Chat"],"summary":"Turn a message into a task; a reply links to it","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"item":{"$ref":"#/components/schemas/WorkItem"}}}}}}}}},"/api/v1/chat/typing":{"post":{"tags":["Chat"],"summary":"Say you're typing (shown for 5 seconds)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"channelId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"parentId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["channelId"]}}}},"responses":{"204":{"description":"Sent"}}}},"/api/v1/chat/search":{"get":{"tags":["Chat"],"summary":"Full-text search in messages you can read","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/presence":{"get":{"tags":["Chat"],"summary":"Who's online, what they're tracking (if they share it) and which agents are connected","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agents":{"get":{"tags":["Agents"],"summary":"Agents in the workspace: provider, model, skills, access, whether they're connected, and canUse (whether you may ask it)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Agents"],"summary":"Add an agent (admins only): name, description, provider, model, skills. Returns its token once","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"description":{"type":"string","maxLength":500},"provider":{"type":"string","enum":["","anthropic","openai","xai","meta","microsoft","google","other"]},"model":{"type":"string","maxLength":80},"skills":{"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"scopeClientIds":{"maxItems":200,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"scopeProjectIds":{"maxItems":500,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"readOnly":{"type":"boolean"},"budgetUsdMonth":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]},"budgetHoursMonth":{"anyOf":[{"type":"number","minimum":0,"maximum":10000},{"type":"null"}]},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"paused":{"type":"boolean"},"instructions":{"type":"string","maxLength":20000}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"type":"object"},"token":{"type":"string"}}}}}}}}},"/api/v1/agents/{id}":{"patch":{"tags":["Agents"],"summary":"Rename, describe, set provider, model and skills, set who may ask it (access: everyone or restricted to allowedRoles and allowedUserIds; its owner and admins always may), or turn off. Owner or admins. Admins only: scope (scopeClientIds, scopeProjectIds), readOnly, budgetUsdMonth, budgetHoursMonth, expiresAt, paused, canCreateCatalog. Owner or admin: instructions (each change is a version), webhookUrl, webhookFormat (hourtick or github_dispatch), webhookAuthorization. Agents can't change agents. Setting a new webhook returns its signing secret once","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"description":{"type":"string","maxLength":500},"disabled":{"type":"boolean"},"provider":{"type":"string","enum":["","anthropic","openai","xai","meta","microsoft","google","other"]},"model":{"type":"string","maxLength":80},"skills":{"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"access":{"type":"string","enum":["everyone","restricted"]},"allowedRoles":{"maxItems":4,"type":"array","items":{"type":"string","enum":["owner","admin","manager","member"]}},"allowedUserIds":{"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"canCreateCatalog":{"type":"boolean"},"scopeClientIds":{"maxItems":200,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"scopeProjectIds":{"maxItems":500,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"readOnly":{"type":"boolean"},"budgetUsdMonth":{"anyOf":[{"type":"number","minimum":0,"maximum":1000000},{"type":"null"}]},"budgetHoursMonth":{"anyOf":[{"type":"number","minimum":0,"maximum":10000},{"type":"null"}]},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"paused":{"type":"boolean"},"instructions":{"type":"string","maxLength":20000},"webhookUrl":{"anyOf":[{"type":"string","maxLength":2000,"format":"uri"},{"type":"null"}]},"webhookFormat":{"type":"string","enum":["hourtick","github_dispatch"]},"webhookAuthorization":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"webhookSecret":{"type":"string"}}}}}},"204":{"description":"Saved"}}}},"/api/v1/work-items/{id}/dependencies":{"post":{"tags":["Tasks"],"summary":"Mark this task blocked by another (type blocked_by) or blocking another (type blocks). Refuses itself, loops and more than 50 blockers. A blocked task can't move to in progress, review or done until its blockers are done","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"type":{"type":"string","enum":["blocked_by","blocks"]},"workItemId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type","workItemId"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"tags":["Tasks"],"summary":"Remove the dependency; a task with no open blockers left unlocks","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"type":{"type":"string","enum":["blocked_by","blocks"]},"workItemId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["type","workItemId"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agents/{id}/events":{"get":{"tags":["Agents"],"summary":"The agent's activity log and this month's usage against its budget (owner or admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agents/{id}/instructions":{"get":{"tags":["Agents"],"summary":"The agent's instructions and every earlier version (owner or admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agents/{id}/webhook":{"post":{"tags":["Agents"],"summary":"action: test (sends a signed agent.ping and returns the status it got) or rotate (a new signing secret, shown once). Owner or admins","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"action":{"type":"string","enum":["test","rotate"]}},"required":["action"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agent-requests":{"get":{"tags":["Agents"],"summary":"Requests for new agents: all for admins, your own otherwise","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Agents"],"summary":"Ask the admins for a new agent (people and agents)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40},"description":{"default":"","type":"string","maxLength":500},"provider":{"default":"","type":"string","enum":["","anthropic","openai","xai","meta","microsoft","google","other"]},"model":{"default":"","type":"string","maxLength":80},"skills":{"default":[],"maxItems":12,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"reason":{"default":"","type":"string","maxLength":2000}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agent-requests/{id}":{"patch":{"tags":["Agents"],"summary":"Approve (creates the agent, owned by you, without a token) or decline. Admins signed in as themselves","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"approve":{"type":"boolean"},"note":{"type":"string","maxLength":1000}},"required":["approve"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/agents/{id}/token":{"post":{"tags":["Agents"],"summary":"Replace the agent's token (owner)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}}}}}}}}},"/api/v1/agent-sessions/{id}":{"get":{"tags":["Agents"],"summary":"One agent session: status, steps, answer, reported tokens and cost, and the helpers it delegated to","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"object"},"helpers":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/agent-sessions/{id}/cancel":{"post":{"tags":["Agents"],"summary":"Stop an agent's work and every helper it delegated to (requester or managers)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Stopped"}}}},"/api/v1/delegations":{"post":{"tags":["Agents"],"summary":"Hand work to an agent: an existing task (workItemId), a new task (title), or a quick request (neither). Agents chain helpers with the MCP tool agent_delegate","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"agent":{"type":"string","minLength":1,"maxLength":100},"instructions":{"type":"string","minLength":1,"maxLength":8000},"workItemId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string","minLength":1,"maxLength":300}},"required":["agent","instructions"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"object"}}}}}},"422":{"description":"Unknown agent, too deep, loop, or invalid"},"429":{"description":"The agent's queue is full"}}}},"/api/v1/workspaces":{"post":{"tags":["Account"],"summary":"Create a workspace","description":"A new workspace you own, with a starter client, project and task types. You stay where you are; switch to it with POST /api/v1/workspace/switch. Up to 20 owned workspaces; agents can't create them.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80}}}}}},"responses":{"201":{"description":"Created"},"409":{"description":"You own the maximum number of workspaces"},"422":{"description":"Invalid name"}}}},"/api/v1/workspace/switch":{"post":{"tags":["Account"],"summary":"Move this signed-in device to another workspace you're a member of, and make it your default. Sign-in sessions only; API and agent tokens stay in their own workspace. Bootstrap lists your workspaces","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string","format":"uuid"}},"required":["workspaceId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workspaceId":{"type":"string"},"role":{"type":"string"}}}}}},"404":{"description":"Not a member"}}}},"/api/v1/connected-apps":{"get":{"tags":["Account"],"summary":"Apps you connected over OAuth (ChatGPT, Claude…). They act as you in your default workspace","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/connected-apps/{clientId}":{"delete":{"tags":["Account"],"summary":"Disconnect an app: its tokens stop working at once","parameters":[{"name":"clientId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Disconnected"}}}},"/api/v1/work-items/{id}/delegate":{"post":{"tags":["Agents"],"summary":"Hand a task to an agent. The people on it stay responsible","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"agentId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"note":{"default":"","type":"string","maxLength":4000}},"required":["agentId"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/work-items/{id}/agent-sessions":{"get":{"tags":["Agents"],"summary":"Agent work on a task, with each session's activity","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/activity":{"get":{"tags":["Time"],"summary":"Your day: tracked entries and what you did (tasks created, moved or commented on, chat messages per channel, agent requests), for drafting a timesheet","parameters":[{"name":"date","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/reports/agents":{"get":{"tags":["Reports","Agents"],"summary":"Agent session time (how long agents worked on requests), tokens and reported cost in USD, by agent and project. Time agents log appears in the normal reports as their own rows","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/tasks":{"post":{"tags":["Catalog"],"summary":"Create a task type (admins)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"billable":{"type":"boolean"}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/tasks/{id}":{"patch":{"tags":["Catalog"],"summary":"Update a task type (admins)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"billable":{"type":"boolean"},"archived":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}}}}