参照ガイド:API の詳細仕様。
SHA-256 a1aa9241884b7a21541d1bec245004a46298a7376c8d15b30969d5f62256d270
# API reference
Use the section or method needed for this operation. Client transport is described in [connection.md](connection.md).
`license.show {}` opens the Ploto Pro license dialog for purchase or serial-code activation. It needs no project editing permission and makes no purchase or project mutation. The reply includes `product:"pro"`, `dialogRequested:true` and `purchased:false`. A `pro_required` rejection from a board mutation also requests this dialog automatically. See [Kanban](kanban.md#when-pro-is-missing) for when to open it and how to explain a blocked request briefly.
Every HTTP call is `POST $PLOTO_API_URL`, `Authorization: Bearer <token>`, `Content-Type: application/json`, with `{ "id": "unique-request-id", "method": "context", "params": {} }`. No browser Origin header. Replies have `{ "ok": true, "result": ... }` or `{ "ok": false, "error": { "code": ..., "message": ... } }`. The PowerShell client prints JSON and exits nonzero on an error. Its generated request ID is included in the output. `-ParamsFile` accepts UTF-8 JSON to avoid shell quoting problems. `-RequestId` permits an exact retry. `-Compact` prints the reply without pretty-printing whitespace and works with every method, including `batch.execute`; use it on every call.
Supported methods:
Kanban: `board.list`, `board.select`, `board.get`, `board.create`, `board.update`, `board.task.move`, and `board.todo.update`. See [Kanban](kanban.md) for exact parameters, standard templates and enforced movement rules. `task.get` also works on the selected board. Task responses include read-only `kanban` membership with board/stage ids and names, or null when unassigned. Board writes are sequential and not supported inside `batch.execute`.
Task rows also include read-only `health`, sharing the Gantt health line/tooltip evaluator: `status` is the worst status across the subtree, `own` gives this task's evaluation/reasons, `todos` gives its own remaining/overdue/today ToDo counts, and `descendants` gives danger/warning descendant counts. List/search/detail/full task mutation responses and schedule reviews include `healthContext` (`asOf`, local `today`, `timeZone`). `health.todos` still reports unfinished ToDos on complete or future parents. These are computed metadata, never fields to write back. See [reading](reading.md) for the exact semantics.
Optional priority is exposed as `priority: { "importance": 75, "urgency": 25 }`. Each independent score is a finite number from 0 to 100; importance is the vertical axis and urgency is horizontal. Both are required when setting a position, and extra keys are rejected. `task.add` accepts `priority` at the top level; `task.update` and `task.preview` accept it in `changes`, including within task mutations in `batch.execute`. Send `null` to clear it, or omit it to preserve the current value on update / leave a new task unassigned. Valid assigned priorities are included in `tasks.list` (outline/full), `tasks.search`, `tasks.schedule`, `task.get` and full mutation responses; otherwise the field is omitted. Internal `matrix_x`/`matrix_y` are not API parameters. Read [planning](planning.md) for when and how to assess priority rather than rating every task by default.
Tags are exposed by name as `tags: ["review", "legal"]`. `context.tags` lists every tag name in the project (the shared vocabulary). `task.add` accepts `tags` at the top level; `task.update` and `task.preview` accept it in `changes`, including within task mutations in `batch.execute`. It replaces the task's complete list; `[]` or `null` removes all tags and omitting it preserves them. Names are matched to existing tags ignoring case, full/half-width and repeated spaces; at most 20 names per task, each 1–50 characters without `<`, `>`, commas or control characters. An unmatched name creates a new project-wide tag before the write is applied; the reply lists such names in `createdTags` (`task.preview` reports them in `newTags` and creates nothing). Assigned tags are included in `tasks.list` (outline/full), `tasks.search`, `tasks.schedule`, `task.get` and full mutation responses; otherwise the field is omitted. Tag IDs and colors are not API fields, and tags cannot be renamed, recolored or deleted through the API. Read [planning](planning.md) before tagging.
`context.showWbs` always reports the current WBS numbering setting. When true, tasks returned by `tasks.list` (outline/full), `tasks.search`, `tasks.schedule`, `task.get`, and full task mutation responses include a read-only `wbs` string. When false, this field is omitted. Values reflect the visible chart's numbering, or stored hierarchy/order for other charts. Numbers belong to one Gantt and may change with structure or sorting. Use returned numbers in conversation, resolve them to task IDs for API calls, and never generate numbers or write them into task names, notes or ToDos. `wbs` is not a writable parameter.
- `tasks.schedule`: `{ "period":"today", "match":"due", "limit":20 }`; read-only date filtering, with optional `scope`, `from`/`to`, `includeCompleted`, `includeSummaries`, `tags`, and `offset`. Defaults to incomplete leaf tasks due today in the visible Gantt. Returns outline rows with `due_date`, resolved date range/timezone, `total`, `undated`, `truncated`, and `nextOffset` when more rows exist. See [daily review](schedule.md) for presets, inclusive date semantics and all parameters.
- `context`: current file path, exact `activeTab`, read-only state, the project's tag names `tags`, Gantt readiness and group, localized human-facing `labels` (`gantt`, `task`, `todo`, `assignee`, `link`), and an error summary (`errorCount`, `hasNewErrors`, `errorCursor`) without error bodies. The first `context` call of a session also returns the static API description (`apiVersion`, `methods`, `durationUnit`, `endDateSemantics`, `taskAddDefaults`, `readTiers`, `persistence`) with `static:true`; later calls omit it and return `static:false`, because it cannot change while the session lives. Pass `{"static":true}` to get it again. This omission is expected — keep calling `context` before every write sequence; it stays cheap. It succeeds on non-Gantt tabs with `gantt:null`, `ganttReady:false`, and `ganttError:"active_tab_not_gantt"`.
- `members.list`: returns the project roster as `{ members: [{ id, name }] }`. Use it when assigning a ToDo or when the user asks about project members; omit routine roster reads for unrelated work. Names are never accepted in place of assignee IDs.
- `highlight.set`: `{ "taskIds": ["task-id"], "tabIds": ["tab-id"] }`; optionally marks additional items for user review without changing or dirtying the project. Normal task edits are highlighted automatically, so do not call this after routine mutations. Both arrays are optional, but at least one ID is required. Task IDs belong to the active Gantt and must exist. Tab IDs come from `context.tabs`; the active tab is deliberately skipped because the user is already looking at it. Highlighted rows, bars, and inactive tabs remain marked until the user clicks them. Do not highlight deleted tasks because they no longer exist.
- `errors.list`: `{ "after": 12, "limit": 20 }`; returns captured Ploto error entries after an optional cursor. `limit` defaults to 20 and accepts 1–100. The result includes `nextCursor`, the latest global `errorCursor`, and `truncated`; while truncated, continue from `nextCursor` rather than `errorCursor`. Omit `after` to start with errors captured since this automation session began.
- `gantt.list`: lists sidebar Gantts as `{ id, viewId, name, active }`; parameters `{}`.
- `gantt.create`: `{ "name": "Release plan", "empty": true }`; creates and selects a sidebar Gantt. `empty` defaults to false for UI-compatible behavior; set it to true to omit the starter task. A successful reply can contain `ready:false` while the new view finishes loading; the Gantt was still created, so wait `retryAfterMs` and use `context` rather than creating it again.
- `gantt.move`: `{ "id": "gantt-id", "before": "other-gantt-id" }` or use `after`; changes the order in the sidebar. IDs are the Gantt IDs returned by `gantt.list`, not view IDs.
- `gantt.select`: `{ "id": "gantt-id" }`; selects and opens a sidebar Gantt by the `id` returned from `gantt.list`.
- `tasks.list`: `{ "response": "outline", "parent": "task-id", "depth": 2, "scope": "gantt" }`; current Gantt tasks and dependency links, including unsaved model edits. Every parameter is optional and `{}` returns the whole chart as a structure outline. `response` defaults to `"outline"`: `id`, `text`, `parent`, derived `type`, `start_date`, `duration`, read-only `last_day`, `progress`, `color`, `pinned`, `revision`, the direct-child count `children`, and the `note_chars`/`todo_count`/`todo_done` signals described under **Reading**. `"full"` adds complete note text and ToDo objects for every returned task and is rarely the right choice on a large chart — prefer `task.get` for the few tasks you actually need. Combining `"full"` with `parent` is the reasonable middle ground when you need the detail of one subtree. `parent` limits the walk to that task and its descendants, and the named task is included as the first row. `depth` (1–20) counts levels below each root: `1` stops at the direct children. When a task's children were cut off, the reply carries `truncated:true`, so drill in with `parent` rather than assuming the chart ends there. Dependency links touching any returned task are always included, including links that leave the subtree. The response includes the target `gantt` object. With `scope:"project"` this becomes a project-wide skeleton and only `depth` still applies: `response:"full"` and `parent` are rejected there, because one addresses a single Gantt and the other would pull every note in the file into the conversation. `'{"scope":"project","depth":1}'` is the cheap "what plans exist and what are their top-level phases" call.
- `tasks.search`: `{ "query": "ベンダー 契約", "tags": ["法務"], "in": ["name","note","todo"], "limit": 20, "offset": 0, "scope": "gantt" }`; finds tasks by keyword and/or tag. `tags` keeps only tasks carrying every listed tag (matched like writes, ignoring case and width); `query` may be omitted when `tags` is given, which lists that tag's tasks. Tag names that no task in the searched scope carries are returned in `unknownTags` — check them against `context.tags` for a typo rather than concluding the category is empty. Search finds tasks by keyword — in the current Gantt by default, or across every sidebar Gantt with `scope:"project"`. Matching is a case-insensitive literal substring, and space-separated terms are ANDed — each term must appear somewhere in the task, not all in the same field. There is no tokenizer and no regular-expression support, so partial words and Japanese text match directly. `in` defaults to all three fields; `limit` defaults to 20 and caps at 50. Results come back strongest first: a task where one field contains every term outranks one that only matches across fields (the name holding one term and a ToDo another), so narrowing `limit` drops the weak matches rather than the strong ones. Each hit is a structure row plus `path` (the ancestor names, for orientation) and `matched`, which names the fields that hit: a `todo` match carries the ToDo itself, and a `note` match carries a `snippet`. **A `note` match with `complete: true` is the entire note, verbatim** — you have already read it, so do not call `task.get` for it, and it is safe to build an appended note on. Without `complete` the snippet is an excerpt: up to three passages cut from around the matches and joined by ` … `, with a leading or trailing `…` when text was dropped at either end. Those gaps hold text you have not seen, and there may be further mentions beyond the three shown, so read the whole note with `task.get` before summarizing or rewriting it. Whole notes are rationed across the reply — short notes on the strongest hits get them, and once the budget is spent the remaining hits fall back to excerpts — so check `complete` on each match instead of assuming a short note always arrives whole. The reply's `total` is the number of matching tasks before `limit`, with `truncated:true` when hits were dropped — narrow the query rather than raising `limit` to the maximum. When every hit is needed (for example all tasks with a tag), continue with `offset` set to the reply's `nextOffset`. In project scope `limit` counts across all Gantts, not per Gantt, and every hit carries its own `gantt`. Use `task.get` on a hit when you need the complete note — but only after `gantt.select`, since `task.get` reads the selected Gantt.
- `task.get`: `{ "id": "..." }`; returns one task in full — complete note text, every ToDo — and a non-null current revision.
- `task.preview`: accepts the same parameters as `task.update`, validates its revision and changes, but does not mutate anything. It returns changed fields, before/after values, and `noteChars` before/after for note edits.
- `task.add`: `{ "text": "Design", "start_date": "2026-09-07", "duration": 3, "progress": 0.5, "parent": "0", "type": "task", "color": "green-base", "tags": ["vendor"], "note": "Scope agreed with the vendor.", "todos": [{ "text": "Draft" }], "before": "sibling-id" }`. Only the name is required; start date defaults to today, duration to 1, progress to 0, parent to `"0"` (root), and type to `"task"`. Use `before` or `after` to insert among the destination parent's existing children; omit both to append. Use type `"project"` only to create an explicit summary task inside the current Gantt; it does not create a sidebar Gantt. **You cannot choose the ID.** Ploto assigns a short ID and returns it in the reply; sending `id` is rejected. Inside a batch, add `ref` to name the new task for the rest of that request and refer to it as `"@design"` — see `batch.execute`. `ref` is meaningless outside a batch and is rejected there, because a lone `task.add` already returns the ID.
- `task.update`: `{ "id": "...", "revision": "r1-...", "changes": { "text": "New name", "color": "#22c55e" } }`. First retrieve the short revision token with `task.get` or `tasks.list`. Editable fields: `text`, `start_date`, `duration`, `progress`, `pinned`, `color`, `priority`, `tags`, `note`, `note_append`, `note_patch`, `todos`. Use only one note operation: `note` replaces the whole note; `note_append` appends text after a blank line; note text is the limited Markdown described in [notes.md](notes.md); `note_patch` is `{ "find": "exact old text", "replace": "new text", "all": false }` and rejects missing or ambiguous matches unless `all:true`. Send the literal revision `"latest"` only when the user explicitly prefers an unconditional last-write-wins update. Progress is a fraction from 0 to 1 and can be set only on manually tracked leaf tasks. Dates/duration on summary tasks are not editable through this API. Unsupported fields are rejected.
- `task.move`: `{ "id": "...", "revision": "...", "parent": "parent-id", "before": "sibling-id" }`. Moves a task (including its descendants) to a new parent and/or sibling position. `parent` defaults to the current parent; use `"0"` for the root. Use `before` or `after`, not both; omit both to append. Moving into itself or a descendant is rejected.
- `task.delete`: `{ "id": "...", "revision": "r1-..." }`. First retrieve the task with `task.get` and use its latest revision token. `"latest"` is also accepted with the same last-write-wins warning. Deleting a summary task also deletes all descendants and every dependency link touching any deleted task. The response lists all deleted task and link IDs. Never delete a starter task by name alone; first confirm from the current Gantt that it is the unwanted initial placeholder.
- Task `color` accepts a Ploto palette ID or a six-digit `#RRGGBB` value. Prefer a Ploto palette color whenever possible so tasks remain consistent with the app theme and each other. If the user's requested color is approximate or named (for example, “light green” or “dark red”), choose the closest preset instead of inventing a HEX value. Use custom HEX only when the user explicitly supplies an exact color, requests a brand color, or a suitable preset does not exist. Palette IDs combine one hue (`red`, `orange`, `green`, `blue`, `purple`, `grey`) with one tone (`base`, `lightest`, `light`, `dark`), for example `orange-light` or `purple-dark`. Send `null` to restore the default blue. Custom-color text contrast is selected automatically. Never send CSS functions, variables, shorthand hex, alpha hex, or a separate text color.
- For note semantics and safe text input, read [notes.md](notes.md).
- For checklist replacement and progress behavior, read [todos.md](todos.md).
- `link.add`: `{ "source": "predecessor-task-id", "target": "successor-task-id", "type": "finish_to_start" }`. Both tasks must exist in the current group. `type` is optional and defaults to `finish_to_start`; alternatives are `start_to_start`, `finish_to_finish`, and `start_to_finish`. As with tasks, Ploto assigns the link ID and returns it; sending `id` is rejected. `source` and `target` accept a `@ref` naming a task the same batch created. Self-links, duplicate directions, and circular dependencies are rejected.
- `link.update`: `{ "id": "link-id", "source": "task-id", "target": "task-id", "type": "start_to_start" }`; omitted source, target, or type values retain their current values. Duplicate and circular dependencies are rejected.
- `link.delete`: `{ "id": "link-id" }`; deletes the dependency returned by `tasks.list`.
- `batch.execute`: `{ "response": "minimal", "operations": [{ "method": "gantt.create", "params": {"name":"Plan"} }, { "method": "task.add", "params": {...} }] }`. Executes up to 200 task/link/icon mutations in order as one Undo and scheduling step. Each operation's `method` may be dotted (`task.add`) or underscored (`task_add`). A single `gantt.create` may be the first operation; it always creates an empty Gantt before applying the remaining operations. To refer to a task the batch itself creates, give its `task.add` a `ref` (a short name of letters, digits, `_` or `-`, unique within the request) and write `"@thatname"` wherever a task ID is expected in a later operation: `parent`, `before`, `after`, `source`, `target`, and the `id` of `task.update` / `task.move` / `task.delete`. A `@ref` with no earlier `task.add` to define it is an error. `ref` is a name for this request only — it is never stored on the task — so the reply maps each one to the ID Ploto assigned (`refs: [{ "ref": "ph-uat", "id": "k3m9qa" }]`, present in every `response` mode). Use those IDs in later requests; the `@ref` form does not survive past the batch. A task created earlier in the same batch can be updated or moved without a revision. Existing tasks still require a revision. `response` selects how much comes back: `"minimal"` returns only `{"applied":<count>}` and is the right default for a plain bulk write, `"summary"` returns IDs and short revisions instead of complete task objects, and `"full"` (the default) returns complete objects. A batch is all or nothing, so success needs no per-operation detail; a failure is an error reply whose message names the failing operation number and the reason, and nothing was applied. `gantt.select` and `gantt.move` are not allowed inside a batch. If this form returns `ready:false` and `operationsApplied:false`, the Gantt exists but the remaining operations were not applied; wait `retryAfterMs`, then submit only those remaining operations without repeating `gantt.create`.
- `icons.list`: `{ "from": "2026-09-01", "to": "2026-09-30", "taskId": "task-id", "query": "release", "limit": 100, "scope": "gantt" }`; every parameter optional. Returns icon markers on live task rows sorted by date as `{ id, task_id, task_name, path, wbs, date, symbol, color, color_name, label, notes }` (empty fields omitted), plus `total`, `truncated` and `nextOffset`. `taskId` is rejected with `scope:"project"`, where each row carries `gantt`. See [icons](icons.md).
- `icon.add`: `{ "task_id": "task-id", "date": "last_day", "symbol": "Flag", "color": "blue", "label": "Release", "notes": "Store submission" }`; only `task_id` and `date` are required. `date` is `YYYY-MM-DD` or `"last_day"` (the task's `last_day` at write time; not updated when the schedule later moves). Symbol defaults to `Star`, color to `yellow`. Ploto assigns the icon ID; sending `id` is rejected. One icon per task row and day (`icon_cell_occupied` with `details.existingId`). Returns `icon`.
- `icon.update`: `{ "id": "icon-id", "date": "2026-10-02", "label": null }`; omitted fields keep their values, `null` clears `label` or `notes`. `task_id`/`date` move the icon. Last write wins; no revision.
- `icon.delete`: `{ "id": "icon-id" }`.
- `symbol` is one of `Star`, `Flag`, `AlertTriangle`, `CheckCircle2`, `Bookmark`, `Sun`, `Moon`, `Cloud`, `CloudRain`, `CloudSnow`, `CloudLightning`, `Wind`, `Umbrella`. `color` is a name (`yellow`, `orange`, `red`, `pink`, `purple`, `indigo`, `blue`, `cyan`, `teal`, `green`, `lime`, `brown`, `grey`, `black`) or `#RRGGBB`. `label` is one line of at most 60 characters shown on the chart; `notes` is plain text of at most 2,000 characters shown on hover. Icon methods are accepted inside `batch.execute`, where `task_id` may be a `@ref`. Task rows in list/search/schedule replies carry `icon_count`, `task.get` returns the task's `icons`, and `tasks.schedule` returns `icons`/`iconsTotal` within its date range.
- `access.request`: `{ "reason": "Add the exam milestones you asked for" }`; allowed while editing is off. Ploto shows the user a permission dialog and waits up to about 25 seconds. `status` is `granted` (editing is on; retry writes directly), `denied` (stay read-only; a repeat request within a minute returns `denied` without a dialog), `pending` (the dialog is still open; tell the user and check `context.allowWrite` later rather than requesting again), or `already_enabled`. `read_only_file` means the file is read-only and editing cannot be enabled.
- Every method name also works with underscores instead of dots (`task_add`), matching MCP tool names.
- `skill`: returns this instruction text.
Ploto error entries have `sequence`, `timestamp`, `source`, and the complete human-readable `message`. Error toasts, alert dialogs, logged application errors, uncaught window errors, and unhandled promise rejections are captured in a bounded recent history. A successful API result includes `plotoErrors` only when Ploto emitted errors during that request; a failed result follows the same per-request rule. `context` never repeats error bodies: it returns `errorCount`, `hasNewErrors`, and `errorCursor`, where the count/signal cover entries since the preceding `context` call. Errors that occur asynchronously after a reply, such as a delayed working-copy save failure, therefore set `hasNewErrors`; retrieve their bodies with `errors.list` using the previous cursor. Inspect `plotoErrors` in every response. After a substantial mutation, call `errors.list` with the previous `errorCursor`; do not report unconditional success when a captured error may affect the requested result. Explain relevant messages accurately enough to identify the problem, translating raw IDs into visible names for the user, while recognizing that the same underlying failure may appear from more than one source.
Inspect the task objects to understand `group_id`, parent IDs, dates, duration, progress and `auto_progress`. API duration always counts calendar days, even when the UI displays working days. `end_date` is exclusive: a one-day task starting March 31 ends at the boundary on April 1. Task rows therefore also carry read-only `last_day`, the last calendar day the task occupies (the start date for a zero-day task); quote it instead of calculating `start_date + duration - 1` yourself. Automatic scheduling may move dependent tasks, so an omitted `task.add.start_date` initially defaults to today and can then be replaced by scheduling. After a schedule edit, verify the affected scope as described under Reading. Close the task detail editor before writing; `close_task_editor` means it has draft state that must not be overwritten, and it also blocks `task.get`, whose revision would already be behind. `tasks.list` and `tasks.search` still work while it is open — the task being edited comes back marked `editing:true`, meaning the screen may be ahead of the model for that one row. Treat a marked row's values as provisional: fine for locating things, not something to quote back or write to until the user closes the editor. Confirm the target Gantt whenever the response includes it; a minimal batch response omits it.
## errors.list parameters
Both `{}` and a parameter object are valid. **The cursor parameter is `after`, not `sinceCursor`.**
| Parameter | Type and range | Default and meaning |
| --- | --- | --- |
| `after` | Non-negative integer | Omitted: session-start cursor. Return entries whose `sequence` is strictly greater than this cursor. Use a previously returned `context.errorCursor` to check only subsequent errors. |
| `limit` | Integer 1–100 | 20 entries per response. |
The response is `{errors, nextCursor, errorCursor, truncated}`. `nextCursor` is the last returned entry's sequence (or `after` when empty); `errorCursor` is the latest global cursor. If `truncated:true`, pass `after:nextCursor` to read the next page. Using the global cursor for the next page would skip entries. History is bounded, so this is recent captured errors, not an unlimited audit log. Use exact field names; unknown parameters are rejected.
```powershell
# Recent errors since this session started:
& $env:PLOTO_CLI errors.list -Compact
# Errors after a cursor obtained earlier; substitute that actual cursor:
& $env:PLOTO_CLI errors.list '{"after":12,"limit":20}' -Compact
```
<!-- PLOTO-DOC-END -->