{"openapi":"3.1.0","info":{"title":"Move Task List API","summary":"Read and write the tasks on a Move task list.","description":"The public REST API for [Move](https://m0ve.app) — the personal\ntimeline app that blends calendars, events and groups.\n\nThis is the API over a single **task list**: a Kanban-style board\nthat lives on a Move calendar. It is switched on per list from that\nlist's Integrations page, which mints an API key.\n\n## Authentication\n\nThe API key is the whole credential and it names exactly one task\nlist, which is why no list id appears in any path — the key already\nsaid which list. Send it as a bearer token:\n\n    Authorization: Bearer move_xxxxxxxxxxxxxxxx\n\nor, for clients that can only send a fixed custom header:\n\n    X-Move-Api-Key: move_xxxxxxxxxxxxxxxx\n\nA key that leaks can be rotated from the same Integrations page\nwithout touching the calendar it belongs to.\n\n## Permissions\n\nA key is read-only unless writes are enabled on the list. A\nread-only key gets `403 read_only` from every write operation. The\ntwo permission levels are published as OAuth-style scope names in\nthe [protected resource metadata](https://m0ve.app/.well-known/oauth-protected-resource):\n`tasks:read` and `tasks:write`.\n\n## Naming a column\n\nAnywhere a column is named — the `status` filter, create, update\nand move — you may use its slug (`verify`), its display name\n(`Verify`) or its stored id (`section_2845be76`). Prefer the slug:\nit is readable and it is what the API returns alongside every id.\n\n## Errors\n\nEvery error is JSON with the same shape: a stable machine-readable\n`error` code, a human `message` that says how to fix it, and a\n`documentation_url`. Branch on `error`, not on the status code.\n","version":"1.0.0","termsOfService":"https://m0ve.app/application-terms","contact":{"name":"Move API support","url":"https://m0ve.app/developers","email":"support@9thdesigns.com"}},"servers":[{"url":"https://m0ve.app","description":"Move"}],"externalDocs":{"description":"Move API documentation","url":"https://docs.m0ve.app"},"tags":[{"name":"Task list","description":"The list itself: its columns, its counts and what this key may do to it."},{"name":"Tasks","description":"The tasks on the list — reading, filtering, creating, updating and moving them."},{"name":"Comments","description":"The comment thread on a task."}],"security":[{"moveApiKey":[]},{"moveApiKeyHeader":[]}],"paths":{"/api/v1/task-list":{"get":{"operationId":"getTaskList","summary":"Get the task list this API key belongs to","description":"Returns the list the API key names — its title, its columns and how many tasks sit in each — plus what this key is allowed to do. Call this first: the `sections` it returns are the only valid values for `status` anywhere else in the API, so a client can discover the columns instead of hardcoding them.","tags":["Task list"],"x-required-scope":"tasks:read","responses":{"200":{"description":"The task list.","content":{"application/json":{"schema":{"type":"object","required":["list"],"properties":{"list":{"$ref":"#/components/schemas/TaskList"}}}}}},"401":{"description":"The API key is missing, unrecognised, or its list has API access switched off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/task-list/tasks":{"get":{"operationId":"listTasks","summary":"List the tasks on the task list","description":"Returns a page of tasks. Every filter is optional and they compose, so `?status=verify&priority=high&due_before=2026-01-01T00:00:00Z` is one request. Results carry the list itself alongside them so a client can render a board from a single call. Use `include=none` when polling: comments and attachments are returned by default and they are the expensive part of the payload.","tags":["Tasks"],"x-required-scope":"tasks:read","parameters":[{"name":"status","in":"query","required":false,"description":"Filter by column. Accepts a column slug, its display name or its stored id, or a comma-separated list of them. Two reserved words cut across columns: `open` (not completed) and `completed`. `all` is the same as omitting the filter.","schema":{"type":"string"},"examples":{"oneColumn":{"value":"verify","summary":"A single column, by slug"},"severalColumns":{"value":"todo,in-progress","summary":"More than one column"},"openOnly":{"value":"open","summary":"Everything not completed"}}},{"name":"completed","in":"query","required":false,"description":"Filter on the completion flag regardless of column. Truthy values are `true`, `1`, `yes` and `on`; anything else reads as false.","schema":{"type":"boolean"}},{"name":"priority","in":"query","required":false,"description":"Filter by priority. Comma-separate to match more than one.","schema":{"type":"string"},"examples":{"urgent":{"value":"high","summary":"High priority only"}}},{"name":"source","in":"query","required":false,"description":"Filter by how the task arrived. Tasks created through this API carry `api`; the hosted intake form and the error inbox carry their own.","schema":{"type":"string","examples":["api"]}},{"name":"assignee_user_id","in":"query","required":false,"description":"Only tasks assigned to this Move user id.","schema":{"type":"integer","format":"int64"}},{"name":"due_before","in":"query","required":false,"description":"Only tasks due at or before this time. A value that does not parse is ignored rather than rejected, so an unused filter may be sent empty.","schema":{"type":"string","format":"date-time"}},{"name":"due_after","in":"query","required":false,"description":"Only tasks due at or after this time.","schema":{"type":"string","format":"date-time"}},{"name":"updated_since","in":"query","required":false,"description":"Only tasks changed at or after this time. This is the field to poll on for an incremental sync.","schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","required":false,"description":"Case-insensitive substring search over task titles and notes.","schema":{"type":"string"}},{"name":"include","in":"query","required":false,"description":"Which nested collections to embed in each task. Omit for both. Send `comments`, `attachments`, `comments,attachments`, or `none` for neither — `none` is simply a value that names neither collection.","schema":{"type":"string","examples":["none","comments","comments,attachments"]}},{"name":"page","in":"query","required":false,"description":"Page number, starting at 1. A value below 1 is treated as 1.","schema":{"type":"integer","format":"int32","minimum":1,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Tasks per page. Values above the maximum are clamped to it.","schema":{"type":"integer","format":"int32","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"A page of tasks.","content":{"application/json":{"schema":{"type":"object","required":["list","tasks","pagination"],"properties":{"list":{"$ref":"#/components/schemas/TaskList"},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"The API key is missing, unrecognised, or its list has API access switched off.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createTask","summary":"Create a task","description":"Adds a task to the list. Only `title` really matters; everything else has a sensible default. An unrecognised or absent `status` lands the task in the list's first column rather than being rejected. Send `multipart/form-data` with `files[]` to attach files at creation.","tags":["Tasks"],"x-required-scope":"tasks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCreateRequest"},"examples":{"minimal":{"summary":"Just a title","value":{"title":"Ship the changelog"}},"full":{"summary":"Placed in a column, with a due date and an assignee","value":{"title":"Ship the changelog","notes":"Draft is in the shared doc.","status":"in-progress","priority":"high","due_date":"2026-09-01T17:00:00Z","assignees":[{"user_id":42}],"actor":"release-bot"}}}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/TaskCreateRequest"},{"type":"object","properties":{"files":{"type":"array","description":"Up to 20 files per task, 25MB each.","items":{"type":"string","format":"binary"}}}}]}}}},"responses":{"201":{"description":"The task that was created.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This API key is read-only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The JSON request body is larger than 512KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The task could not be saved. `details` carries the per-field errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/task-list/tasks/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"The task id. Scoped to the list the API key names — an id belonging to another list is a 404, not a way to read across calendars.","schema":{"type":"integer","format":"int64"}}],"get":{"operationId":"getTask","summary":"Get one task in full","description":"Returns a single task whole — status, priority, people, provenance, the comment thread and signed links to every attachment.","tags":["Tasks"],"x-required-scope":"tasks:read","parameters":[{"name":"include","in":"query","required":false,"description":"Which nested collections to embed. Omit for both comments and attachments; send `none` for neither.","schema":{"type":"string","examples":["none","comments","attachments"]}}],"responses":{"200":{"description":"The task.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No task with that id on this list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateTask","summary":"Update a task (PATCH)","description":"Applies the fields present in the body and leaves every other field alone — including with PUT, which behaves as a partial update here rather than a replacement. Omitting a field is not the same as sending it null. To change which column a task sits in, prefer `moveTask`: it keeps `completed` and the column from disagreeing.","tags":["Tasks"],"x-required-scope":"tasks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskUpdateRequest"},"examples":{"retitle":{"summary":"Change the title","value":{"title":"Ship the changelog today"}},"complete":{"summary":"Mark it done","value":{"completed":true}}}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/TaskUpdateRequest"},{"type":"object","properties":{"files":{"type":"array","description":"Files to add to the task. Existing attachments are kept.","items":{"type":"string","format":"binary"}}}}]}}}},"responses":{"200":{"description":"The updated task.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This API key is read-only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No task with that id on this list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The JSON request body is larger than 512KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The task could not be saved. `details` carries the per-field errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"replaceTask","summary":"Update a task (PUT)","description":"Applies the fields present in the body and leaves every other field alone — including with PUT, which behaves as a partial update here rather than a replacement. Omitting a field is not the same as sending it null. To change which column a task sits in, prefer `moveTask`: it keeps `completed` and the column from disagreeing.","tags":["Tasks"],"x-required-scope":"tasks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskUpdateRequest"},"examples":{"retitle":{"summary":"Change the title","value":{"title":"Ship the changelog today"}},"complete":{"summary":"Mark it done","value":{"completed":true}}}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/TaskUpdateRequest"},{"type":"object","properties":{"files":{"type":"array","description":"Files to add to the task. Existing attachments are kept.","items":{"type":"string","format":"binary"}}}}]}}}},"responses":{"200":{"description":"The updated task.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This API key is read-only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No task with that id on this list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The JSON request body is larger than 512KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The task could not be saved. `details` carries the per-field errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/task-list/tasks/{id}/move":{"parameters":[{"name":"id","in":"path","required":true,"description":"The task id. Scoped to the list the API key names — an id belonging to another list is a 404, not a way to read across calendars.","schema":{"type":"integer","format":"int64"}}],"post":{"operationId":"moveTask","summary":"Move a task to another column","description":"Moves a task between columns. This is its own operation rather than a field on update because completion has to move with it — moving a task into the completed column marks it done, and moving it out un-marks it, so the flag and the column can never disagree. Name the column by slug, display name or id; `getTaskList` returns all three for every column.","tags":["Tasks"],"x-required-scope":"tasks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","description":"The destination column, by slug, display name or stored id."},"kanban_status":{"type":"string","description":"Accepted as an alias for `status`. Prefer `status`."}}},"examples":{"toVerify":{"value":{"status":"verify"}}}}}},"responses":{"200":{"description":"The task after the move.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This API key is read-only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No task with that id on this list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"No `status` was sent, or it is not a column on this list. The `message` lists the columns that are.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/task-list/tasks/{id}/comments":{"parameters":[{"name":"id","in":"path","required":true,"description":"The task id. Scoped to the list the API key names — an id belonging to another list is a 404, not a way to read across calendars.","schema":{"type":"integer","format":"int64"}}],"post":{"operationId":"createTaskComment","summary":"Comment on a task","description":"Adds a comment to a task's thread. An API key names a list, not a person, so every comment posted this way is a guest comment: send `author_name` (or `actor`) to say who it is from, or the thread will attribute it to \"API\". Send `multipart/form-data` with `files[]` to attach up to 5 files — a CI job can post the log it is complaining about rather than a link to it. Returns the whole task, so the caller sees the refreshed thread.","tags":["Comments"],"x-required-scope":"tasks:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentCreateRequest"},"examples":{"fromCI":{"summary":"A note from an automated caller","value":{"body":"Reproduced on main at 4f2c1a9.","author_name":"ci-bot"}}}},"multipart/form-data":{"schema":{"allOf":[{"$ref":"#/components/schemas/CommentCreateRequest"},{"type":"object","properties":{"files":{"type":"array","description":"Up to 5 files per comment.","items":{"type":"string","format":"binary"}}}}]}}}},"responses":{"201":{"description":"The task, including the new comment.","content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"401":{"description":"The API key is missing or unrecognised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"This API key is read-only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No task with that id on this list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The JSON request body is larger than 512KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The comment had no `body`, carried too many files, or could not be saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong handling the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"moveApiKey":{"type":"http","scheme":"bearer","bearerFormat":"Move API key (move_…)","description":"The task list's API key, sent as `Authorization: Bearer move_…`. Mint and rotate it on the list's Integrations page.\n\n`tasks:read` — Read the task list, its columns and its tasks, including comments and signed attachment links.\n\n`tasks:write` — Create, update, move and comment on tasks. Granted only to a key whose task list has writes switched on.","x-scopes":{"tasks:read":"Read the task list, its columns and its tasks, including comments and signed attachment links.","tasks:write":"Create, update, move and comment on tasks. Granted only to a key whose task list has writes switched on."}},"moveApiKeyHeader":{"type":"apiKey","in":"header","name":"X-Move-Api-Key","description":"The same API key, for clients that can only send a fixed custom header.","x-scopes":{"tasks:read":"Read the task list, its columns and its tasks, including comments and signed attachment links.","tasks:write":"Create, update, move and comment on tasks. Granted only to a key whose task list has writes switched on."}}},"schemas":{"TaskList":{"type":"object","description":"A task list and what this API key may do to it.","required":["id","title","sections","counts","permissions"],"properties":{"id":{"type":"integer","format":"int64","description":"The task list id."},"title":{"type":"string","description":"The list name as shown in Move."},"description":{"type":["string","null"],"description":"The list summary, if one is set."},"calendar":{"type":"object","description":"The Move calendar the list lives on.","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":["string","null"]},"slug":{"type":["string","null"]}}},"kanban_enabled":{"type":"boolean","description":"Whether the list is in Kanban mode. A list that is not still answers the reserved `open` and `completed` status filters."},"sections":{"type":"array","description":"The columns, in board order. These are the only valid `status` values.","items":{"$ref":"#/components/schemas/Section"}},"counts":{"type":"object","description":"Task totals for the whole list, not for the current page.","properties":{"total":{"type":"integer"},"open":{"type":"integer"},"completed":{"type":"integer"}}},"permissions":{"type":"object","description":"What this key may do. `write` false means every write returns 403 read_only.","properties":{"read":{"type":"boolean"},"write":{"type":"boolean"}}},"url":{"type":["string","null"],"format":"uri","description":"The list in the Move web app."}}},"Section":{"type":"object","description":"One column on the board.","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"The stored id. Survives a rename, which is why a client that caches a column should key off this.","examples":["completed","section_2845be76"]},"slug":{"type":"string","description":"The readable alias, derived from the name. Prefer this when a person or a model has to read it.","examples":["verify","in-progress"]},"name":{"type":"string","description":"The column name as shown on the board."},"color":{"type":["string","null"],"description":"The column colour, if one is set."},"position":{"type":"integer","description":"Left-to-right board order, from 0."},"task_count":{"type":"integer","description":"How many tasks sit in this column."}}},"Task":{"type":"object","description":"A task on the list. `comments` and `attachments` are present unless the request narrowed `include`.","required":["id","title","status","completed"],"properties":{"id":{"type":"integer","format":"int64"},"title":{"type":["string","null"],"description":"The task title."},"notes":{"type":["string","null"],"description":"Free-text notes on the task."},"status":{"type":["string","null"],"description":"The stored column id. May name a column that has since been deleted, in which case `status_slug` and `status_name` are null."},"status_slug":{"type":["string","null"],"description":"The column slug."},"status_name":{"type":["string","null"],"description":"The column display name."},"completed":{"type":"boolean","description":"Whether the task is done."},"priority":{"type":["string","null"],"enum":["low","normal","high",null],"description":"Task priority. New tasks default to `normal`."},"position":{"type":["integer","null"],"description":"Order within its column."},"due_date":{"type":["string","null"],"format":"date-time"},"reminder_time":{"type":["string","null"],"format":"date-time"},"duration":{"type":["string","null"],"description":"Estimated duration, as stored on the task."},"recurring":{"type":["object","null"],"description":"Present only when the task repeats.","properties":{"interval":{"type":["string","null"],"enum":["daily","weekly","bi-weekly","monthly","quarterly","yearly",null]},"ends_at":{"type":["string","null"],"format":"date-time"}}},"requesters":{"type":"array","description":"Who asked for it.","items":{"$ref":"#/components/schemas/Person"}},"assignees":{"type":"array","description":"Who is doing it.","items":{"$ref":"#/components/schemas/Person"}},"created_by":{"type":["object","null"],"description":"The Move user who created the task. Null for a task created by an API key.","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":["string","null"]},"email":{"type":["string","null"]}}},"source":{"type":["object","null"],"description":"How the task arrived, when it came from an integration rather than from the board. Tasks created through this API carry kind `api`.","properties":{"kind":{"type":["string","null"]},"label":{"type":["string","null"]},"url":{"type":["string","null"],"format":"uri"},"reference":{"type":["string","null"]},"environment":{"type":["string","null"]},"level":{"type":["string","null"]},"occurrences":{"type":"integer"},"last_seen_at":{"type":["string","null"],"format":"date-time"},"submitted_by":{"type":["string","null"]},"submitted_by_email":{"type":["string","null"]}}},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"url":{"type":["string","null"],"format":"uri","description":"The task in the Move web app."},"comments":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}}},"TaskCreateRequest":{"type":"object","description":"A new task. Only `title` is required.","required":["title"],"additionalProperties":false,"properties":{"title":{"type":"string","description":"The task title."},"notes":{"type":"string","description":"Free-text notes."},"status":{"type":"string","description":"The column, by slug, display name or stored id."},"kanban_status":{"type":"string","description":"Accepted as an alias for `status`."},"completed":{"type":"boolean","description":"Wins over whatever the column implied, and drags the column with it."},"priority":{"type":"string","enum":["low","normal","high"]},"due_date":{"type":"string","format":"date-time"},"reminder_time":{"type":"string","format":"date-time"},"duration":{"type":"string","description":"Estimated duration."},"assignees":{"type":"array","description":"Who is doing it. A `user_id` must be a member of the list's calendar — an id that is not is dropped, so an API key cannot attach a stranger to a task. Guests (name and email) pass through untouched.","items":{"$ref":"#/components/schemas/Person"}},"requesters":{"type":"array","description":"Who asked for it. Same membership rule as `assignees`.","items":{"$ref":"#/components/schemas/Person"}},"actor":{"type":"string","description":"A label for whoever or whatever made this call, shown on the task.","examples":["release-bot"]}}},"TaskUpdateRequest":{"type":"object","description":"The fields to change. Anything omitted is left alone.","minProperties":1,"additionalProperties":false,"properties":{"title":{"type":"string","description":"The task title."},"notes":{"type":"string","description":"Free-text notes."},"status":{"type":"string","description":"The column, by slug, display name or stored id."},"kanban_status":{"type":"string","description":"Accepted as an alias for `status`."},"completed":{"type":"boolean","description":"Wins over whatever the column implied, and drags the column with it."},"priority":{"type":"string","enum":["low","normal","high"]},"due_date":{"type":"string","format":"date-time"},"reminder_time":{"type":"string","format":"date-time"},"duration":{"type":"string","description":"Estimated duration."},"assignees":{"type":"array","description":"Who is doing it. A `user_id` must be a member of the list's calendar — an id that is not is dropped, so an API key cannot attach a stranger to a task. Guests (name and email) pass through untouched.","items":{"$ref":"#/components/schemas/Person"}},"requesters":{"type":"array","description":"Who asked for it. Same membership rule as `assignees`.","items":{"$ref":"#/components/schemas/Person"}},"actor":{"type":"string","description":"A label for whoever or whatever made this call, shown on the task.","examples":["release-bot"]}}},"CommentCreateRequest":{"type":"object","description":"A comment to add to a task's thread.","required":["body"],"additionalProperties":false,"properties":{"body":{"type":"string","description":"The comment text."},"author_name":{"type":"string","description":"Who the comment is from. Defaults to \"API\" when neither this nor `actor` is sent."},"author_email":{"type":"string","format":"email"},"actor":{"type":"string","description":"Used as the author when `author_name` is absent."},"pinned":{"type":"boolean","description":"Pin the comment to the top of the thread."}}},"Comment":{"type":"object","description":"One comment. Replies hang off a top-level comment, one level deep.","required":["id","body"],"properties":{"id":{"type":"integer","format":"int64"},"body":{"type":"string"},"author":{"type":["string","null"]},"author_user_id":{"type":["integer","null"],"format":"int64","description":"Set when a Move user wrote it; null for a guest or an API comment."},"pinned":{"type":"boolean"},"resolved":{"type":"boolean"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"created_at":{"type":["string","null"],"format":"date-time"},"replies":{"type":"array","description":"Replies to this comment. Present on top-level comments only.","items":{"type":"object"}}}},"Attachment":{"type":"object","description":"A file attached to a task or a comment.","required":["id","filename"],"properties":{"id":{"type":"integer","format":"int64"},"filename":{"type":"string"},"content_type":{"type":["string","null"]},"byte_size":{"type":["integer","null"],"format":"int64"},"checksum":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"url":{"type":["string","null"],"format":"uri","description":"A signed link that expires. Follow it now rather than storing it."}}},"Person":{"type":"object","description":"Someone on a task — either a Move user (`user_id`) or a guest (`name` and `email`).","properties":{"user_id":{"type":["integer","null"],"format":"int64"},"name":{"type":["string","null"]},"email":{"type":["string","null"],"format":"email"}}},"Pagination":{"type":"object","description":"Where this page sits in the filtered set. `total` counts every matching task, not the ones on this page.","required":["page","per_page","total","pages"],"properties":{"page":{"type":"integer","description":"The page returned, from 1."},"per_page":{"type":"integer","description":"How many were asked for, after clamping."},"total":{"type":"integer","description":"Matching tasks across all pages."},"pages":{"type":"integer","description":"How many pages that is."}}},"Error":{"type":"object","description":"A failed request.","required":["error","message"],"properties":{"error":{"type":"string","description":"A stable machine-readable code. Branch on this.","enum":["missing_key","invalid_key","read_only","task_not_found","invalid_status","invalid_comment","too_many_files","invalid","body_too_large","server_error"]},"message":{"type":"string","description":"A human-readable explanation that says how to fix it."},"details":{"type":["object","null"],"description":"Per-field validation errors, when the failure was a validation failure.","additionalProperties":true},"documentation_url":{"type":"string","format":"uri","description":"Where this error is documented."}}}}},"x-oauth-protected-resource":"https://m0ve.app/.well-known/oauth-protected-resource"}