{"openapi":"3.0.3","info":{"title":"Mnemo REST API","version":"2.9.3","description":"Personal access token API for pages, databases, comments, whiteboards, search, capture, and history.\n\n**Auth:** `Authorization: Bearer mnemo_…` (create under Settings → API & MCP). Write is the default scope; a read-only token stores `read` only. Optional resource grants (page subtrees and/or databases) are deny-closed when set.\n\n**Quota:** Free workspaces share **100** successful REST + MCP calls per UTC month. Pro is unlimited. OpenAPI JSON, this docs UI, and GET /formulas are unmetered. Over quota returns **429** with `code: MCP_QUOTA_EXCEEDED`, `resetsAt`, and `Retry-After` until month end. Burst limits (before quota): 120 req/min per IP, 300 req/min per token.\n\n**MCP:** the same capabilities are available at `POST /api/mcp` (Streamable HTTP). `create_subpage` is MCP-only (no REST twin).\n\nHosted docs: `GET /api/v1/docs`. Formula catalog: `GET /api/v1/formulas`."},"servers":[{"url":"/api/v1"}],"tags":[{"name":"Docs","description":"Unmetered discovery"},{"name":"Pages"},{"name":"Search"},{"name":"Attachments","description":"Text inside uploaded PDF, Word and text files"},{"name":"Databases"},{"name":"Comments"},{"name":"Whiteboards"},{"name":"Capture"},{"name":"History"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"mnemo_… PAT","description":"Settings → API & MCP. Resource grants, when set, deny anything outside the listed pages/databases."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"QuotaError":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string","enum":["MCP_QUOTA_EXCEEDED"]},"resetsAt":{"type":"string","format":"date-time","description":"When the Free allowance starts again (00:00 UTC on the 1st)"}}},"PageType":{"type":"string","enum":["document","database","whiteboard"]},"PageTreeNode":{"type":"object","required":["id","title","parentId","type","position","children"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true},"parentId":{"type":"string","nullable":true},"type":{"$ref":"#/components/schemas/PageType"},"position":{"type":"number"},"children":{"type":"array","items":{"$ref":"#/components/schemas/PageTreeNode"}}}},"Page":{"type":"object","required":["id","title","type","updatedAt","createdAt","body","bodyMarkdown"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true},"cover":{"type":"string","nullable":true},"type":{"type":"string"},"parentId":{"type":"string","nullable":true},"updatedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"body":{"type":"string","description":"Plaintext preview"},"bodyMarkdown":{"type":"string","description":"Markdown reconstructed from the live document (same format as File Export)"}}},"PageCreated":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string"},"title":{"type":"string"}}},"PageUpdated":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true}}},"CreatePageBody":{"type":"object","properties":{"title":{"type":"string"},"parentId":{"type":"string","nullable":true,"description":"null = workspace root"},"bodyMarkdown":{"type":"string","maxLength":100000,"description":"Initial page body (markdown, max 100,000 characters). Page links: `[[Title|pageId]]`, or a bare `[[Title]]`, which links the page the token can read with that exact title (any case; the most recently updated wins; no match stays plain text). Callouts open with `:::callout info` or `:::callout type=info` and close with `:::`; kinds are info, success or tip, warning, danger, alert or error, and note, or a colour id (blue, green, yellow, red, purple)."},"templateId":{"type":"string","description":"A document template id from GET /templates. Not with bodyMarkdown. Embedded databases and boards the token is not granted are left out."}}},"CreateWhiteboardBody":{"type":"object","properties":{"title":{"type":"string"},"parentId":{"type":"string","nullable":true,"description":"null = workspace root"},"icon":{"type":"string","nullable":true,"description":"Known picker lucide:<id> (optional #color) or a single emoji"},"templateId":{"type":"string","description":"A whiteboard template id from GET /templates. Images and page cards are left out."}}},"WhiteboardCreated":{"type":"object","required":["id","title","type"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string","enum":["whiteboard"]},"icon":{"type":"string","nullable":true}}},"PageVerification":{"type":"object","required":["pageId","freshness","verifiedAt","verifiedBy","stampName","reviewIntervalDays","bodyUpdatedAt","reviewDueAt"],"properties":{"pageId":{"type":"string"},"freshness":{"type":"string","enum":["none","verified","changed","due","unverified"],"description":"Derived: verified (stamped, unchanged, not due), changed (body written after the stamp), due (interval elapsed), unverified (interval set, never stamped), none (never opted in)."},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"verifiedBy":{"type":"object","nullable":true,"description":"The person who owns the stamp. `name` is the stamp line: the token name when an agent verified, otherwise this person.","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"stampName":{"type":"string","nullable":true,"description":"Token name when an agent verified. Null on a human stamp."},"reviewIntervalDays":{"type":"integer","nullable":true,"enum":[30,90,180,365,null]},"bodyUpdatedAt":{"type":"string","format":"date-time","nullable":true},"reviewDueAt":{"type":"string","format":"date-time","nullable":true}}},"PageOutline":{"type":"object","required":["pageId","headings"],"properties":{"pageId":{"type":"string"},"headings":{"type":"array","items":{"type":"object","required":["id","level","text"],"properties":{"id":{"type":"string","description":"Stable heading id. Survives edits to the heading's text and level; a paragraph turned into a heading gets a new one."},"level":{"type":"integer","minimum":1,"maximum":6},"text":{"type":"string"}}}}}},"ActivityList":{"type":"object","required":["entries","nextCursor"],"properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/ActivityEntry"}},"nextCursor":{"type":"string","nullable":true}}},"ActivityEntry":{"type":"object","required":["id","at","kind","page","actor","detail"],"properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"kind":{"type":"string","enum":["created","renamed","moved","archived","restored","verified","verification_cleared","body_edited","row_added"]},"page":{"type":"object","required":["id","title","type","isArchived"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true},"type":{"type":"string"},"isArchived":{"type":"boolean"}}},"actor":{"type":"object","required":["userId","name","agent"],"properties":{"userId":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"agent":{"type":"string","nullable":true,"description":"The token's name when an agent made the change."}}},"detail":{"type":"object","description":"Kind-specific facts: `from` / `to` titles for renamed; `fromParent` / `toParent`, `toTopLevel`, or `fromWorkspace` for moved (a parent the caller cannot open is null); `rowId` / `rowTitle` for row_added; `via` for body_edited when not typed (api, restore); `origin` for created when not made blank.","additionalProperties":true}}},"PageSection":{"type":"object","required":["pageId","heading","bodyMarkdown"],"properties":{"pageId":{"type":"string"},"heading":{"type":"object","required":["id","level","text"],"properties":{"id":{"type":"string"},"level":{"type":"integer","minimum":1,"maximum":6},"text":{"type":"string"}}},"bodyMarkdown":{"type":"string","description":"The section as Markdown, heading line first."}}},"ReviewQueueEntry":{"allOf":[{"$ref":"#/components/schemas/PageVerification"},{"type":"object","required":["title","type"],"properties":{"title":{"type":"string"},"type":{"type":"string"}}}]},"VerifyPageBody":{"type":"object","properties":{"note":{"type":"string","maxLength":500,"description":"Optional one-liner, e.g. \"checked the pricing table\""},"reviewIntervalDays":{"type":"integer","nullable":true,"enum":[30,90,180,365,null],"description":"Also set the re-verify cadence in the same call. Omit to leave it."}}},"ReviewIntervalBody":{"type":"object","required":["reviewIntervalDays"],"properties":{"reviewIntervalDays":{"type":"integer","nullable":true,"enum":[30,90,180,365,null],"description":"null opts the page out of review."}}},"UpdatePageBody":{"type":"object","properties":{"title":{"type":"string"},"icon":{"type":"string","nullable":true}},"description":"Title and/or icon. Cover is not writable on this endpoint."},"ContentBody":{"type":"object","properties":{"content":{"type":"string","maxLength":100000},"text":{"type":"string","maxLength":100000,"description":"Alias for `content`"}}},"SearchHit":{"type":"object","required":["id","title","type"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true},"type":{"type":"string"},"parentId":{"type":"string","nullable":true},"updatedAt":{"type":"string","format":"date-time"}}},"SearchRowHit":{"type":"object","required":["rowId","databaseId","pageId"],"properties":{"rowId":{"type":"string"},"databaseId":{"type":"string"},"pageId":{"type":"string"},"databaseTitle":{"type":"string"},"rowTitle":{"type":"string"},"snippet":{"type":"string"},"icon":{"type":"string","nullable":true}}},"Comment":{"type":"object","required":["id","pageId","authorId","body","createdAt"],"properties":{"id":{"type":"string"},"pageId":{"type":"string"},"parentId":{"type":"string","nullable":true},"authorId":{"type":"string"},"authorName":{"type":"string"},"body":{"type":"string"},"anchor":{"type":"string","nullable":true},"resolvedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"CreateCommentBody":{"type":"object","required":["body"],"properties":{"body":{"type":"string"},"parentId":{"type":"string","nullable":true},"anchor":{"type":"string","nullable":true}}},"Tag":{"type":"object","required":["id","name","color"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"}}},"TagIdsBody":{"type":"object","required":["tagIds"],"properties":{"tagIds":{"type":"array","items":{"type":"string"},"maxItems":50}}},"MovePageBody":{"type":"object","properties":{"parentId":{"type":"string","nullable":true,"description":"Null moves to the workspace root. A limited token cannot do that."},"position":{"description":"A non-negative integer, or `append` to place it last among siblings.","oneOf":[{"type":"integer","minimum":0},{"type":"string","enum":["append"]}]}}},"ResolveCommentBody":{"type":"object","required":["resolved"],"properties":{"resolved":{"type":"boolean"}}},"BatchBody":{"type":"object","required":["operations"],"properties":{"operations":{"type":"array","maxItems":20,"items":{"type":"object","required":["op"],"properties":{"op":{"type":"string"},"input":{"type":"object"}}}}}},"DatabaseSummary":{"type":"object","required":["id","title","pageId"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"pageId":{"type":"string"}}},"CreateDatabaseBody":{"type":"object","properties":{"title":{"type":"string"},"parentId":{"type":"string","nullable":true},"templateId":{"type":"string","description":"`blank`, a legacy starter name (maps to blank), or `tpl_…`"}}},"DatabaseCreated":{"type":"object","required":["id","pageId","title"],"properties":{"id":{"type":"string"},"pageId":{"type":"string"},"title":{"type":"string"},"templateId":{"type":"string"}}},"PropertyType":{"type":"string","enum":["text","number","select","multi_select","date","checkbox","relation","formula","person","url","email","phone","auto_id","created_time","last_edited_time"]},"SearchFileHit":{"type":"object","properties":{"id":{"type":"string","description":"Attachment id, for /attachments/{id}/text"},"filename":{"type":"string"},"contentType":{"type":"string"},"pageId":{"type":"string"},"pageTitle":{"type":"string"},"snippet":{"type":"string"}}},"AttachmentTextState":{"type":"string","enum":["ready","pending","empty","unreadable","not_text"]},"SelectOption":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string","enum":["gray","blue","green","orange","red","purple","yellow"]}}},"SelectOptionInput":{"description":"An option name, or `{ name, color }` to set its color.","oneOf":[{"type":"string"},{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":40},"color":{"type":"string","enum":["gray","blue","green","orange","red","purple","yellow"]}}}]},"DatabaseView":{"type":"object","required":["id","name","viewType","filter","isDefault"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"viewType":{"type":"string","enum":["table","kanban","gallery","calendar","chart"]},"filter":{"type":"object","description":"FilterGroup"},"sortPropId":{"type":"string","nullable":true},"sortDir":{"type":"string","enum":["asc","desc"]},"boardPropertyId":{"type":"string","nullable":true},"groupByPropId":{"type":"string","nullable":true},"subGroupByPropId":{"type":"string","nullable":true},"datePropertyId":{"type":"string","nullable":true},"chart":{"$ref":"#/components/schemas/DatabaseChart","nullable":true},"position":{"type":"integer"},"isDefault":{"type":"boolean"}}},"DatabaseChart":{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["bar","pie"]},"categoryPropId":{"type":"string","nullable":true,"description":"A select, status, multi_select, date or checkbox property"},"valuePropId":{"type":"string","nullable":true,"description":"A number property; required to sum"},"aggregation":{"type":"string","enum":["count","sum"]}}},"DatabaseViewBody":{"type":"object","description":"Property ids come from list_database_rows. A kanban's board property must be a select, a calendar's date property a date, and table grouping a select, multi_select or checkbox. Pass null to clear a field.","properties":{"name":{"type":"string","maxLength":100},"viewType":{"type":"string","enum":["table","kanban","gallery","calendar","chart"]},"filter":{"type":"object","description":"FilterGroup, as in the rows `filter` query"},"sortPropId":{"type":"string","nullable":true},"sortDir":{"type":"string","enum":["asc","desc"]},"boardPropertyId":{"type":"string","nullable":true},"groupByPropId":{"type":"string","nullable":true},"subGroupByPropId":{"type":"string","nullable":true},"datePropertyId":{"type":"string","nullable":true},"chart":{"$ref":"#/components/schemas/DatabaseChart","nullable":true},"makeDefault":{"type":"boolean","description":"true makes this the view the database opens with"}}},"DatabaseProperty":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"options":{"type":"array","items":{"$ref":"#/components/schemas/SelectOption"}},"configJson":{"type":"object","additionalProperties":true}}},"DatabaseRow":{"type":"object","properties":{"id":{"type":"string"},"databaseId":{"type":"string"},"pageId":{"type":"string"},"properties":{"type":"object","additionalProperties":true},"notes":{"type":"string"},"linkedPageId":{"type":"string","nullable":true}}},"WriteRowBody":{"type":"object","properties":{"title":{"type":"string","description":"Merged into the Name property"},"properties":{"type":"object","additionalProperties":true,"description":"Property id or name → value"},"notes":{"type":"string","description":"Plaintext notes on the row"},"linkedPageId":{"type":"string","nullable":true,"description":"Existing page, board, or database id"}}},"CreatePropertyBody":{"type":"object","required":["name","type"],"properties":{"name":{"type":"string","maxLength":60},"type":{"$ref":"#/components/schemas/PropertyType"},"options":{"type":"array","items":{"$ref":"#/components/schemas/SelectOptionInput"}},"targetDatabaseId":{"type":"string","description":"Required when type is `relation`"},"expression":{"type":"string","description":"Required when type is `formula`"}}},"UpdatePropertyBody":{"type":"object","properties":{"name":{"type":"string","maxLength":60},"options":{"type":"array","items":{"$ref":"#/components/schemas/SelectOptionInput"},"description":"Replaces select / multi_select options. Existing names keep their ids, and their color unless a color is given."}}},"OkId":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true]},"id":{"type":"string"},"pageId":{"type":"string"},"databaseId":{"type":"string"}}},"Shape":{"type":"object","additionalProperties":true,"description":"Whiteboard shape (rect, ellipse, diamond, triangle, text, arrow, ink, image, sticky, frame, page, …). A `page` shape is a card that links to another page: `pageId` must name a live page the token can read; the card's title, icon, and verification mark are looked up live, never stored."},"CaptureIdeaBody":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"notes":{"type":"string"},"timeZone":{"type":"string","description":"IANA time zone for the Date stamp"}}},"CaptureTaskBody":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"due":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"timeZone":{"type":"string"}}},"CaptureDecisionBody":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"notes":{"type":"string"},"timeZone":{"type":"string","description":"IANA time zone for the Date stamp"}}},"CaptureTodayBody":{"type":"object","properties":{"dailyDate":{"type":"string","description":"YYYY-MM-DD. When omitted, uses timeZone (same as the UI)."},"timeZone":{"type":"string","description":"IANA time zone when dailyDate is omitted"}}},"CaptureRowResult":{"type":"object","required":["rowId","pageId","databaseId","created","restored","peekUrl"],"properties":{"rowId":{"type":"string"},"pageId":{"type":"string"},"databaseId":{"type":"string"},"created":{"type":"boolean"},"restored":{"type":"boolean"},"peekUrl":{"type":"string"},"due":{"type":"string","nullable":true}}},"CaptureTodayResult":{"type":"object","required":["id","dailyDate","created","restored","pageUrl"],"properties":{"id":{"type":"string"},"dailyDate":{"type":"string"},"created":{"type":"boolean"},"restored":{"type":"boolean"},"pageUrl":{"type":"string"},"tasks":{"type":"array","description":"Open tasks whose Due is this daily note. Omitted from view when the token cannot see Tasks.","items":{"type":"object","required":["rowId","title","due","peekUrl"],"properties":{"rowId":{"type":"string"},"title":{"type":"string"},"due":{"type":"string"},"peekUrl":{"type":"string"}}}}}},"PageHistoryList":{"type":"object","required":["snapshots","matchesSnapshot"],"properties":{"snapshots":{"type":"array","items":{"type":"object","required":["id","createdAt","reason","isCurrent"],"properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reason":{"type":"string"},"actorName":{"type":"string","nullable":true},"isCurrent":{"type":"boolean"}}}},"matchesSnapshot":{"type":"boolean"}}},"PageHistoryDiff":{"type":"object","required":["snapshotId","createdAt","reason","liveMarkdown","snapshotMarkdown","unifiedDiff"],"properties":{"snapshotId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"reason":{"type":"string"},"actorName":{"type":"string","nullable":true},"liveMarkdown":{"type":"string"},"snapshotMarkdown":{"type":"string"},"unifiedDiff":{"type":"string"}}},"RunbookStep":{"type":"object","required":["id","pageId","label","position"],"properties":{"id":{"type":"string"},"pageId":{"type":"string"},"headingId":{"type":"string","nullable":true,"description":"Stable heading id when the step is one section. Null for a whole page."},"label":{"type":"string"},"sourceTitle":{"type":"string","nullable":true,"description":"The source page name, set on a section step."},"position":{"type":"number"}}},"Runbook":{"type":"object","required":["id","pageId","title","steps"],"properties":{"id":{"type":"string"},"pageId":{"type":"string","description":"The runbook document."},"title":{"type":"string"},"steps":{"type":"array","description":"Steps this token can open. Hidden steps are omitted.","items":{"$ref":"#/components/schemas/RunbookStep"}}}},"AddRunbookStepBody":{"type":"object","required":["pageId"],"properties":{"pageId":{"type":"string"},"headingId":{"type":"string","description":"Stable heading id from the page outline. Omit to add the whole page."}}},"RunbookStepCreated":{"type":"object","required":["id","runbookId","pageId","position"],"properties":{"id":{"type":"string"},"runbookId":{"type":"string"},"pageId":{"type":"string"},"headingId":{"type":"string","nullable":true},"position":{"type":"number"}}}}},"security":[{"bearerAuth":[]}],"paths":{"/docs":{"get":{"operationId":"getApiDocs","summary":"Hosted API docs","description":"Public, unmetered HTML generated from this OpenAPI document. Mnemo-owned; no third-party docs runtime.","tags":["Docs"],"security":[],"responses":{"200":{"description":"API reference HTML"}}}},"/openapi.json":{"get":{"operationId":"getOpenApi","summary":"This OpenAPI document","description":"Public, unmetered. Agents should generate against this spec.","tags":["Docs"],"security":[],"responses":{"200":{"description":"OpenAPI 3 JSON","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/formulas":{"get":{"operationId":"listFormulaFunctions","summary":"Formula function catalog","description":"Public, unmetered. Locked 1.9 function set used by formula columns.","tags":["Docs"],"security":[],"responses":{"200":{"description":"Formula functions","content":{"application/json":{"schema":{"type":"object","required":["functions"],"properties":{"functions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"arity":{"type":"object","properties":{"min":{"type":"integer"},"max":{"type":"integer"}}},"summary":{"type":"string"},"example":{"type":"string"}}}}}}}}}}}},"/pages":{"get":{"operationId":"listPages","summary":"List pages","description":"Workspace tree visible to the token (ACL- and grant-filtered). Row pages are not listed.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Page tree","content":{"application/json":{"schema":{"type":"object","required":["pages"],"properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/PageTreeNode"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createPage","summary":"Create page","description":"Optional `bodyMarkdown` (max 100,000 characters). Optional `parentId` (null = root). Page links: `[[Title|pageId]]`, or a bare `[[Title]]`, which links the page the token can read with that exact title (any case; the most recently updated wins; no match stays plain text). Callouts open with `:::callout info` or `:::callout type=info` and close with `:::`; kinds are info, success or tip, warning, danger, alert or error, and note, or a colour id (blue, green, yellow, red, purple).","tags":["Pages"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePageBody"}}}},"responses":{"201":{"description":"Created page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageCreated"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/templates":{"get":{"operationId":"listPageTemplates","summary":"List workspace templates","description":"The workspace's saved templates. A document template starts a page (POST /pages), a whiteboard template a board (POST /whiteboards), a database template a database (POST /databases). Saving a template stays in the app.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Templates","content":{"application/json":{"schema":{"type":"object","required":["templates"],"properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"kind":{"type":"string","enum":["document","whiteboard","database"]}}}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/whiteboards":{"post":{"operationId":"createWhiteboard","summary":"Create whiteboard","description":"Mints a whiteboard page. Optional `parentId` (null = root) and picker `icon`. Document pages stay on POST /pages.","tags":["Whiteboards"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWhiteboardBody"}}}},"responses":{"201":{"description":"Created whiteboard","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhiteboardCreated"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}":{"get":{"operationId":"getPage","summary":"Get page","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Page including plaintext `body` and markdown `bodyMarkdown`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"patch":{"operationId":"updatePage","summary":"Update page title/icon","description":"Cover is not writable on this endpoint.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePageBody"}}}},"responses":{"200":{"description":"Updated page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageUpdated"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"archivePage","summary":"Archive page","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}},{"name":"children","in":"query","required":false,"description":"`keep` (default) promotes children to roots. `trash` archives the subtree.","schema":{"type":"string","enum":["keep","trash"],"default":"keep"}}],"responses":{"200":{"description":"Archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/capture/idea":{"post":{"operationId":"captureIdea","summary":"Capture an idea","description":"Prepends a row on the workspace Ideas database (write). Restricted tokens may write an existing Ideas page they are granted; only unrestricted tokens may create it.","tags":["Capture"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureIdeaBody"}}}},"responses":{"200":{"description":"Captured idea","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureRowResult"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/capture/task":{"post":{"operationId":"captureTask","summary":"Capture a task","description":"Prepends a row on the workspace Tasks database (write). Restricted tokens may write an existing Tasks page they are granted; only unrestricted tokens may create it.","tags":["Capture"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureTaskBody"}}}},"responses":{"200":{"description":"Captured task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureRowResult"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/capture/decision":{"post":{"operationId":"captureDecision","summary":"Capture a decision","description":"Prepends a row on the workspace Decisions database, dated now with Status on Decided (write). Restricted tokens may write an existing Decisions page they are granted; only unrestricted tokens may create it.","tags":["Capture"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureDecisionBody"}}}},"responses":{"200":{"description":"Captured decision","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureRowResult"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/capture/today":{"post":{"operationId":"captureToday","summary":"Open or create today","description":"Opens the daily note for `dailyDate` or the caller `timeZone` day (write). Never midnight-spawns another day. Restricted tokens cannot create a missing daily note.","tags":["Capture"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureTodayBody"}}}},"responses":{"200":{"description":"Daily note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaptureTodayResult"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/history":{"get":{"operationId":"listPageHistory","summary":"List page history","description":"Viewers can list. API rows include `actorName` (token name at write).","tags":["History"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Snapshots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageHistoryList"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/history/{snapshotId}/diff":{"get":{"operationId":"getPageHistoryDiff","summary":"Diff a snapshot against live","description":"Plaintext/markdown unified diff of live vs snapshot. Viewers can diff.","tags":["History"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}},{"name":"snapshotId","in":"path","required":true,"description":"Snapshot id","schema":{"type":"string"}}],"responses":{"200":{"description":"Diff","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageHistoryDiff"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/history/{snapshotId}/restore":{"post":{"operationId":"restorePageSnapshot","summary":"Restore a snapshot","description":"Write + edit. Saves a before_restore snapshot first.","tags":["History"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}},{"name":"snapshotId","in":"path","required":true,"description":"Snapshot id","schema":{"type":"string"}}],"responses":{"200":{"description":"Restored","content":{"application/json":{"schema":{"type":"object","required":["ok","documentName"],"properties":{"ok":{"type":"boolean","enum":[true]},"documentName":{"type":"string"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/content":{"post":{"operationId":"appendPageContent","summary":"Append markdown","description":"`content` or alias `text`. Max 100,000 characters. Document pages only. Page links: `[[Title|pageId]]`, or a bare `[[Title]]`, which links the page the token can read with that exact title (any case; the most recently updated wins; no match stays plain text). Callouts open with `:::callout info` or `:::callout type=info` and close with `:::`; kinds are info, success or tip, warning, danger, alert or error, and note, or a colour id (blue, green, yellow, red, purple).","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentBody"}}}},"responses":{"200":{"description":"Appended","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"pageId":{"type":"string"},"appendedChars":{"type":"integer"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"put":{"operationId":"replacePageContent","summary":"Replace markdown","description":"`content` or alias `text`. Max 100,000 characters. Document pages only. Page links: `[[Title|pageId]]`, or a bare `[[Title]]`, which links the page the token can read with that exact title (any case; the most recently updated wins; no match stays plain text). Callouts open with `:::callout info` or `:::callout type=info` and close with `:::`; kinds are info, success or tip, warning, danger, alert or error, and note, or a colour id (blue, green, yellow, red, purple).","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentBody"}}}},"responses":{"200":{"description":"Replaced","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"pageId":{"type":"string"},"replacedChars":{"type":"integer"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/comments":{"get":{"operationId":"listComments","summary":"List comments","tags":["Comments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Comments","content":{"application/json":{"schema":{"type":"object","required":["comments"],"properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createComment","summary":"Create comment","description":"Reply nesting is one level. API-created comments use authorName `API`.","tags":["Comments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentBody"}}}},"responses":{"201":{"description":"Created comment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comment"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/review":{"get":{"operationId":"listReviewQueue","summary":"Pages that need review","description":"Verified pages (2.3). Pages the token can see that are due, changed since verified, or never verified with an interval set. Overdue first.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Review queue","content":{"application/json":{"schema":{"type":"object","required":["pages"],"properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/ReviewQueueEntry"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/verification":{"get":{"operationId":"getPageVerification","summary":"Verification state","description":"Who last vouched for the page, when, the review interval, and the derived freshness.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Verification state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageVerification"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"verifyPage","summary":"Verify page","description":"Vouch for the page as the token's user (write scope, member role, page grant). Records the snapshot current at this moment. Optional note and interval.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyPageBody"}}}},"responses":{"200":{"description":"Verification state after the stamp","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageVerification"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"patch":{"operationId":"setReviewInterval","summary":"Set review interval","description":"Set or clear the re-verify cadence without verifying.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIntervalBody"}}}},"responses":{"200":{"description":"Verification state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageVerification"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"clearPageVerification","summary":"Stop verifying","description":"Clear the stamp and the interval. The page reads as untracked again; past stamps stay in the log.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Verification state, now untracked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageVerification"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/outline":{"get":{"operationId":"getPageOutline","summary":"Document outline","description":"Headings of a document in order, with levels and stable ids (read scope). Reads the stored document, so an edit a few seconds old may be missing. 400 for databases and whiteboards.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Document page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Outline","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOutline"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/sections/{headingId}":{"get":{"operationId":"getPageSection","summary":"One section of a document","description":"A heading and what follows it, up to the next heading of the same or a higher level, as Markdown (read scope). Take `headingId` from the page outline. This is the read a section embed makes. Reads the stored document, so an edit a few seconds old may be missing. 404 when the heading is no longer on the page.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Document page id","schema":{"type":"string"}},{"name":"headingId","in":"path","required":true,"description":"Stable heading id from the page outline","schema":{"type":"string"}}],"responses":{"200":{"description":"Section","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageSection"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/shapes":{"get":{"operationId":"listWhiteboardShapes","summary":"List whiteboard shapes","tags":["Whiteboards"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Whiteboard page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Shapes","content":{"application/json":{"schema":{"type":"object","properties":{"pageId":{"type":"string"},"shapes":{"type":"array","items":{"$ref":"#/components/schemas/Shape"}},"zOrder":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Whiteboard not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"addWhiteboardShape","summary":"Add whiteboard shape","description":"Body is the shape object, or `{ \"shape\": { … } }`.","tags":["Whiteboards"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Whiteboard page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Shape"},{"type":"object","properties":{"shape":{"$ref":"#/components/schemas/Shape"}}}]}}}},"responses":{"201":{"description":"Created shape","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"pageId":{"type":"string"},"shape":{"$ref":"#/components/schemas/Shape"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/tags":{"get":{"operationId":"listTags","summary":"List workspace tags","description":"The tag catalog (read scope). Assigning a tag is a separate call.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Tags","content":{"application/json":{"schema":{"type":"object","required":["tags"],"properties":{"tags":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Tag"},{"type":"object","properties":{"assignmentCount":{"type":"integer"}}}]}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/tags":{"get":{"operationId":"listPageTags","summary":"List tags on a page","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Page tags","content":{"application/json":{"schema":{"type":"object","properties":{"pageId":{"type":"string"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"addPageTags","summary":"Add tags to a page","description":"Adds the named tags and leaves the rest. Write scope, member role, page grant.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagIdsBody"}}}},"responses":{"200":{"description":"Page tags after the add","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"put":{"operationId":"setPageTags","summary":"Replace tags on a page","description":"Replaces the page's tags with this list. Tags not in the list are removed.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagIdsBody"}}}},"responses":{"200":{"description":"Page tags after the replace","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/tags/remove":{"post":{"operationId":"removePageTags","summary":"Remove tags from a page","description":"Removes the named tags and leaves the rest.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagIdsBody"}}}},"responses":{"200":{"description":"Page tags after the remove","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/duplicate":{"post":{"operationId":"duplicatePage","summary":"Duplicate a page","description":"Copies the page next to the original as `Copy of <title>`: body, icon, cover, tags and access, and for a database its columns, views and rows. Read grant on the page and write grant on its parent; a limited token cannot copy a top-level page.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"201":{"description":"The copy","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"type":{"type":"string"},"parentId":{"type":"string","nullable":true}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/restore":{"post":{"operationId":"restorePage","summary":"Restore a page from the trash","description":"Write scope and a write grant on the parent the page returns under; a top-level page needs a grant naming it. Restores one page: a page whose parent is still in the trash returns 400, and pages trashed with it stay there. Deleting forever stays in the app.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/trash":{"get":{"operationId":"listTrash","summary":"List the trash","description":"Trashed pages this token could restore, newest first, up to 200. Database rows are not listed.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Trashed pages","content":{"application/json":{"schema":{"type":"object","required":["pages"],"properties":{"pages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"icon":{"type":"string","nullable":true},"type":{"type":"string"},"parentId":{"type":"string","nullable":true},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/move":{"post":{"operationId":"movePage","summary":"Move or reorder a page","description":"Write scope and a write grant on the page and on the destination. A limited token cannot move a page to the workspace root. Same-parent reorder does not write an activity row.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MovePageBody"}}}},"responses":{"200":{"description":"Moved","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"parentId":{"type":"string","nullable":true},"position":{"type":"integer"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/comments/{commentId}":{"patch":{"operationId":"setCommentResolved","summary":"Resolve or reopen a comment","description":"Root comments only. The token owner must be the comment author, or an admin or owner.","tags":["Comments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}},{"name":"commentId","in":"path","required":true,"description":"Comment id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveCommentBody"}}}},"responses":{"200":{"description":"Comment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Comment"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"deleteComment","summary":"Delete an API comment","description":"Only a comment written through the API by this token's owner. A thread with a reply from anyone else returns 409; resolve it instead.","tags":["Comments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}},{"name":"commentId","in":"path","required":true,"description":"Comment id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/shapes/{shapeId}":{"patch":{"operationId":"updateWhiteboardShape","summary":"Update a whiteboard shape","description":"Geometry and text on an existing shape. `z` is `front` or `back`. A missing id is 404 and does not create a shape.","tags":["Whiteboards"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Whiteboard page id","schema":{"type":"string"}},{"name":"shapeId","in":"path","required":true,"description":"Shape id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"deleteWhiteboardShape","summary":"Delete a whiteboard shape","description":"Removes the shape from the board. Shapes have no trash.","tags":["Whiteboards"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Whiteboard page id","schema":{"type":"string"}},{"name":"shapeId","in":"path","required":true,"description":"Shape id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/batch":{"post":{"operationId":"batch","summary":"Run up to 20 operations","description":"One quota charge. Each item returns its own success or error. A failure does not roll back earlier items. Nested batch is rejected. ops: add_page_tags, remove_page_tags, set_page_tags, move_page, resolve_comment, unresolve_comment, delete_comment, update_page, restore_page, create_comment, add_whiteboard_shape, update_whiteboard_shape, delete_whiteboard_shape, create_database_view, update_database_view, delete_database_view, move_runbook_step, remove_runbook_step, verify_page.","tags":["Pages"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchBody"}}}},"responses":{"200":{"description":"Per-item results","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/activity":{"get":{"operationId":"listActivity","summary":"What changed in the workspace","description":"The change history, newest first (read scope): pages created, renamed, moved, trashed, restored, verified or unverified, bodies edited, and database rows added, each with when and by whom. Only pages the token's owner can open and the token is granted. Body edits are one entry per editor per quiet spell, not per keystroke. To poll, ask again with `since` set to the newest `at` you hold. Pass `nextCursor` back as `cursor` for the next page; a page can be empty and still carry a `nextCursor`, so follow the cursor until it is null.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string"},"description":"ISO 8601 time. Entries at or after it."},{"name":"until","in":"query","required":false,"schema":{"type":"string"},"description":"ISO 8601 time. Entries before it."},{"name":"pageId","in":"query","required":false,"schema":{"type":"string"},"description":"Only this page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200},"description":"Page size, 1 to 200. Default 50."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"`nextCursor` from the previous page."}],"responses":{"200":{"description":"Activity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityList"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/live":{"get":{"operationId":"liveActivity","summary":"Subscribe to page activity","description":"Server-sent events for a Bearer token. Each event is `{ pageId, kind, at }` only. The same grant and page access as list activity apply. Titles and row bodies are not on this stream.","tags":["Pages"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Text event stream","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/graph":{"get":{"operationId":"graphNeighbors","summary":"Page link neighbors","description":"Incoming and outgoing page links from one page, depth at most 2. Archived pages and pages the token cannot open are omitted.","tags":["Pages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"query","required":true,"schema":{"type":"string"}},{"name":"depth","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":2}}],"responses":{"200":{"description":"Graph","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/search":{"get":{"operationId":"searchPages","summary":"Search pages and database rows","description":"Returns `{ results, rows, files }`. `results` are pages (limit 20 with `q`, 12 without). `rows` are cell-value hits (empty when `q` is blank, limit 12). `files` are uploaded PDF, Word and text files whose name or text matches (limit 10), each with its page and a snippet; empty when `q` is blank or `types` / `tags` is set. `types` is comma-separated `document|database|whiteboard` (unknown values ignored). `tags` is comma-separated workspace tag ids (OR).","tags":["Search"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Search query. Empty still returns recent pages."},{"name":"types","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated page types: document, database, whiteboard","example":"document,whiteboard"},{"name":"tags","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated workspace tag ids (OR)"}],"responses":{"200":{"description":"Page results plus row and file hits","content":{"application/json":{"schema":{"type":"object","required":["results","rows","files"],"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchHit"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/SearchRowHit"}},"files":{"type":"array","items":{"$ref":"#/components/schemas/SearchFileHit"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/pages/{pageId}/attachments":{"get":{"operationId":"listPageAttachments","summary":"List a page's files","description":"Read scope + page grant. `text` is ready, pending (not read yet), empty, unreadable, or not_text (images, spreadsheets, zips).","tags":["Attachments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"pageId","in":"path","required":true,"description":"Page id","schema":{"type":"string"}}],"responses":{"200":{"description":"Files","content":{"application/json":{"schema":{"type":"object","required":["attachments"],"properties":{"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer"},"text":{"$ref":"#/components/schemas/AttachmentTextState"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/attachments/{attachmentId}/text":{"get":{"operationId":"getAttachmentText","summary":"Read a file's text","description":"The text inside an uploaded PDF, Word (.docx) or text file, in windows. Read scope + grant on the file's page. A file not read yet is read on this call. Up to 200,000 characters per file are kept; scanned PDFs have none.","tags":["Attachments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"attachmentId","in":"path","required":true,"description":"Attachment id","schema":{"type":"string"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0},"description":"Character to start at. Pass the last `nextOffset`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50000},"description":"Characters to return (default 20,000)"}],"responses":{"200":{"description":"File text","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"pageId":{"type":"string"},"text":{"$ref":"#/components/schemas/AttachmentTextState"},"content":{"type":"string"},"offset":{"type":"integer"},"nextOffset":{"type":"integer","nullable":true},"totalChars":{"type":"integer"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases":{"get":{"operationId":"listDatabases","summary":"List databases","tags":["Databases"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Databases","content":{"application/json":{"schema":{"type":"object","required":["databases"],"properties":{"databases":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseSummary"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createDatabase","summary":"Create database","tags":["Databases"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDatabaseBody"}}}},"responses":{"201":{"description":"Created database","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseCreated"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/rows":{"get":{"operationId":"listDatabaseRows","summary":"List database rows","description":"`databaseId` may be the database id, the host page id, or a unique title. Results are always paged: `limit` defaults to 80 and is capped at 200. When `nextCursor` is not null, request again with `cursor` set to it (and the same `filter`, `sortPropId` and `sortDir`) for the next page; `totalCount` is the filtered total.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"filter","in":"query","schema":{"type":"string"},"description":"JSON FilterGroup"},{"name":"sortPropId","in":"query","schema":{"type":"string"}},{"name":"sortDir","in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"`nextCursor` from the previous page"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":80},"description":"Page size (default 80, max 200)"}],"responses":{"200":{"description":"Rows (computed lookup/rollup/formula filled)","content":{"application/json":{"schema":{"type":"object","properties":{"databaseId":{"type":"string"},"pageId":{"type":"string"},"properties":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseProperty"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseRow"}},"nextCursor":{"type":"string","nullable":true},"totalCount":{"type":"integer"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createDatabaseRow","summary":"Create database row","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteRowBody"}}}},"responses":{"201":{"description":"Created row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseRow"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/rows/{rowId}":{"patch":{"operationId":"updateDatabaseRow","summary":"Update database row","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"rowId","in":"path","required":true,"description":"Row id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteRowBody"}}}},"responses":{"200":{"description":"Updated row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseRow"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"deleteDatabaseRow","summary":"Delete database row","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"rowId","in":"path","required":true,"description":"Row id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/properties":{"post":{"operationId":"createDatabaseProperty","summary":"Create database property","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePropertyBody"}}}},"responses":{"201":{"description":"Created property","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/DatabaseProperty"},{"type":"object","properties":{"databaseId":{"type":"string"},"pageId":{"type":"string"}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/properties/{propertyId}":{"patch":{"operationId":"updateDatabaseProperty","summary":"Update database property","description":"At least one of `name` or `options`.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"propertyId","in":"path","required":true,"description":"Property id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePropertyBody"}}}},"responses":{"200":{"description":"Updated property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseProperty"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"deleteDatabaseProperty","summary":"Delete database property","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"propertyId","in":"path","required":true,"description":"Property id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/views":{"get":{"operationId":"listDatabaseViews","summary":"List database views","description":"Saved views with their filter, sort and grouping, and which is the default. Read scope + grant.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}}],"responses":{"200":{"description":"Views","content":{"application/json":{"schema":{"type":"object","required":["databaseId","views"],"properties":{"databaseId":{"type":"string"},"views":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseView"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createDatabaseView","summary":"Create database view","description":"Write scope + write grant. `viewType` is required.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseViewBody"}}}},"responses":{"201":{"description":"Created view","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseView"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/databases/{databaseId}/views/{viewId}":{"patch":{"operationId":"updateDatabaseView","summary":"Update database view","description":"Write scope + write grant. Fields left out keep their value. `makeDefault: true` makes it the default.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"viewId","in":"path","required":true,"description":"View id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseViewBody"}}}},"responses":{"200":{"description":"Updated view","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatabaseView"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"delete":{"operationId":"deleteDatabaseView","summary":"Delete database view","description":"Rows are not touched. The last view cannot be deleted. Deleting the default makes the first remaining view the default.","tags":["Databases"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"databaseId","in":"path","required":true,"description":"Database id, page id, or unique title","schema":{"type":"string"}},{"name":"viewId","in":"path","required":true,"description":"View id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/runbooks":{"get":{"operationId":"listRunbooks","summary":"List runbooks","description":"Runbooks (2.7) this token can open. Each step is a whole page or one section. Steps the token cannot open are omitted, titles included.","tags":["Runbooks"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Runbooks","content":{"application/json":{"schema":{"type":"object","required":["runbooks"],"properties":{"runbooks":{"type":"array","items":{"$ref":"#/components/schemas/Runbook"}}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}},"post":{"operationId":"createRunbook","summary":"Create a runbook","description":"Write scope, member role. Optional parentId; a limited token must pass a write-granted parentId. Add steps with POST /runbooks/{id}/steps.","tags":["Runbooks"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"parentId":{"type":"string","nullable":true}}}}}},"responses":{"201":{"description":"Created runbook","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"pageId":{"type":"string"},"title":{"type":"string"}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/runbooks/{id}/steps/{stepId}":{"delete":{"operationId":"removeRunbookStep","summary":"Remove a runbook step","description":"Write scope + write grant on the runbook. The page the step points at is not touched.","tags":["Runbooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Runbook id","schema":{"type":"string"}},{"name":"stepId","in":"path","required":true,"description":"Step id","schema":{"type":"string"}}],"responses":{"200":{"description":"Removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkId"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/runbooks/{id}/steps/{stepId}/move":{"post":{"operationId":"moveRunbookStep","summary":"Move a runbook step","description":"One place earlier or later. A step already at that end stays put. Write scope + write grant on the runbook.","tags":["Runbooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Runbook id","schema":{"type":"string"}},{"name":"stepId","in":"path","required":true,"description":"Step id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["direction"],"properties":{"direction":{"type":"string","enum":["earlier","later"]}}}}}},"responses":{"200":{"description":"Moved","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"id":{"type":"string"},"direction":{"type":"string","enum":["earlier","later"]}}}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}},"/runbooks/{id}/steps":{"post":{"operationId":"addPageToRunbook","summary":"Add a page to a runbook","description":"Write scope, member role. Adds a whole page, or one section when headingId is set. A runbook cannot be a step of itself.","tags":["Runbooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Runbook id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRunbookStepBody"}}}},"responses":{"201":{"description":"Step added","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunbookStepCreated"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, or expired Bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope, not a member, or grant denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found (ACL-masked as 404)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Burst rate limit (IP 120/min or token 300/min) or Free monthly quota. `Retry-After` is seconds. Quota body includes `code: MCP_QUOTA_EXCEEDED`.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the burst window or UTC month resets"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/QuotaError"}]}}}}}}}}}