{"openapi":"3.1.0","info":{"title":"LegendKeeper API","version":"3.0.0","description":"REST API for the [LegendKeeper](https://www.legendkeeper.com) world-building platform.\n\nEvery endpoint follows one response contract: a single object is returned bare,\na collection is `{ data: [...], hasMore, nextCursor }`, and a delete returns `204`.\n\n## Blocks and rows\n\nPage content is a tree of typed blocks (`getDocumentBlocks`). Every block carries a stable `id`.\nA write that omits an id gets one minted. `insertBlock` and `replaceBlock` keep a requested id, and answer `409`\n`DUPLICATE_ID` with the field path when another block of the document already uses it; `replaceBlock` may reuse\nthe ids of the subtree it replaces. Two equal block ids in one body answer `400` `VALIDATION_ERROR` at the second. Legacy\ndocuments whose blocks lack ids become addressable after one `assignBlockIds` call.\n\n`replaceDocumentBlocks` replaces the whole tree. `insertBlock` appends at the end or takes one of\n`after`, `before`, `parent`; `replaceBlock` keeps the block id; `updateBlock` changes own fields;\n`moveBlock` relocates a subtree; `deleteBlock` removes it. Content the block model cannot\nexpress is returned as `unsupported` and survives a replace only when echoed by id.\nEvery write validates the resulting document and answers `400` with `VALIDATION_ERROR`,\n`UNSUPPORTED_KIND` or `INVALID_CONTENT` and the offending block path. Nothing is written in that case.\n\nKey-value data lives in three places and shares one row shape at each:\na sidebar property of kind `keyValue` (`/properties/{propertyId}/rows`), a `keyValue` block\n(`/blocks/{blockId}/rows`), and a property inside an infobox\n(`/blocks/{infoboxId}/properties/{propertyId}/rows`). Rows are ordered by `rank`.\nAn infobox row is a property; `/blocks/{infoboxId}/properties` takes the same body\nas `createProperty`.\n\nEvery block, row and infobox-property response carries the document `version`\n(also the `ETag` header). Send it back as `If-Match` to fail with `412` instead of\noverwriting a change made since you read.\n\n## Boards\n\nA board document holds tldraw 3.9 records: pages, shapes, bindings and assets (`getBoardContent`).\nReads return the records as stored, in tldraw's own record shape, so tldraw's `TLShape`,\n`TLBinding` and `TLAsset` types describe them. Writes (`createBoardShapes`, `updateBoardShapes`,\n`deleteBoardShapes`, `replaceBoardContent`) are batched and atomic, and every record is validated\nwith tldraw's validators against the schema the app's board view uses. Each record is stored\nseparately, so a write merges with concurrent edits made in the app, record by record.\n\n## Field limits\n\nEvery request field declares its limit as `maxLength`, `maxItems` or `maxProperties`, and nesting is limited\nto 64 levels. A value past a limit answers `400` with `code: \"VALIDATION_ERROR\"` and the field path.\nLimits apply to writes. Content created in the app that exceeds a limit reads back unchanged; a write that\nsends it back, such as a whole-block replace, answers `400` at that value.\n\n## Errors\n\nEvery 4xx and 5xx response body is `{ message, code, requestId, errors? }`. `code` is one of the\nvalues below and fixes the status. `message` is human-readable and stable in meaning, not in wording.\n`errors` appears only on 400 responses: one entry `{ path, message }` per failing field or block, with a\ndotted `path` (`block.children[0].level`). `KIND_MISMATCH` names a path entity rather than a body field\nand carries no `errors`.\n\n| Status | Code | Meaning |\n| --- | --- | --- |\n| 400 | `VALIDATION_ERROR` | The body or query fails the schema; `errors[].path` names each field. |\n| 400 | `INVALID_CONTENT` | The block tree is schema-valid but the editor cannot hold it. |\n| 400 | `UNSUPPORTED_KIND` | Creating an `unsupported` block or property, or echoing an unsupported id the document does not hold. |\n| 400 | `KIND_MISMATCH` | The target document, block or calendar is not a kind the route accepts (rows on a block or property that is not keyValue; blocks on a document that is not a page; pins on a document that is not a map; events on a document that is not a timeline; an update or delete of a built-in calendar). |\n| 401 | `UNAUTHENTICATED` | No credential, or an unknown, revoked or expired key. |\n| 402 | `SUBSCRIPTION_LAPSED` | The project owner's plan does not allow the write. |\n| 402 | `PAID_PLAN_REQUIRED` | The project owner is not on a paid plan, which API keys require; a trial does not count. |\n| 403 | `FORBIDDEN` | The caller is not a member with the required role. |\n| 403 | `WRONG_PROJECT` | The key's project is not the path's project. |\n| 403 | `INSUFFICIENT_SCOPE` | The key lacks a scope the operation requires. |\n| 403 | `FEATURE_UNAVAILABLE` | The request uses a field of a feature that is not available yet; send it without that field. |\n| 404 | `NOT_FOUND` | A missing entity, including a placement anchor. |\n| 405 | `METHOD_NOT_ALLOWED` | The path exists; the method does not. |\n| 409 | `DUPLICATE_ID` | A supplied id already exists. |\n| 409 | `AMBIGUOUS` | A block id occurs more than once in a legacy document. |\n| 409 | `ALREADY_DELETED` | The entity is already deleted. |\n| 409 | `HAS_CHILDREN` | The resource has child resources that are not deleted; pass `cascade=true` to delete them with it. |\n| 409 | `NOT_DELETED` | The entity to restore is not deleted. |\n| 409 | `PARENT_DELETED` | The resource's parent is deleted; restore the parent first. |\n| 409 | `IN_PROGRESS` | A prior operation on the entity has not finished. |\n| 409 | `IDEMPOTENCY_KEY_REUSED` | The idempotency key was used for a different request. |\n| 409 | `TOO_MANY_PENDING_INVITES` | The project holds as many pending invites as it may; revoke some before inviting more. |\n| 412 | `VERSION_MISMATCH` | `If-Match` does not equal the current version. |\n| 422 | `DOCUMENT_TOO_LARGE` | The write would grow the document past its size limit. |\n| 413 | `PAYLOAD_TOO_LARGE` | The body exceeds the route's limit. |\n| 413 | `STORAGE_QUOTA_EXCEEDED` | The project owner's storage quota is reached. |\n| 429 | `RATE_LIMITED` | A key or project tier is exhausted; see `Retry-After`. |\n| 429 | `UPLOAD_RATE_EXCEEDED` | The upload tier is exhausted. |\n| 500 | `INTERNAL` | Unexpected failure; the body carries only the code, a fixed message and `requestId`, which identifies the server log line. |\n\n## Identifiers\n\n`createResource`, `createLane`, `createEvent` and `createFeature` accept an optional `id`. An id must be a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters):\nthe formats LegendKeeper itself generates. Any other value answers `400` `VALIDATION_ERROR` at `id`. An id that is\nalready taken answers `409` `DUPLICATE_ID` and nothing is created. A resource id is taken when any resource of the\nproject has it, including a deleted resource, which stays restorable from the trash. A lane, event or feature id\nis taken when the same timeline or map already has it.\n\nA client-chosen id lets an importer keep one stable identity per record and find it again on the next sync with\n`getResource`, instead of matching by name. Idempotency keys expire after 24 hours and are not a re-sync mechanism.\nA created resource's documents are its `documents`, in the order sent; each is reached through the resource id.\n\n## Resource order\n\nSiblings in the resource tree are ordered by `rank`, a fractional index compared as a plain string. `createResource`\nand `moveResource` compute the rank with the same jittered fractional-indexing functions the app uses: after the\nlast sibling by default, or between the anchor and its neighbour for `after` and `before`. The new rank never\nequals the rank of an existing sibling. Resources created or moved through older clients can share a rank; placing\nafter or before one of them places the resource after or before every sibling that shares that rank.\n\n## Templates\n\nA template is a resource under the virtual root `templates`. `templates` is a reserved id: no resource has it,\nand it is not returned by getResource. A top-level template has `parentId` `templates`. A resource under a\ntemplate is a template too, and its `parentId` is that template's id. Search and collections do not return\ntemplates.\n\nTemplates are read, updated, moved and deleted with the resource operations. These operations also take the\n`templates` id:\n\n| Operation | `templates` as |\n| --- | --- |\n| `listResources` | Without `parentId`, templates are listed with the other resources. `parentId=templates` lists the top-level templates. |\n| `createResource`, `createManyResources` | `parentId: \"templates\"` creates a top-level template. |\n| `moveResource` | `parentId: \"templates\"` makes the resource a top-level template; `parentId: null` moves it back to the root. |\n\nThree operations cover templates without the `templates` id:\n\n| Operation | Does |\n| --- | --- |\n| `listTemplates` | Lists every template at any depth, paginated. |\n| `saveResourceAsTemplate` | Copies a resource, and with `includeChildren` its descendants, into a new top-level template. The resource does not change. |\n| `createResourceFromTemplate` | Copies a template, and with `includeChildren` its descendants, into a new resource. The name drops the word `Template`. |\n\nOnly a project admin may create a resource under `templates`, move one there, or call `saveResourceAsTemplate`.\nA copy takes the source's fields, properties and documents with their content, under new ids. Mentions in the\ncopied content keep pointing at the resources they named in the source.\n\n## Request ids\n\nEvery response carries an `x-request-id` header; every error body carries the same value as `requestId`.\nA client-supplied `x-request-id` is echoed when it matches `^[A-Za-z0-9._-]{1,64}$`; otherwise a fresh id\nis minted and the supplied value is ignored. The server log line for the request carries the same id, so\nquote it when reporting a problem.\n\n## Idempotency\n\nEvery POST accepts an optional `Idempotency-Key` header of 1–255 characters from `A-Z a-z 0-9 . _ -`.\nA malformed key answers `400` `VALIDATION_ERROR` with `Idempotency-Key` in `errors[].path`. Keys are scoped\nto the API key, or to the user for a session, so two callers never share one.\n\nThe first request with a key runs and its response is kept for 24 hours. A repeat with the same key, method,\npath and body returns the kept status and body without running the write again, with `Idempotent-Replay: true`\nand `Idempotent-Original-Request-Id` naming the first request; its own `x-request-id` is new. A repeat while the\nfirst is still running answers `409` `IN_PROGRESS`; retry it. The same key on a different request answers\n`409` `IDEMPOTENCY_KEY_REUSED`.\n\n2xx and 4xx responses are kept, except the refusals answered before any write: `400` `VALIDATION_ERROR`,\n`401`, `403` and `404`. A refusal, a 5xx or 429 response, or a body over 64 KB is not kept: the key is released\nand a request with the key runs, so a corrected request can reuse the key. PATCH, PUT and DELETE ignore the header.\n\n## Rate limits\n\nAPI-key requests are counted in the tiers below. A request that exhausts any tier answers `429` with\n`code: \"RATE_LIMITED\"`.\n\n| Scope | Window | Limit |\n| --- | --- | --- |\n| Writes (POST, PUT, PATCH, DELETE), per key | 1 minute | 120 |\n| Writes (POST, PUT, PATCH, DELETE), per key | 1 hour | 3,000 |\n| All requests, per key | 1 minute | 300 |\n| All requests, per key | 1 hour | 6,000 |\n| All requests, per key | 1 day | 60,000 |\n| All requests, per project across keys | 1 hour | 12,000 |\n\nTiers are consumed in the order write minute, write hour, key minute, key hour, key day, project hour; a read skips the write tiers.\nEvery response to an authenticated request carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and\n`X-RateLimit-Reset` (a Unix time in seconds) for the tier with the fewest requests remaining, so a write reports\nthe write tier once it is the tightest. A `429` carries them for the tier that rejected, plus `Retry-After` in\nseconds. A request refused before it is counted (a 400 schema error, 401, 402, 403 or 405) carries none. The\nper-project tier is keyed on the key's project, so every key of a project draws on it."},"servers":[{"url":"https://www.legendkeeper.com","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Project API key. Create one in Project Settings → Developers → API Keys. A key acts with the lower of its own role and its creator's project role, and only in its own project: a request that names another project answers 403 WRONG_PROJECT. An API key has at most the ADMIN role, and is accepted only on /api/v3 routes: the app's /api/v1 and /api/v2 routes answer 403 FORBIDDEN to a key. Keys need the project owner to be on a paid plan (a trial does not count): creating a key, and every request a key authenticates, answers 402 PAID_PLAN_REQUIRED while the owner is not."}},"schemas":{"BoardJsonValue":{"description":"Any JSON value: a string of up to 100,000 characters, a number, a boolean, null, an array of up to 10,000 values, or an object of up to 10,000 keys of up to 256 characters. Arrays and objects nest at most 32 levels.","x-max-depth":32,"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/BoardJsonValue"}},{"type":"object","maxProperties":10000,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/BoardJsonValue"}}]},"JsonValue":{"description":"Any JSON value: a string of up to 100,000 characters, a number, a boolean, null, an array of up to 256 values, or an object of up to 256 keys of up to 256 characters. Arrays and objects nest at most 8 levels.","x-max-depth":8,"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","maxItems":256,"items":{"$ref":"#/components/schemas/JsonValue"}},{"type":"object","maxProperties":256,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}]},"MapImage":{"type":"object","properties":{"assetId":{"type":["string","null"],"description":"The image asset in the project's library whose `url` is the map's image. null when no image asset readable by the caller has that url: the asset was deleted, it is hidden and the caller is not a project admin, or the map uses a legacy tiled map."},"url":{"type":["string","null"],"description":"The URL of the map's image. null for a legacy tiled map, which has no single image file."},"width":{"type":"integer","exclusiveMinimum":0,"description":"The image width in pixels."},"height":{"type":"integer","exclusiveMinimum":0,"description":"The image height in pixels."},"bounds":{"type":"array","prefixItems":[{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2}],"description":"`[[south, west], [north, east]]`, the `[lat, lng]` corners the image covers. `north` and `west` are 0 at the image's top-left corner; `south` is negative and `east` is positive.","minItems":2,"maxItems":2}},"required":["assetId","url","width","height","bounds"],"description":"The image of a map document and its coordinate frame. Feature `pos` values are `[lat, lng]` in this frame, the frame the app uses when a feature is placed by clicking the map. A pixel `(x, y)` of the image, counted in pixels from its top-left corner, is at `pos = [north - y * (north - south) / height, west + x * (east - west) / width]`, which is `[-y / 2^z, x / 2^z]` with `z = ceil(log2(max(width, height) / 256))`. A `pos` converts back with `x = (lng - west) * width / (east - west)` and `y = (north - lat) * height / (north - south)`. The SDK exports this conversion as `pixelToPos` and `posToPixel`."},"TextFieldProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["textField"]},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","children"],"additionalProperties":false},"KeyValueProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["keyValue"]},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","rows"],"additionalProperties":false},"ImageProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","url"],"additionalProperties":false,"description":"An image property by `url`. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL. `fill: true` draws the image edge to edge with no frame or title, as the app's \"Fill block\" option does."},"MeterProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["meter"]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","mode","items"],"additionalProperties":false},"FilterPredicate":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["field"]},"field":{"type":"string","maxLength":256},"operator":{"type":"string","enum":["equals","not_equals","greater_than","greater_than_or_equal","less_than","less_than_or_equal","contains","starts_with","ends_with","regex","in","not_in"]},"value":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]},"maxItems":1000},{"type":"null"}]}},"required":["type","id","filterType","field","operator"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["id"]},"operator":{"type":"string","enum":["in","not_in"]},"ids":{"type":"array","items":{"anyOf":[{"type":"string","maxLength":256},{"type":"number"}]},"maxItems":1000}},"required":["type","id","filterType","operator","ids"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["tag"]},"operator":{"type":"string","enum":["has_all","has_any","has_none"]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":1000}},"required":["type","id","filterType","operator","tags"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["custom"]},"predicate":{"type":"string","maxLength":256},"params":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]},"maxItems":1000},{"type":"null"}]},"maxProperties":64,"propertyNames":{"type":"string","maxLength":256}}},"required":["type","id","filterType","predicate"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["date_range"]},"field":{"type":"string","maxLength":256},"start":{"type":"number"},"end":{"type":"number"}},"required":["type","id","filterType","field"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["property"]},"propertyType":{"type":"string","maxLength":256},"key":{"type":"string","maxLength":256},"field":{"type":"string","enum":["textValue","numValue","meterCurrent","meterMax"]},"operator":{"type":"string","enum":["equals","not_equals","greater_than","greater_than_or_equal","less_than","less_than_or_equal","contains","starts_with","ends_with","regex","in","not_in"]},"value":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"anyOf":[{"type":"string","maxLength":100000},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]},"maxItems":1000},{"type":"null"}]}},"required":["type","id","filterType","operator"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["mention"]},"targetId":{"type":"string","maxLength":256},"propertyType":{"type":"string","maxLength":256},"key":{"type":"string","maxLength":256}},"required":["type","id","filterType","targetId"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["text"]},"operator":{"type":"string","enum":["contains"]},"value":{"type":"string","maxLength":100000}},"required":["type","id","filterType","operator","value"]},{"type":"object","properties":{"type":{"type":"string","enum":["filter"]},"id":{"type":"string","maxLength":256},"scope":{"type":"string","maxLength":256},"filterType":{"type":"string","enum":["composite"]},"operator":{"type":"string","enum":["and","or","not"]},"filters":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/FilterPredicate"}}},"required":["type","id","filterType","operator","filters"]}],"description":"A collection filter. `composite` combines `filters` with `and`, `or` or `not`. Nesting through `children`, `rows` and filter `filters` is limited to 64 levels; deeper input answers 400 VALIDATION_ERROR.","x-max-depth":64},"ResourceCollectionProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceCollection"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind"],"additionalProperties":false},"ResourceLinkProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceLink"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","items"],"additionalProperties":false},"EmbedProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["embed"]},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"url":{"type":"string","maxLength":2048},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind","provider","url"],"additionalProperties":false,"description":"An embedded player property. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"MapViewport":{"type":"object","properties":{"center":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"zoom":{"type":"number"}},"required":["center","zoom"],"additionalProperties":false,"description":"The view a map opens at: `center` as `[lat, lng]` in the map's coordinate frame, the frame of a feature's `pos`, and the Leaflet `zoom` level."},"MapProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["map"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"}},"required":["kind"],"additionalProperties":false,"description":"An interactive map property. `resourceId` and `documentId` name a `map` document of this project that the caller can read. A resource or document that does not exist, is deleted, is hidden from the caller, belongs to another project or is not a `map` document answers 400 VALIDATION_ERROR naming the field, unless the same document or resource already holds that map. Name both ids or neither; a map with neither is an empty block that the app shows as \"Link a map\". `viewport` is the view the map opens at; omit it to center at zoom 4, or at the map's deepest zoom when that is lower, on a pin of the map whose link points to the resource holding the map. `displayHeight` is the height in pixels, 150 to 800; the app draws 200 when it is omitted. `fill: true` draws the map edge to edge and hides the title whatever `isTitleHidden` says."},"UnsupportedProperty":{"type":"object","properties":{"kind":{"type":"string","enum":["unsupported"]},"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"}},"required":["kind","id"],"additionalProperties":false},"PropertyBlock":{"oneOf":[{"$ref":"#/components/schemas/TextFieldProperty"},{"$ref":"#/components/schemas/KeyValueProperty"},{"$ref":"#/components/schemas/ImageProperty"},{"$ref":"#/components/schemas/MeterProperty"},{"$ref":"#/components/schemas/ResourceCollectionProperty"},{"$ref":"#/components/schemas/ResourceLinkProperty"},{"$ref":"#/components/schemas/EmbedProperty"},{"$ref":"#/components/schemas/MapProperty"},{"$ref":"#/components/schemas/UnsupportedProperty"}],"discriminator":{"propertyName":"kind","mapping":{"textField":"#/components/schemas/TextFieldProperty","keyValue":"#/components/schemas/KeyValueProperty","image":"#/components/schemas/ImageProperty","meter":"#/components/schemas/MeterProperty","resourceCollection":"#/components/schemas/ResourceCollectionProperty","resourceLink":"#/components/schemas/ResourceLinkProperty","embed":"#/components/schemas/EmbedProperty","map":"#/components/schemas/MapProperty","unsupported":"#/components/schemas/UnsupportedProperty"}},"description":"A sidebar or infobox property: a structured block kind plus the property envelope (`rank`, `title`, `isTitleHidden`, `isHidden`). A property the public model cannot express reads as `kind: \"unsupported\"` with its id and envelope. A property is laid out by the infobox or sidebar that holds it, so it carries neither `layout` nor `width`. Nesting through `children`, `rows` and filter `filters` is limited to 64 levels; deeper input answers 400 VALIDATION_ERROR.","x-max-depth":64},"ListedDocument":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"type":{"type":["string","null"],"description":"The document type, as on Document: `page`, `board`, `map`, `time` or `blank`."}},"required":["id","name","type"],"description":"A document as listed on a ResourceListItem."},"ResourceListItem":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"parentId":{"type":["string","null"]},"iconGlyph":{"type":["string","null"]},"iconColor":{"type":["string","null"],"description":"Fill color of this resource's map pins. Also tints its cards and graph nodes. Written as `#RRGGBB`; a resource from an import or an older version may hold another CSS color string. Null when no color is stored."},"tags":{"type":"array","items":{"type":"string"}},"aliases":{"type":"array","items":{"type":"string"},"description":"Alternative names of the resource, as on getResource."},"rank":{"type":["string","null"]},"isHidden":{"type":"boolean"},"createdAt":{"type":["string","null"],"format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"updatedAt":{"type":["string","null"],"format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin, or `none` for the glyph alone."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape. Absent when `iconShape` is `none`."},"documents":{"type":"array","items":{"$ref":"#/components/schemas/ListedDocument"},"description":"The resource's documents, ordered by name. Deleted documents are left out, and so are hidden documents for a caller who is not a project admin. Read a document by id for its content and settings."}},"required":["id","name","tags","aliases","documents"],"description":"A resource as listed: identity, icon, tags, aliases, rank and its documents' ids, names and types, enough to compare a page of resources with a local copy without reading each one. Read a resource by id for its properties, permissions and lock state."},"ResourceList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ResourceListItem"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"ErrorCode":{"type":"string","enum":["VALIDATION_ERROR","INVALID_CONTENT","UNSUPPORTED_KIND","KIND_MISMATCH","UNAUTHENTICATED","SUBSCRIPTION_LAPSED","PAID_PLAN_REQUIRED","FORBIDDEN","WRONG_PROJECT","INSUFFICIENT_SCOPE","FEATURE_UNAVAILABLE","NOT_FOUND","METHOD_NOT_ALLOWED","DUPLICATE_ID","AMBIGUOUS","ALREADY_DELETED","HAS_CHILDREN","NOT_DELETED","PARENT_DELETED","IN_PROGRESS","IDEMPOTENCY_KEY_REUSED","TOO_MANY_PENDING_INVITES","VERSION_MISMATCH","DOCUMENT_TOO_LARGE","PAYLOAD_TOO_LARGE","STORAGE_QUOTA_EXCEEDED","RATE_LIMITED","UPLOAD_RATE_EXCEEDED","INTERNAL"],"description":"The closed set of error codes. Each code has one status; the Errors section lists them."},"Error":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable. Stable in meaning, not in wording."},"code":{"$ref":"#/components/schemas/ErrorCode"},"requestId":{"type":"string","description":"The same value as the `x-request-id` response header. Quote it when reporting a problem."},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"]},"description":"On 400 responses only: one entry per failing field or block; path is dotted (`block.children[0].level`). A `KIND_MISMATCH` response carries no `errors`."}},"required":["message","code","requestId"],"description":"The body of every 4xx and 5xx response."},"TimelineSource":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256,"description":"The resource that holds the source timeline."},"documentId":{"type":"string","minLength":1,"maxLength":256,"description":"The source timeline document."}},"required":["resourceId","documentId"],"additionalProperties":false,"description":"A timeline (`time`) document that another timeline chains as a source. listLanes and listEvents on the chaining timeline include the lanes and events of its sources, and of their sources in turn."},"Document":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["blank","page","board","map","time"]},"rank":{"type":"string"},"isHidden":{"type":"boolean"},"isFullWidth":{"type":"boolean"},"deletedAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"createdAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"updatedAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"calendarId":{"type":"string","description":"On a timeline (`time`) document, the id of the calendar its dates render in, as listed by listCalendars. Absent when the timeline has no calendar assigned; it then renders in the Gregorian calendar, as it does when the id names a deleted calendar. Absent on other document types."},"mapImage":{"anyOf":[{"$ref":"#/components/schemas/MapImage"},{"type":"null"}]},"sources":{"type":"array","items":{"$ref":"#/components/schemas/TimelineSource"},"description":"On a timeline (`time`) document, the timelines it chains, in order; empty when it chains none. A reference to a timeline the caller cannot read, because its resource is unreachable, it is hidden from a caller who is not a project admin, or it or its resource is deleted, is left out. Absent on other document types."}},"required":["id","name","type","rank","isHidden"],"description":"A document of a resource. `type` is `page`, `board`, `map`, `time` or `blank`. A new resource's first document is `blank`. The first write of page blocks, board records, map features or timeline lanes to a `blank` document converts it to a `page`, `board`, `map` or `time` document and keeps its name, as picking a type for a blank document in the app does; a write that is refused or changes nothing leaves it `blank`, and reads never convert it. Once converted, the document answers 400 KIND_MISMATCH to writes of another type. A map document carries `mapImage` in the responses of getDocument, createDocument and updateDocument: its image and coordinate frame, or null when it has no image. listDocuments and getResource do not include `mapImage`. A timeline document carries `sources` in the responses of listDocuments, getDocument, createDocument and updateDocument; getResource does not include `sources`."},"Resource":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"aliases":{"type":"array","items":{"type":"string"}},"iconGlyph":{"type":"string"},"iconColor":{"type":"string","description":"Fill color of this resource's map pins. Also tints its cards and graph nodes. Written as `#RRGGBB`; a resource from an import or an older version may hold another CSS color string."},"parentId":{"type":"string"},"rank":{"type":"string"},"isHidden":{"type":"boolean"},"isLocked":{"type":"boolean"},"isFullWidth":{"type":"boolean"},"showPropertyBar":{"type":"boolean"},"imageUrl":{"type":"string"},"banner":{"type":"object","properties":{"enabled":{"type":"boolean"},"url":{"type":"string"},"yPosition":{"type":"number"}},"required":["enabled","url","yPosition"]},"permissions":{"type":"object","additionalProperties":{"type":"integer","enum":[0,1,2,3,4,5]}},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"properties":{"type":"array","items":{"$ref":"#/components/schemas/PropertyBlock"}},"createdAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"updatedAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin, or `none` for the glyph alone."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape. Absent when `iconShape` is `none`."}},"required":["id","name","tags","aliases","rank","isHidden","permissions","documents","properties"],"description":"A resource. `properties` are its sidebar properties as PropertyBlocks. `iconSize` is absent when `iconShape` is `none`, and both are absent when no shape is stored; the app then draws a medium `pin`. A shape stored by the app in an older format reads as the app draws it: a glyph-only shape reads as `none`, and any other shape outside these values reads as `pin` and `medium`."},"ResourceDocumentParams":{"type":"object","properties":{"type":{"type":"string","enum":["blank","page","board","map","time"],"description":"The document type: `page`, `board`, `map`, `time` or `blank`. Defaults to `page` when `blocks` is sent, otherwise to `blank`."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"The document name, 1–500 characters. Defaults to `Main`."},"calendarId":{"type":"string","minLength":1,"maxLength":100,"description":"For a timeline (`time`) document, the id of a calendar from listCalendars, custom or built-in. An id that names no calendar in the project, or a `calendarId` with any other type, answers 400 VALIDATION_ERROR at `documents[i].calendarId`."},"blocks":{"type":"array","description":"The content of a `page` document as Blocks, validated as replaceDocumentBlocks validates them. Blocks with any other type answer 400 VALIDATION_ERROR at `documents[i].blocks`.","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"additionalProperties":false,"description":"A document of a new resource."},"ResourceCreateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"parentId":{"type":"string","maxLength":256,"description":"The parent resource. Omitted, the resource is created at the root. `templates` creates a top-level template. An unknown or deleted id answers 404 NOT_FOUND. A caller who is not a project admin must name a resource they can edit (Can Edit or Full Access), and cannot name `templates`."},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50},"aliases":{"type":"array","items":{"type":"string","maxLength":256},"maxItems":128},"iconGlyph":{"type":"string","maxLength":128,"description":"FontAwesome icon name (e.g., \"crown\", \"dog\", \"snowflake\"). See fontawesome.com/icons for valid names. An unknown name answers 400 VALIDATION_ERROR."},"iconColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of this resource's map pins, as `#RRGGBB`. Also tints its cards and graph nodes. Defaults to `#C49454`."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin: `pin`, `diamond`, `flag`, `marker`, `shield`, `circle`, `banner` or `arch`, or `none` for the glyph alone. Any other value answers 400 VALIDATION_ERROR at the field. Omitted while `iconSize` is sent, it is `pin`. A resource created with neither `iconShape` nor `iconSize` has `iconShape` `none`."},"isHidden":{"type":"boolean","description":"`true` creates the resource hidden. Only a project admin may create a hidden resource; a caller who is not answers 403 FORBIDDEN."},"isLocked":{"type":"boolean"},"banner":{"type":"object","properties":{"enabled":{"type":"boolean"},"url":{"type":"string","maxLength":2048,"description":"The banner image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"yPosition":{"type":"number"}},"required":["enabled","url","yPosition"]},"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers. A malformed id answers 400 VALIDATION_ERROR. An id already used by a resource of the project, including a deleted one, answers 409 DUPLICATE_ID."},"documents":{"type":"array","items":{"$ref":"#/components/schemas/ResourceDocumentParams"},"minItems":1,"maxItems":5,"description":"1–5 documents, created in this order. Omitted, the resource starts with one `blank` document named `Main`, which its first typed write converts."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape: `medium` or `small`. Ignored when `iconShape` is `none`. Any other value answers 400 VALIDATION_ERROR at the field. Omitted while `iconShape` is sent, it is `medium`."},"after":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly after it. Mutually exclusive with `before`."},"before":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly before it. Mutually exclusive with `after`."}},"required":["name"],"additionalProperties":false},"ResourceBatch":{"type":"object","properties":{"resources":{"type":"array","items":{"$ref":"#/components/schemas/Resource"}}},"required":["resources"],"description":"The created resources, in the order of the request."},"ResourceBatchCreateParams":{"type":"object","properties":{"resources":{"type":"array","items":{"$ref":"#/components/schemas/ResourceCreateParams"},"minItems":1,"maxItems":100,"description":"1–100 resources to create, each a ResourceCreateParams, created in this order. An item may name an earlier item of the same batch as its `parentId` when that earlier item has an `id`; such an item is placed after its earlier siblings in the batch and cannot use `after` or `before`. A `parentId` that names a later item answers 404 NOT_FOUND."}},"required":["resources"]},"ResourceFromTemplateParams":{"type":"object","properties":{"templateId":{"type":"string","maxLength":256,"description":"The template to copy: a resource under the `templates` root, at any depth. A resource that is not a template answers 400 VALIDATION_ERROR. An unknown or deleted id, or one the caller cannot view, answers 404 NOT_FOUND."},"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id for the new resource: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers. An id already used by a resource of the project answers 409 DUPLICATE_ID."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Name of the new resource. Omitted, it is the template's name with the word `Template` removed."},"parentId":{"type":"string","maxLength":256,"description":"The parent of the new resource, as in createResource. Omitted, the resource is created at the root. An unknown or deleted id answers 404 NOT_FOUND."},"includeChildren":{"type":"boolean","description":"`true` also copies the template's descendants the caller can view, keeping their tree. Default false. A copy holds at most 100 resources; a larger template answers 400 VALIDATION_ERROR."},"after":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly after it. Mutually exclusive with `before`."},"before":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly before it. Mutually exclusive with `after`."}},"required":["templateId"],"additionalProperties":false},"ResourceSaveAsTemplateParams":{"type":"object","properties":{"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id for the new template: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers. An id already used by a resource of the project answers 409 DUPLICATE_ID."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Name of the new template. Omitted, it is the resource's name."},"includeChildren":{"type":"boolean","description":"`true` also copies the resource's descendants the caller can view, keeping their tree. Default false. A copy holds at most 100 resources; a larger tree answers 400 VALIDATION_ERROR."},"after":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly after it. Mutually exclusive with `before`."},"before":{"type":"string","maxLength":256,"description":"Id of a sibling under the same parent. The resource is placed directly before it. Mutually exclusive with `after`."}},"additionalProperties":false},"ResourceUpdateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50},"aliases":{"type":"array","items":{"type":"string","maxLength":256},"maxItems":128},"iconGlyph":{"type":"string","maxLength":128,"description":"FontAwesome icon name (e.g., \"crown\", \"dog\", \"snowflake\"). See fontawesome.com/icons for valid names. An unknown name answers 400 VALIDATION_ERROR."},"iconColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of this resource's map pins, as `#RRGGBB`. Also tints its cards and graph nodes."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin: `pin`, `diamond`, `flag`, `marker`, `shield`, `circle`, `banner` or `arch`, or `none` for the glyph alone. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconSize`, the stored `iconSize` is kept, or `medium` when none is stored."},"isHidden":{"type":"boolean","description":"Only project admins may change `isHidden`. A change by a caller who is not a project admin answers 403 FORBIDDEN."},"isLocked":{"type":"boolean"},"banner":{"type":"object","properties":{"enabled":{"type":"boolean"},"url":{"type":"string","maxLength":2048,"description":"The banner image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"yPosition":{"type":"number"}},"required":["enabled","url","yPosition"]},"permissions":{"type":"object","additionalProperties":{"type":"integer","enum":[0,1,2,3,4,5]},"description":"Access levels keyed by a role (`MEMBER`, `ADMIN` or `OWNER`) or a user id. A level is 0 No Access, 1 Can Read, 2 Can Edit, 3 Full Access, 4 defer to the role or 5 inherit from the parent. Entries not sent keep their value. Changing `permissions` needs project admin or Full Access on the resource; otherwise the request answers 403 FORBIDDEN.","maxProperties":1000,"propertyNames":{"type":"string","maxLength":256}},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape: `medium` or `small`. Ignored when `iconShape` is `none`. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconShape`, the stored `iconShape` is kept, or `pin` when none is stored."}},"additionalProperties":false},"ResourceMoveParams":{"type":"object","properties":{"parentId":{"type":["string","null"],"maxLength":256,"description":"The new parent resource id, or null for the root. `templates` makes the resource a top-level template; only a project admin may name it. Omitted, the resource stays under its current parent. The resource itself or one of its descendants answers 400 VALIDATION_ERROR. An unknown or deleted id answers 404 NOT_FOUND."},"after":{"type":"string","maxLength":256,"description":"Id of a sibling under the destination parent. The resource is placed directly after it. Sending both `after` and `before` answers 400 VALIDATION_ERROR. An anchor that is not a child of the destination parent answers 400 VALIDATION_ERROR; an unknown or deleted anchor answers 404 NOT_FOUND."},"before":{"type":"string","maxLength":256,"description":"Id of a sibling under the destination parent. The resource is placed directly before it. Sending both `after` and `before` answers 400 VALIDATION_ERROR. An anchor that is not a child of the destination parent answers 400 VALIDATION_ERROR; an unknown or deleted anchor answers 404 NOT_FOUND."}},"additionalProperties":false},"DocumentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"DocumentCreateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"type":{"type":"string","enum":["blank","page","board","map","time"]},"isHidden":{"type":"boolean","description":"Defaults to false."},"isFullWidth":{"type":"boolean","description":"Defaults to false."},"calendarId":{"type":"string","minLength":1,"maxLength":100,"description":"The id of a calendar from listCalendars, custom or built-in, that a timeline (`time`) document's dates render in. An id that names no calendar in the project, or a `calendarId` on any other document type, answers 400 VALIDATION_ERROR at `calendarId`."}},"required":["name","type"],"additionalProperties":false},"MapImageParams":{"type":"object","properties":{"assetId":{"type":"string","minLength":1,"maxLength":256,"description":"An image asset in the project's library that the caller can read. An `assetId` that is not an asset of this project, is not an image, or is hidden from a caller who is not a project admin answers 400 VALIDATION_ERROR at `mapImage.assetId`."}},"required":["assetId"],"additionalProperties":false,"description":"The image asset to show as a map document's image. It sets or replaces the image, as \"Add map\" and \"Replace map\" do in the app. The map's coordinate frame follows from the image's pixel size; the response's `mapImage` carries it (see MapImage). Features keep their `pos`: after a replacement with an image of another size, a feature sits over a different pixel of the new image. The app draws the image from tiles cut from the asset on request, so the map shows it with no processing step. A document that is not a map or `blank` answers 400 KIND_MISMATCH. A write to a `blank` document converts it to a map document and saves the content in the same request."},"DocumentUpdateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":500},"rank":{"type":"string","maxLength":65536},"isHidden":{"type":"boolean"},"isFullWidth":{"type":"boolean"},"calendarId":{"type":"string","minLength":1,"maxLength":100,"description":"The id of a calendar from listCalendars, custom or built-in, that a timeline (`time`) document's dates render in. An id that names no calendar in the project, or a `calendarId` on any other document type, answers 400 VALIDATION_ERROR at `calendarId`. Changing it does not touch the timeline's events: they keep their times and render in the new calendar."},"mapImage":{"$ref":"#/components/schemas/MapImageParams"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/TimelineSource"},"maxItems":100,"description":"The timelines this timeline (`time`) document chains, in order. `sources` replaces the timelines a timeline (`time`) document chains, as adding and removing timelines with the timeline picker on a timeline does in the app; `[]` removes them all. It takes at most 100 references. Each must name a timeline (`time`) document of this project that the caller can read and that is not deleted, other than the document itself, and appear once. Chains may loop: a timeline may chain a timeline that chains it, directly or through others, and listLanes and listEvents include each timeline in the loop once. A reference that breaks a rule answers 400 VALIDATION_ERROR at `sources[i]`, its index, and nothing is written; `sources` on a document that is not a timeline answers 400 VALIDATION_ERROR at `sources`. References stored on the document that the caller cannot read are kept after the write. The document's filters are not changed."}},"additionalProperties":false},"BlockIdsResult":{"type":"object","properties":{"assigned":{"type":"integer","minimum":0},"version":{"type":"string"}},"required":["assigned","version"]},"PropertyList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PropertyBlock"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"PropertyCreateRequest":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["textField"]},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","children"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["keyValue"]},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","rows"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","url"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["meter"]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","mode","items"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceCollection"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceLink"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","items"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["embed"]},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"url":{"type":"string","maxLength":2048},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind","provider","url"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["map"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"before":{"type":"string","maxLength":256,"description":"Place before this property id."},"after":{"type":"string","maxLength":256,"description":"Place after this property id."}},"required":["kind"],"additionalProperties":false}],"description":"A property to create: `kind` plus that kind's fields, an optional `id`, the envelope fields `title`, `isTitleHidden` and `isHidden`, and optional `before`/`after` placement (at most one; neither appends last). `rank` is set by placement and is rejected in the body with 400 VALIDATION_ERROR. `kind: \"unsupported\"` cannot be created and answers 400 UNSUPPORTED_KIND."},"PropertyUpdateRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"anyOf":[{"type":"boolean"},{"type":"boolean"}]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256}]},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800}},"additionalProperties":false,"description":"A partial PropertyBlock: any of the envelope fields (`rank`, `title`, `isTitleHidden`, `isHidden`) and any field of the property's own kind. The patch is merged over the current property and the result is validated as a whole, so a field of another kind answers 400 VALIDATION_ERROR. `kind` and `id` cannot be patched."},"DocumentBlocks":{"type":"object","properties":{"id":{"type":"string"},"version":{"type":"string"},"schema":{"type":"number","enum":[1],"description":"Block model version."},"text":{"type":"string","description":"Plain text of the document, one line per text-bearing block. A mention reads as its label, or else its resource's name."},"blocks":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["id","version","schema","text","blocks"]},"DocumentBlocksWrite":{"type":"object","properties":{"blocks":{"type":"array","description":"The whole new tree. A block without an id is given a new id; a requested id is kept. The same block id twice answers 400 VALIDATION_ERROR at the second occurrence.","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["blocks"],"additionalProperties":false,"description":"Whole-document replacement. `unsupported` blocks are preserved only when echoed by id."},"Run":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}],"description":"A text run with optional marks, a mention, or a line break. A run with `code: true` carries no other mark, and a run carries at most one of `sub` and `sup`. Runs are normalized on write: a run whose `text` is empty is dropped, and adjacent runs carrying identical marks are merged into one. A mention's `text` is an optional label. `name` is the resource's current name; it is read-only."},"VersionedParagraphBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["paragraph"]},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000},"version":{"type":"string"}},"required":["kind","content","version"],"additionalProperties":false},"VersionedHeadingBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["heading"]},"level":{"type":"integer","minimum":1,"maximum":6},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000},"version":{"type":"string"}},"required":["kind","level","content","version"],"additionalProperties":false},"VersionedQuoteBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["quote"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedCodeBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["code"]},"language":{"type":"string","maxLength":256},"text":{"type":"string","maxLength":100000},"version":{"type":"string"}},"required":["kind","text","version"],"additionalProperties":false},"VersionedRuleBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["rule"]},"version":{"type":"string"}},"required":["kind","version"],"additionalProperties":false},"VersionedBulletListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["bulletList"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedOrderedListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["orderedList"]},"start":{"type":"integer","minimum":0},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedListItemBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["listItem"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedTaskListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["taskList"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedTaskItemBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["taskItem"]},"checked":{"type":"boolean"},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000},"version":{"type":"string"}},"required":["kind","checked","content","version"],"additionalProperties":false},"VersionedTableBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["table"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedTableRowBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["tableRow"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedTableCellBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["tableCell"]},"header":{"type":"boolean"},"colspan":{"type":"integer","minimum":1},"rowspan":{"type":"integer","minimum":1},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedCalloutBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["callout"]},"tone":{"type":"string","enum":["info","note","success","warning","error","custom"]},"icon":{"type":"string","maxLength":256},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Icon color and background tint, as `#RRGGBB`. Accepted only when `tone` is `custom`; the other tones draw their own color."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","tone","children","version"],"additionalProperties":false},"VersionedExpandBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["expand"]},"title":{"type":"string","maxLength":2048},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","title","children","version"],"additionalProperties":false},"VersionedLayoutBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["layout"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedLayoutColumnBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["layoutColumn"]},"width":{"type":"number","minimum":0,"maximum":100},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"BlockLayout":{"type":"string","enum":["default","wrapLeft","wrapRight","center","alignStart","alignEnd"],"description":"Where a block sits in the flow of the page. `default` is full width. `wrapLeft` and `wrapRight` float the block to that side and let the text after it wrap beside it. `center`, `alignStart` and `alignEnd` place a narrowed block on its own line."},"VersionedImageBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","url","version"],"additionalProperties":false},"VersionedEmbedBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["embed"]},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"url":{"type":"string","maxLength":2048},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","provider","url","version"],"additionalProperties":false},"VersionedKeyValueBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["keyValue"]},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","rows","version"],"additionalProperties":false},"VersionedInfoboxBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["infobox"]},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"rows":{"type":"array","maxItems":256,"items":{"$ref":"#/components/schemas/PropertyBlock"}},"version":{"type":"string"}},"required":["kind","rows","version"],"additionalProperties":false},"VersionedMeterBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["meter"]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","mode","items","version"],"additionalProperties":false},"VersionedResourceCollectionBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceCollection"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","version"],"additionalProperties":false},"VersionedResourceLinkBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceLink"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","items","version"],"additionalProperties":false},"VersionedMapBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["map"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"version":{"type":"string"}},"required":["kind","version"],"additionalProperties":false},"VersionedSecretBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["secret"]},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedTextFieldBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["textField"]},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedUnsupportedBlock":{"type":"object","properties":{"kind":{"type":"string","enum":["unsupported"]},"id":{"type":"string","minLength":1,"maxLength":256},"version":{"type":"string"}},"required":["kind","id","version"],"additionalProperties":false},"VersionedBlock":{"oneOf":[{"$ref":"#/components/schemas/VersionedParagraphBlock"},{"$ref":"#/components/schemas/VersionedHeadingBlock"},{"$ref":"#/components/schemas/VersionedQuoteBlock"},{"$ref":"#/components/schemas/VersionedCodeBlock"},{"$ref":"#/components/schemas/VersionedRuleBlock"},{"$ref":"#/components/schemas/VersionedBulletListBlock"},{"$ref":"#/components/schemas/VersionedOrderedListBlock"},{"$ref":"#/components/schemas/VersionedListItemBlock"},{"$ref":"#/components/schemas/VersionedTaskListBlock"},{"$ref":"#/components/schemas/VersionedTaskItemBlock"},{"$ref":"#/components/schemas/VersionedTableBlock"},{"$ref":"#/components/schemas/VersionedTableRowBlock"},{"$ref":"#/components/schemas/VersionedTableCellBlock"},{"$ref":"#/components/schemas/VersionedCalloutBlock"},{"$ref":"#/components/schemas/VersionedExpandBlock"},{"$ref":"#/components/schemas/VersionedLayoutBlock"},{"$ref":"#/components/schemas/VersionedLayoutColumnBlock"},{"$ref":"#/components/schemas/VersionedImageBlock"},{"$ref":"#/components/schemas/VersionedEmbedBlock"},{"$ref":"#/components/schemas/VersionedKeyValueBlock"},{"$ref":"#/components/schemas/VersionedInfoboxBlock"},{"$ref":"#/components/schemas/VersionedMeterBlock"},{"$ref":"#/components/schemas/VersionedResourceCollectionBlock"},{"$ref":"#/components/schemas/VersionedResourceLinkBlock"},{"$ref":"#/components/schemas/VersionedMapBlock"},{"$ref":"#/components/schemas/VersionedSecretBlock"},{"$ref":"#/components/schemas/VersionedTextFieldBlock"},{"$ref":"#/components/schemas/VersionedUnsupportedBlock"}],"discriminator":{"propertyName":"kind","mapping":{"paragraph":"#/components/schemas/VersionedParagraphBlock","heading":"#/components/schemas/VersionedHeadingBlock","quote":"#/components/schemas/VersionedQuoteBlock","code":"#/components/schemas/VersionedCodeBlock","rule":"#/components/schemas/VersionedRuleBlock","bulletList":"#/components/schemas/VersionedBulletListBlock","orderedList":"#/components/schemas/VersionedOrderedListBlock","listItem":"#/components/schemas/VersionedListItemBlock","taskList":"#/components/schemas/VersionedTaskListBlock","taskItem":"#/components/schemas/VersionedTaskItemBlock","table":"#/components/schemas/VersionedTableBlock","tableRow":"#/components/schemas/VersionedTableRowBlock","tableCell":"#/components/schemas/VersionedTableCellBlock","callout":"#/components/schemas/VersionedCalloutBlock","expand":"#/components/schemas/VersionedExpandBlock","layout":"#/components/schemas/VersionedLayoutBlock","layoutColumn":"#/components/schemas/VersionedLayoutColumnBlock","image":"#/components/schemas/VersionedImageBlock","embed":"#/components/schemas/VersionedEmbedBlock","keyValue":"#/components/schemas/VersionedKeyValueBlock","infobox":"#/components/schemas/VersionedInfoboxBlock","meter":"#/components/schemas/VersionedMeterBlock","resourceCollection":"#/components/schemas/VersionedResourceCollectionBlock","resourceLink":"#/components/schemas/VersionedResourceLinkBlock","map":"#/components/schemas/VersionedMapBlock","secret":"#/components/schemas/VersionedSecretBlock","textField":"#/components/schemas/VersionedTextFieldBlock","unsupported":"#/components/schemas/VersionedUnsupportedBlock"}},"description":"A Block plus the document `version` it was read or written at."},"ParagraphBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["paragraph"]},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000}},"required":["kind","content"],"additionalProperties":false},"HeadingBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["heading"]},"level":{"type":"integer","minimum":1,"maximum":6},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000}},"required":["kind","level","content"],"additionalProperties":false},"QuoteBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["quote"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"CodeBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["code"]},"language":{"type":"string","maxLength":256},"text":{"type":"string","maxLength":100000}},"required":["kind","text"],"additionalProperties":false},"RuleBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["rule"]}},"required":["kind"],"additionalProperties":false},"BulletListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["bulletList"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"OrderedListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["orderedList"]},"start":{"type":"integer","minimum":0},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false,"description":"An ordered list. `start` is the first number; `start: 1` is the default and is omitted on read."},"ListItemBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["listItem"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false,"description":"The first child must be a paragraph; nested bulletList and orderedList blocks follow it."},"TaskListBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["taskList"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"TaskItemBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["taskItem"]},"checked":{"type":"boolean"},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000}},"required":["kind","checked","content"],"additionalProperties":false},"TableBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["table"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"TableRowBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["tableRow"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"TableCellBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["tableCell"]},"header":{"type":"boolean"},"colspan":{"type":"integer","minimum":1},"rowspan":{"type":"integer","minimum":1},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"CalloutBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["callout"]},"tone":{"type":"string","enum":["info","note","success","warning","error","custom"]},"icon":{"type":"string","maxLength":256},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Icon color and background tint, as `#RRGGBB`. Accepted only when `tone` is `custom`; the other tones draw their own color."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","tone","children"],"additionalProperties":false},"ExpandBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["expand"]},"title":{"type":"string","maxLength":2048},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","title","children"],"additionalProperties":false},"LayoutBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["layout"]},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"LayoutColumnBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["layoutColumn"]},"width":{"type":"number","minimum":0,"maximum":100},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false},"ImageBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind","url"],"additionalProperties":false,"description":"An image by `url`. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL. `fill: true` draws the image edge to edge with no frame or title, as the app's \"Fill block\" option does. It applies while `isTitleHidden` is true; an omitted `fill` reads as absent and draws the framed image. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Image\"` and `isTitleHidden: true`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"EmbedBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["embed"]},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"url":{"type":"string","maxLength":2048},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind","provider","url"],"additionalProperties":false,"description":"An embedded player; the URL must belong to `provider` and may be on any host the provider uses. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Embed\"` and `isTitleHidden: true`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"KeyValueBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["keyValue"]},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind","rows"],"additionalProperties":false,"description":"Key-value rows drawn in the `display` variant. A row value is `content` (runs) or `text` (a plain string); `content` wins when both are sent and `text` is always returned alongside `content`. A leading or trailing `{ break: true }` run in a row value is trimmed. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Stats\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"InfoboxBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["infobox"]},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"rows":{"type":"array","maxItems":256,"items":{"$ref":"#/components/schemas/PropertyBlock"}}},"required":["kind","rows"],"additionalProperties":false,"description":"An infobox whose `rows` are properties. Carries `layout` and `width`. A new one written without them is `wrapRight` at `width` 40, the shape the editor gives a new infobox; on a replace or an update an omitted field keeps the value the block already has."},"MeterBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["meter"]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind","mode","items"],"additionalProperties":false,"description":"Tracked values drawn in `mode`. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Meter\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"ResourceCollectionBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceCollection"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind"],"additionalProperties":false,"description":"Resources picked by `items` or selected by `filter`. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Collection\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"ResourceLinkBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceLink"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind","items"],"additionalProperties":false,"description":"Links to resources. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Links\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"MapBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["map"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."}},"required":["kind"],"additionalProperties":false,"description":"An interactive map. `resourceId` and `documentId` name a `map` document of this project that the caller can read. A resource or document that does not exist, is deleted, is hidden from the caller, belongs to another project or is not a `map` document answers 400 VALIDATION_ERROR naming the field, unless the same document or resource already holds that map. Name both ids or neither; a map with neither is an empty block that the app shows as \"Link a map\". `viewport` is the view the map opens at; omit it to center at zoom 4, or at the map's deepest zoom when that is lower, on a pin of the map whose link points to the resource holding the map. `displayHeight` is the height in pixels, 150 to 800; the app draws 200 when it is omitted. `fill: true` draws the map edge to edge and hides the title whatever `isTitleHidden` says. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Map\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"SecretBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["secret"]},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false,"description":"Content hidden from players and stripped from public pages. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"TextFieldBlock":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["textField"]},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"layout":{"$ref":"#/components/schemas/BlockLayout"},"width":{"type":"integer","minimum":10,"maximum":100,"description":"Block width as a percentage of the column it sits in, 10 to 100. It applies when `layout` is not `default`."},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}}},"required":["kind","children"],"additionalProperties":false,"description":"A rich-text container. Carries `title`, the label above the block, and `isTitleHidden`, which hides that label and the frame around the block. A new one written without them reads `title: \"Text\"` and `isTitleHidden: false`; on a replace or an update an omitted `title` keeps the value the block already has. A block the app stored without `isTitleHidden` reads `isTitleHidden: true`, as the app draws it. Carries `layout` and `width`. A new one written without them is full width; on a replace or an update an omitted field keeps the value the block already has."},"UnsupportedBlock":{"type":"object","properties":{"kind":{"type":"string","enum":["unsupported"]},"id":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","id"],"additionalProperties":false},"Block":{"oneOf":[{"$ref":"#/components/schemas/ParagraphBlock"},{"$ref":"#/components/schemas/HeadingBlock"},{"$ref":"#/components/schemas/QuoteBlock"},{"$ref":"#/components/schemas/CodeBlock"},{"$ref":"#/components/schemas/RuleBlock"},{"$ref":"#/components/schemas/BulletListBlock"},{"$ref":"#/components/schemas/OrderedListBlock"},{"$ref":"#/components/schemas/ListItemBlock"},{"$ref":"#/components/schemas/TaskListBlock"},{"$ref":"#/components/schemas/TaskItemBlock"},{"$ref":"#/components/schemas/TableBlock"},{"$ref":"#/components/schemas/TableRowBlock"},{"$ref":"#/components/schemas/TableCellBlock"},{"$ref":"#/components/schemas/CalloutBlock"},{"$ref":"#/components/schemas/ExpandBlock"},{"$ref":"#/components/schemas/LayoutBlock"},{"$ref":"#/components/schemas/LayoutColumnBlock"},{"$ref":"#/components/schemas/ImageBlock"},{"$ref":"#/components/schemas/EmbedBlock"},{"$ref":"#/components/schemas/KeyValueBlock"},{"$ref":"#/components/schemas/InfoboxBlock"},{"$ref":"#/components/schemas/MeterBlock"},{"$ref":"#/components/schemas/ResourceCollectionBlock"},{"$ref":"#/components/schemas/ResourceLinkBlock"},{"$ref":"#/components/schemas/MapBlock"},{"$ref":"#/components/schemas/SecretBlock"},{"$ref":"#/components/schemas/TextFieldBlock"},{"$ref":"#/components/schemas/UnsupportedBlock"}],"discriminator":{"propertyName":"kind","mapping":{"paragraph":"#/components/schemas/ParagraphBlock","heading":"#/components/schemas/HeadingBlock","quote":"#/components/schemas/QuoteBlock","code":"#/components/schemas/CodeBlock","rule":"#/components/schemas/RuleBlock","bulletList":"#/components/schemas/BulletListBlock","orderedList":"#/components/schemas/OrderedListBlock","listItem":"#/components/schemas/ListItemBlock","taskList":"#/components/schemas/TaskListBlock","taskItem":"#/components/schemas/TaskItemBlock","table":"#/components/schemas/TableBlock","tableRow":"#/components/schemas/TableRowBlock","tableCell":"#/components/schemas/TableCellBlock","callout":"#/components/schemas/CalloutBlock","expand":"#/components/schemas/ExpandBlock","layout":"#/components/schemas/LayoutBlock","layoutColumn":"#/components/schemas/LayoutColumnBlock","image":"#/components/schemas/ImageBlock","embed":"#/components/schemas/EmbedBlock","keyValue":"#/components/schemas/KeyValueBlock","infobox":"#/components/schemas/InfoboxBlock","meter":"#/components/schemas/MeterBlock","resourceCollection":"#/components/schemas/ResourceCollectionBlock","resourceLink":"#/components/schemas/ResourceLinkBlock","map":"#/components/schemas/MapBlock","secret":"#/components/schemas/SecretBlock","textField":"#/components/schemas/TextFieldBlock","unsupported":"#/components/schemas/UnsupportedBlock"}},"description":"A content block. Container kinds carry `children`; text kinds carry `content` runs. A container written with no children reads back holding one empty paragraph. `unsupported` blocks are read-only placeholders for content the public model cannot express; echo them by id to preserve them. Nesting through `children`, `rows` and filter `filters` is limited to 64 levels; deeper input answers 400 VALIDATION_ERROR.","x-max-depth":64},"BlockInsertRequest":{"type":"object","properties":{"block":{"$ref":"#/components/schemas/Block"},"after":{"type":"string","maxLength":256,"description":"Insert after this block id."},"before":{"type":"string","maxLength":256,"description":"Insert before this block id."},"parent":{"type":"string","maxLength":256,"description":"Append as the last child of this container block."}},"required":["block"],"additionalProperties":false,"description":"At most one of after, before, parent; none appends at the end of the document. An id in `block` or its subtree is kept. An id that another block of the document already uses answers 409 DUPLICATE_ID with its path (`block.id`, `block.children[0].id`), and nothing is written. The same id twice in the body answers 400 VALIDATION_ERROR."},"BlockPatch":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000},"level":{"type":"integer","minimum":1,"maximum":6},"text":{"type":"string","maxLength":100000},"language":{"type":"string","maxLength":256},"checked":{"type":"boolean"},"title":{"anyOf":[{"type":"string","maxLength":2048},{"type":"string","maxLength":256}]},"isTitleHidden":{"type":"boolean"},"fill":{"anyOf":[{"type":"boolean"},{"type":"boolean"}]},"tone":{"type":"string","enum":["info","note","success","warning","error","custom"]},"icon":{"type":"string","maxLength":256},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Icon color and background tint, as `#RRGGBB`. Accepted only when `tone` is `custom`; the other tones draw their own color."},"header":{"type":"boolean"},"colspan":{"type":"integer","minimum":1},"rowspan":{"type":"integer","minimum":1},"start":{"type":"integer","minimum":0},"width":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"integer","minimum":10,"maximum":100}]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"layout":{"$ref":"#/components/schemas/BlockLayout"},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},{"type":"array","maxItems":256,"items":{"$ref":"#/components/schemas/PropertyBlock"}}]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256}]},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800}},"additionalProperties":false,"description":"Shallow update of a block's own fields (content, level, text, language, checked, title, isTitleHidden, fill, tone, icon, color, header, colspan, rowspan, start, width, url, alt, provider, layout, display, rows, mode, items, showText, showIcon, showMax, view, filter, resourceId, documentId, viewport, displayHeight). `kind`, `id` and `children` cannot be patched and answer 400 VALIDATION_ERROR."},"BlockMoveRequest":{"type":"object","properties":{"after":{"type":"string","maxLength":256,"description":"Insert after this block id."},"before":{"type":"string","maxLength":256,"description":"Insert before this block id."},"parent":{"type":"string","maxLength":256,"description":"Append as the last child of this container block."}},"additionalProperties":false,"description":"Exactly one of after, before, parent."},"Row":{"type":"object","properties":{"id":{"type":["string","null"]},"rank":{"type":"string"},"key":{"type":"string"},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000},"text":{"type":"string"}},"required":["id","rank","key","content","text"]},"RowList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Row"}},"version":{"type":"string"}},"required":["data","version"]},"RowCreateRequest":{"type":"object","properties":{"key":{"type":"string","maxLength":256},"content":{"type":"array","items":{"$ref":"#/components/schemas/Run"},"maxItems":10000,"description":"The row value as runs. A `{ break: true }` run starts a new line; a stored line break and a paragraph boundary both read back as `break`. When both `content` and `text` are sent, `content` wins and `text` is ignored, so a row read from the API can be echoed back."},"text":{"type":"string","maxLength":100000,"description":"The row value as a plain string. Ignored when `content` is sent."},"before":{"type":"string","maxLength":256,"description":"Place before this row id. At most one of `before` and `after`; neither appends last."},"after":{"type":"string","maxLength":256,"description":"Place after this row id. At most one of `before` and `after`; neither appends last."}},"required":["key"],"additionalProperties":false},"RowPatchRequest":{"type":"object","properties":{"key":{"type":"string","maxLength":256},"content":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Run"},"maxItems":10000,"description":"The row value as runs. `null` clears the value. When both `content` and `text` are sent, `content` wins."},"text":{"type":"string","maxLength":100000,"description":"The row value as a plain string. It cannot be null."}},"additionalProperties":false},"BlockPropertyList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PropertyBlock"}},"version":{"type":"string"}},"required":["data","version"]},"VersionedTextFieldProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["textField"]},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"children":{"type":"array","maxItems":10000,"items":{"$ref":"#/components/schemas/Block"}},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","children","version"],"additionalProperties":false},"VersionedKeyValueProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["keyValue"]},"display":{"type":"string","enum":["list","grid","inline"]},"rows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"key":{"type":"string","maxLength":2048},"content":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"code":{"type":"boolean"},"link":{"type":"string","maxLength":2048},"sub":{"type":"boolean"},"sup":{"type":"boolean"}},"required":["text"],"additionalProperties":false},{"type":"object","properties":{"mention":{"type":"object","properties":{"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"text":{"type":"string","maxLength":2048},"name":{"type":"string","maxLength":2048}},"required":["resourceId"],"additionalProperties":false}},"required":["mention"],"additionalProperties":false},{"type":"object","properties":{"break":{"type":"boolean","enum":[true]}},"required":["break"],"additionalProperties":false}]},"maxItems":10000},"text":{"type":"string","maxLength":100000}},"required":["key"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","rows","version"],"additionalProperties":false},"VersionedImageProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["image"]},"url":{"type":"string","maxLength":2048},"alt":{"type":"string","maxLength":500},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","url","version"],"additionalProperties":false},"VersionedMeterProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["meter"]},"mode":{"type":"string","enum":["bar","wheel","gauge-180","gauge-270","pool","rating"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"name":{"type":"string","maxLength":2048},"icon":{"type":"string","maxLength":256},"ratingIcon":{"type":"string","maxLength":256},"current":{"type":"number","minimum":0},"max":{"type":"number","minimum":1},"color":{"anyOf":[{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$"},{"type":"string","enum":["none"]}],"description":"Fill color of the meter as `#RRGGBB`, or `none` to use the block tint. With `none` and no block tint the meter is drawn `#3B82F6`. Absent, `none`."}},"required":["name","icon","current","max"],"additionalProperties":false},"maxItems":256},"showText":{"type":"boolean"},"showIcon":{"type":"boolean"},"showMax":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","mode","items","version"],"additionalProperties":false},"VersionedResourceCollectionProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceCollection"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"filter":{"$ref":"#/components/schemas/FilterPredicate"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","version"],"additionalProperties":false},"VersionedResourceLinkProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["resourceLink"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256}},"required":["resourceId"],"additionalProperties":false},"maxItems":256},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","items","version"],"additionalProperties":false},"VersionedEmbedProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["embed"]},"provider":{"type":"string","enum":["youtube","spotify","soundcloud"]},"url":{"type":"string","maxLength":2048},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","provider","url","version"],"additionalProperties":false},"VersionedMapProperty":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":256},"kind":{"type":"string","enum":["map"]},"resourceId":{"type":"string","minLength":1,"maxLength":256},"documentId":{"type":"string","minLength":1,"maxLength":256},"viewport":{"$ref":"#/components/schemas/MapViewport"},"displayHeight":{"type":"number","minimum":150,"maximum":800},"fill":{"type":"boolean"},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"rank":{"type":"string","minLength":1,"maxLength":65536},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","version"],"additionalProperties":false},"VersionedUnsupportedProperty":{"type":"object","properties":{"kind":{"type":"string","enum":["unsupported"]},"id":{"type":"string","minLength":1,"maxLength":256},"rank":{"type":"string","minLength":1,"maxLength":65536},"title":{"type":"string","maxLength":256},"isTitleHidden":{"type":"boolean"},"isHidden":{"type":"boolean"},"version":{"type":"string"}},"required":["kind","id","version"],"additionalProperties":false},"VersionedProperty":{"oneOf":[{"$ref":"#/components/schemas/VersionedTextFieldProperty"},{"$ref":"#/components/schemas/VersionedKeyValueProperty"},{"$ref":"#/components/schemas/VersionedImageProperty"},{"$ref":"#/components/schemas/VersionedMeterProperty"},{"$ref":"#/components/schemas/VersionedResourceCollectionProperty"},{"$ref":"#/components/schemas/VersionedResourceLinkProperty"},{"$ref":"#/components/schemas/VersionedEmbedProperty"},{"$ref":"#/components/schemas/VersionedMapProperty"},{"$ref":"#/components/schemas/VersionedUnsupportedProperty"}],"discriminator":{"propertyName":"kind","mapping":{"textField":"#/components/schemas/VersionedTextFieldProperty","keyValue":"#/components/schemas/VersionedKeyValueProperty","image":"#/components/schemas/VersionedImageProperty","meter":"#/components/schemas/VersionedMeterProperty","resourceCollection":"#/components/schemas/VersionedResourceCollectionProperty","resourceLink":"#/components/schemas/VersionedResourceLinkProperty","embed":"#/components/schemas/VersionedEmbedProperty","map":"#/components/schemas/VersionedMapProperty","unsupported":"#/components/schemas/VersionedUnsupportedProperty"}},"description":"A PropertyBlock plus the document `version` it was read or written at."},"Lane":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"rank":{"type":"string","description":"Fractional index for ordering (e.g. \"a0\", \"a1\")"},"size":{"type":"string","enum":["sm","lg"]},"style":{"type":"object","properties":{"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of every event in the lane, as `#RRGGBB`. When set, it replaces each event's `color` and hides the lane and event images. Absent, each event uses its own color."},"imageUrl":{"type":"string","maxLength":2048,"description":"Lane background image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"opacity":{"type":"number"}},"additionalProperties":false,"description":"Lane visual style options"}},"required":["id","name","rank","size"]},"LaneList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lane"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"LaneCreateParams":{"type":"object","properties":{"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers."},"name":{"type":"string","maxLength":500,"description":"Lane display name"},"rank":{"type":"string","maxLength":65536,"description":"Fractional index for ordering (e.g. \"a0\", \"a1\")"},"size":{"type":"string","enum":["sm","lg"],"description":"Lane height"},"style":{"type":"object","properties":{"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of every event in the lane, as `#RRGGBB`. When set, it replaces each event's `color` and hides the lane and event images. Absent, each event uses its own color."},"imageUrl":{"type":"string","maxLength":2048,"description":"Lane background image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"opacity":{"type":"number"}},"additionalProperties":false,"description":"Lane visual style options"}},"required":["name","rank","size"],"additionalProperties":false},"LaneUpdateParams":{"type":"object","properties":{"name":{"type":"string","maxLength":500},"rank":{"type":"string","maxLength":65536},"size":{"type":"string","enum":["sm","lg"]},"style":{"type":"object","properties":{"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of every event in the lane, as `#RRGGBB`. When set, it replaces each event's `color` and hides the lane and event images. Absent, each event uses its own color."},"imageUrl":{"type":"string","maxLength":2048,"description":"Lane background image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"opacity":{"type":"number"}},"additionalProperties":false,"description":"Lane visual style options"}},"additionalProperties":false},"EventDateEra":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"abbr":{"type":"string"}},"required":["id","name","abbr"],"description":"The era a date falls in, as defined by the calendar."},"EventDate":{"type":"object","properties":{"year":{"type":"integer","description":"The year counted within `era`, as the app displays it; always 0 or more. A date before the first positive era is counted backwards in the negative era (44 with era BCE is 44 BCE)."},"month":{"type":"integer","description":"The month number within the year, 1 for the first month of the calendar."},"monthName":{"type":"string"},"day":{"type":"integer","description":"The day of the month, 1 for the first day."},"hour":{"type":"integer"},"minute":{"type":"integer"},"era":{"$ref":"#/components/schemas/EventDateEra"},"iso":{"type":"string","description":"Present only when the document uses the Gregorian calendar (`gregorian`). An ISO 8601 calendar date cut to `detail`: `YYYY`, `YYYY-MM`, `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm`, with no time zone. Years before 1 CE use astronomical numbering, so 1 BCE is `0000` and 44 BCE is `-0043`."}},"required":["year","month","monthName","day","hour","minute","era"],"description":"The start date resolved in the document's calendar."},"Event":{"type":"object","properties":{"id":{"type":"string"},"laneId":{"type":"string"},"rank":{"type":"string","description":"Fractional index for ordering within a lane"},"type":{"type":"string","enum":["event","note","placeholder","invisible-placeholder"]},"start":{"type":"number","description":"Start date in minutes"},"end":{"type":"number"},"formattedStart":{"type":"string","description":"The start date as the app displays it in the document's calendar, at `detail`."},"formattedEnd":{"type":"string","description":"The end date as the app displays it, when the event has an end."},"startDate":{"$ref":"#/components/schemas/EventDate"},"endDate":{"allOf":[{"$ref":"#/components/schemas/EventDate"},{"description":"The end date resolved in the document's calendar, when the event has an end."}]},"detail":{"type":"number","description":"The precision of the dates: 1=year 2=month 3=day 4=time. Absent means day."},"name":{"type":"string"},"uri":{"type":"string","description":"Link to a resource or document in this project: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`."},"iconGlyph":{"type":"string"},"color":{"type":"string","description":"Fill color of the event on the timeline and the calendar, usually `#RRGGBB`. Ignored while the event's lane sets `style.color`. Absent, `#0079CC`."},"imageUrl":{"type":"string"},"isHidden":{"type":"boolean"},"showOnCalendar":{"type":"boolean"}},"required":["id","laneId","type","start","startDate"]},"EventList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"EventCreateParams":{"type":"object","properties":{"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers."},"laneId":{"type":"string","maxLength":256,"description":"ID of the lane this event belongs to"},"type":{"type":"string","enum":["event","note"],"description":"\"event\" (point/range) or \"note\" (annotation)"},"name":{"type":"string","maxLength":500},"start":{"type":"number","description":"Start in minutes. Required unless formattedStart is set."},"end":{"type":"number"},"formattedStart":{"type":"string","maxLength":256,"description":"Human date, fuzzy-parsed with the document calendar and converted to `start` and `detail`."},"formattedEnd":{"type":"string","maxLength":256,"description":"Human date, fuzzy-parsed with the document calendar and converted to `end`."},"detail":{"type":"number","description":"1=year 2=month 3=day 4=time"},"uri":{"type":"string","maxLength":2048,"description":"Link to a resource or document in this project. Accepted forms: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`; no other scheme is accepted. The target must be in the same project, must not be deleted, and must be readable by the caller: a target that answers 404 to the caller on GET cannot be linked. A legacy `docs` link names a document of that resource. Any other value answers 400 VALIDATION_ERROR at `uri`. A target created in the app can take a few seconds to become linkable while the server indexes it. An empty string clears the link."},"iconGlyph":{"type":"string","maxLength":128},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of the event on the timeline and the calendar, as `#RRGGBB`. Ignored while the event's lane sets `style.color`. Absent, `#0079CC`."},"imageUrl":{"type":"string","maxLength":2048,"description":"Event image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"isHidden":{"type":"boolean"},"showOnCalendar":{"type":"boolean"}},"required":["laneId","type"],"additionalProperties":false},"EventUpdateParams":{"type":"object","properties":{"laneId":{"type":"string","maxLength":256,"description":"Move event to a different lane"},"name":{"type":"string","maxLength":500},"start":{"type":"number"},"end":{"type":"number"},"formattedStart":{"type":"string","maxLength":256,"description":"Human date, fuzzy-parsed with the document calendar and converted to `start` and `detail`."},"formattedEnd":{"type":"string","maxLength":256,"description":"Human date, fuzzy-parsed with the document calendar and converted to `end`."},"detail":{"type":"number"},"uri":{"type":"string","maxLength":2048,"description":"Link to a resource or document in this project. Accepted forms: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`; no other scheme is accepted. The target must be in the same project, must not be deleted, and must be readable by the caller: a target that answers 404 to the caller on GET cannot be linked. A legacy `docs` link names a document of that resource. Any other value answers 400 VALIDATION_ERROR at `uri`. A target created in the app can take a few seconds to become linkable while the server indexes it. An empty string clears the link. Omitting `uri` leaves the stored link unchanged."},"iconGlyph":{"type":"string","maxLength":128},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Fill color of the event on the timeline and the calendar, as `#RRGGBB`. Ignored while the event's lane sets `style.color`. Absent, `#0079CC`."},"imageUrl":{"type":"string","maxLength":2048,"description":"Event image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"isHidden":{"type":"boolean"},"showOnCalendar":{"type":"boolean"}},"additionalProperties":false},"FeatureImage":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"description":"Image URL. The URL is the `url` of an image asset of this project (upload with createImageUpload and createImageAsset). Any other URL, including an image asset of another project, answers 400 VALIDATION_ERROR naming the field, unless the same document, resource or board already holds that URL in an image field. A `data:` or `blob:` URI answers 400 VALIDATION_ERROR naming the field: documents hold no inline image data. Upload the image (createImageUpload, createImageAsset) and reference its URL."},"height":{"type":"number"},"width":{"type":"number"}},"required":["url","height","width"]},"Feature":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["pin","label","region","path","folder"]},"pos":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"description":"[lat, lng] coordinate","minItems":2,"maxItems":2},"uri":{"type":"string","description":"Link to a resource or document in this project: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`."},"parentId":{"type":"string"},"rank":{"type":"string","description":"Fractional index ordering the feature among its siblings under `parentId`."},"iconGlyph":{"type":"string"},"iconColor":{"type":"string","description":"For a `pin`: fill color of the pin shape, usually `#RRGGBB`. Absent, the pin is drawn `#A7A7A7`."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin, or `none` for the glyph alone."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape. Absent when `iconShape` is `none`."},"pinImage":{"$ref":"#/components/schemas/FeatureImage"},"isHidden":{"type":"boolean"},"polygon":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2}},"polygons":{"type":"array","items":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2}}},"polyline":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2}},"color":{"type":"string","description":"For a `region`: fill and border color. For a `path`: line color. Usually `#RRGGBB`. Absent, the app draws `#3B82F6`."},"fillOpacity":{"type":"number"},"fillStyle":{"type":"string","enum":["solid","striped","dotted","none"]},"borderStyle":{"type":"string","enum":["solid","dashed","dotted","none"]},"strokeWidth":{"type":"number"},"strokeStyle":{"type":"string","enum":["solid","dashed","dotted","none"]},"strokeOpacity":{"type":"number"},"labelVisibility":{"type":"string","enum":["always","hover","never"]},"labelSize":{"type":"string","description":"Size of the name text. Written as `xs` to `3xl`; features drawn in the app may hold `small`, `medium` or `large`."},"textColor":{"type":"string","description":"Color of the name text of a `label`, `region` or `path`, usually `#RRGGBB`. Absent, `#FFFFFF`."},"textEffect":{"type":"string","enum":["outline","background"],"description":"How `textEffectColor` is drawn behind the name text of a `label`, `region` or `path`: `outline` draws a 3-pixel outline around the letters, `background` draws a box behind the text at 50% opacity. Not accepted on other types. Absent, `outline`."},"textEffectColor":{"type":"string","description":"Color of the outline or background box set by `textEffect`, usually `#RRGGBB`. Absent, `#000000`."},"updatedAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."}},"required":["id"],"description":"A feature of a map document. A pin carries its icon in `iconGlyph`, `iconColor`, `iconShape` and `iconSize`. `iconSize` is absent when `iconShape` is `none`, and both are absent when no shape is stored; the app then draws a medium `pin`. A shape stored by the app in an older format reads as the app draws it: a glyph-only shape reads as `none`, and any other shape outside these values reads as `pin` and `medium`."},"FeatureList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Feature"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"FeatureCreateParams":{"type":"object","properties":{"id":{"type":"string","maxLength":24,"pattern":"^[a-z](?:[0-9a-z]{7}|[0-9a-z]{23})$","description":"Optional client-chosen id: a lowercase letter followed by 7 or 23 lowercase letters or digits (a cuid2 id of 8 or 24 characters). See Identifiers."},"name":{"type":"string","maxLength":500},"type":{"type":"string","enum":["pin","label","region","path","folder"],"description":"Feature type"},"pos":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"description":"Position as [lat, lng] coordinate. Optional for folders.","minItems":2,"maxItems":2},"uri":{"type":"string","maxLength":2048,"description":"Link to a resource or document in this project. Accepted forms: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`; no other scheme is accepted. The target must be in the same project, must not be deleted, and must be readable by the caller: a target that answers 404 to the caller on GET cannot be linked. A legacy `docs` link names a document of that resource. Any other value answers 400 VALIDATION_ERROR at `uri`. A target created in the app can take a few seconds to become linkable while the server indexes it. An empty string clears the link."},"parentId":{"type":"string","maxLength":256,"description":"Parent feature ID for hierarchy (null = root). Nests the feature under a folder."},"rank":{"type":"string","maxLength":65536,"description":"Fractional index for ordering within the parent (e.g. \"a0\")"},"iconGlyph":{"type":"string","maxLength":128,"description":"For a `pin`: a FontAwesome icon name."},"pinImage":{"$ref":"#/components/schemas/FeatureImage"},"isHidden":{"type":"boolean"},"polygon":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000,"description":"Polygon vertices (for regions)"},"polygons":{"type":"array","items":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000},"maxItems":100,"description":"Several polygons of vertices (for regions)"},"fillOpacity":{"type":"number","description":"Fill opacity (for regions)"},"labelVisibility":{"type":"string","enum":["always","hover","never"]},"borderStyle":{"type":"string","enum":["solid","dashed","dotted","none"],"description":"Border line style (for regions)"},"fillStyle":{"type":"string","enum":["solid","striped","dotted","none"],"description":"Fill style (for regions)"},"polyline":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000,"description":"Polyline vertices (for paths)"},"strokeWidth":{"type":"number","description":"Line width (for paths)"},"strokeStyle":{"type":"string","enum":["solid","dashed","dotted","none"],"description":"Line style (for paths)"},"strokeOpacity":{"type":"number","description":"Line opacity (for paths)"},"labelSize":{"type":"string","enum":["xs","sm","md","lg","xl","2xl","3xl"]},"visibilityRange":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"description":"Zoom range [min, max] as 0-1","minItems":2,"maxItems":2},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin: `pin`, `diamond`, `flag`, `marker`, `shield`, `circle`, `banner` or `arch`, or `none` for the glyph alone. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconSize`, the stored `iconSize` is kept, or `medium` when none is stored."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape: `medium` or `small`. Ignored when `iconShape` is `none`. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconShape`, the stored `iconShape` is kept, or `pin` when none is stored."},"iconColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"For a `pin`: fill color of the pin shape, as `#RRGGBB`; the glyph is drawn black or white for contrast. No effect when `iconShape` is `none` or the pin has a `pinImage`. A pin with `isSynced` and a `uri` draws the linked resource's `iconColor` instead. Not accepted on other types. Absent, the pin is drawn `#A7A7A7`."},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"For a `region`: fill and border color. For a `path`: line color. `#RRGGBB`. Not accepted on other types. Absent, the app draws `#3B82F6`."},"textColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Color of the feature's name text: the text of a `label`, or the name label drawn on a `region` or `path`. `#RRGGBB`. Not accepted on other types. Absent, the text is drawn `#FFFFFF`."},"textEffect":{"type":"string","enum":["outline","background"],"description":"How `textEffectColor` is drawn behind the name text of a `label`, `region` or `path`: `outline` draws a 3-pixel outline around the letters, `background` draws a box behind the text at 50% opacity. Not accepted on other types. Absent, `outline`."},"textEffectColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Color of the outline or background box set by `textEffect`, as `#RRGGBB`. Not accepted on other types. Absent, `#000000`."}},"additionalProperties":false,"description":"A color field sent on a feature type it does not apply to answers 400 VALIDATION_ERROR."},"FeatureUpdateParams":{"type":"object","properties":{"name":{"type":"string","maxLength":500},"type":{"type":"string","enum":["pin","label","region","path","folder"],"description":"Feature type"},"pos":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"description":"Position as [lat, lng] coordinate. Optional for folders.","minItems":2,"maxItems":2},"uri":{"type":"string","maxLength":2048,"description":"Link to a resource or document in this project. Accepted forms: `lk://resources/<resourceId>`, `lk://documents/<documentId>` or `lk://resources/<resourceId>/docs/<documentId>`; no other scheme is accepted. The target must be in the same project, must not be deleted, and must be readable by the caller: a target that answers 404 to the caller on GET cannot be linked. A legacy `docs` link names a document of that resource. Any other value answers 400 VALIDATION_ERROR at `uri`. A target created in the app can take a few seconds to become linkable while the server indexes it. An empty string clears the link. Omitting `uri` leaves the stored link unchanged."},"parentId":{"type":"string","maxLength":256,"description":"Parent feature ID for hierarchy (null = root). Nests the feature under a folder."},"rank":{"type":"string","maxLength":65536,"description":"Fractional index for ordering within the parent (e.g. \"a0\")"},"iconGlyph":{"type":"string","maxLength":128,"description":"For a `pin`: a FontAwesome icon name."},"pinImage":{"$ref":"#/components/schemas/FeatureImage"},"isHidden":{"type":"boolean"},"polygon":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000,"description":"Polygon vertices (for regions)"},"polygons":{"type":"array","items":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000},"maxItems":100,"description":"Several polygons of vertices (for regions)"},"fillOpacity":{"type":"number","description":"Fill opacity (for regions)"},"labelVisibility":{"type":"string","enum":["always","hover","never"]},"borderStyle":{"type":"string","enum":["solid","dashed","dotted","none"],"description":"Border line style (for regions)"},"fillStyle":{"type":"string","enum":["solid","striped","dotted","none"],"description":"Fill style (for regions)"},"polyline":{"type":"array","items":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"minItems":2,"maxItems":2},"maxItems":10000,"description":"Polyline vertices (for paths)"},"strokeWidth":{"type":"number","description":"Line width (for paths)"},"strokeStyle":{"type":"string","enum":["solid","dashed","dotted","none"],"description":"Line style (for paths)"},"strokeOpacity":{"type":"number","description":"Line opacity (for paths)"},"labelSize":{"type":"string","enum":["xs","sm","md","lg","xl","2xl","3xl"]},"visibilityRange":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"}],"description":"Zoom range [min, max] as 0-1","minItems":2,"maxItems":2},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin: `pin`, `diamond`, `flag`, `marker`, `shield`, `circle`, `banner` or `arch`, or `none` for the glyph alone. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconSize`, the stored `iconSize` is kept, or `medium` when none is stored."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape: `medium` or `small`. Ignored when `iconShape` is `none`. Any other value answers 400 VALIDATION_ERROR at the field. Sent without `iconShape`, the stored `iconShape` is kept, or `pin` when none is stored."},"iconColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"For a `pin`: fill color of the pin shape, as `#RRGGBB`; the glyph is drawn black or white for contrast. No effect when `iconShape` is `none` or the pin has a `pinImage`. A pin with `isSynced` and a `uri` draws the linked resource's `iconColor` instead. Not accepted on other types. Absent, the pin is drawn `#A7A7A7`."},"color":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"For a `region`: fill and border color. For a `path`: line color. `#RRGGBB`. Not accepted on other types. Absent, the app draws `#3B82F6`."},"textColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Color of the feature's name text: the text of a `label`, or the name label drawn on a `region` or `path`. `#RRGGBB`. Not accepted on other types. Absent, the text is drawn `#FFFFFF`."},"textEffect":{"type":"string","enum":["outline","background"],"description":"How `textEffectColor` is drawn behind the name text of a `label`, `region` or `path`: `outline` draws a 3-pixel outline around the letters, `background` draws a box behind the text at 50% opacity. Not accepted on other types. Absent, `outline`."},"textEffectColor":{"type":"string","maxLength":7,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Color of the outline or background box set by `textEffect`, as `#RRGGBB`. Not accepted on other types. Absent, `#000000`."}},"additionalProperties":false,"description":"A color field sent on a feature type it does not apply to answers 400 VALIDATION_ERROR."},"BoardSchemaVersion":{"type":"object","properties":{"schemaVersion":{"type":"number"},"sequences":{"type":"object","additionalProperties":{"type":"number"}}},"required":["schemaVersion","sequences"],"description":"The serialized tldraw schema (`SerializedSchema`) that writes are validated against."},"BoardPage":{"type":"object","properties":{"id":{"type":"string","description":"A tldraw page id, `page:…`."},"typeName":{"type":"string","enum":["page"]},"name":{"type":"string"},"index":{"type":"string","description":"Fractional index ordering the pages."},"meta":{"type":"object","additionalProperties":{}}},"required":["id","typeName","name","index","meta"],"description":"A tldraw page record. The app shows one page per board."},"BoardShape":{"type":"object","properties":{"id":{"type":"string","description":"A tldraw shape id, `shape:…`."},"typeName":{"type":"string","enum":["shape"]},"type":{"type":"string","description":"The shape type: `arrow`, `bookmark`, `content-block`, `draw`, `element`, `embed`, `frame`, `geo`, `group`, `highlight`, `image`, `line`, `note`, `text`, `video`."},"x":{"type":"number"},"y":{"type":"number"},"rotation":{"type":"number","description":"Radians."},"index":{"type":"string","description":"Fractional index ordering the shape among the children of its parent; a higher index draws above."},"parentId":{"type":"string","description":"The page (`page:…`) or the frame or group shape (`shape:…`) that contains the shape."},"isLocked":{"type":"boolean"},"opacity":{"type":"number"},"props":{"type":"object","additionalProperties":{},"description":"The props of the shape type, exactly as tldraw 3.9 defines them (`TLGeoShapeProps`, `TLTextShapeProps` and so on)."},"meta":{"type":"object","additionalProperties":{}}},"required":["id","typeName","type","x","y","rotation","index","parentId","isLocked","opacity","props","meta"],"description":"A tldraw shape record, typed by tldraw's `TLShape`."},"BoardBinding":{"type":"object","properties":{"id":{"type":"string","description":"A tldraw binding id, `binding:…`."},"typeName":{"type":"string","enum":["binding"]},"type":{"type":"string","description":"The binding type: `arrow`."},"fromId":{"type":"string","description":"The arrow shape the binding starts at."},"toId":{"type":"string","description":"The shape the arrow end is attached to."},"props":{"type":"object","additionalProperties":{},"description":"`TLArrowBindingProps`: `terminal` (`start` or `end`), `normalizedAnchor`, `isExact`, `isPrecise`."},"meta":{"type":"object","additionalProperties":{}}},"required":["id","typeName","type","fromId","toId","props","meta"],"description":"A tldraw binding record, typed by tldraw's `TLBinding`. An arrow end attached to a shape is a binding from the arrow to that shape."},"BoardAsset":{"type":"object","properties":{"id":{"type":"string","description":"A tldraw asset id, `asset:…`."},"typeName":{"type":"string","enum":["asset"]},"type":{"type":"string","enum":["image","video","bookmark"]},"props":{"type":"object","additionalProperties":{},"description":"The props of the asset type (`TLImageAsset`, `TLVideoAsset`, `TLBookmarkAsset`). An image `src` is the `url` of an image asset of this project; a video `src` is a LegendKeeper asset URL."},"meta":{"type":"object","additionalProperties":{}}},"required":["id","typeName","type","props","meta"],"description":"A tldraw asset record, typed by tldraw's `TLAsset`. Image and video shapes reference one by `props.assetId`."},"BoardContent":{"type":"object","properties":{"schema":{"$ref":"#/components/schemas/BoardSchemaVersion"},"pages":{"type":"array","items":{"$ref":"#/components/schemas/BoardPage"}},"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShape"}},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/BoardBinding"}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/BoardAsset"}},"version":{"type":"string","description":"The board `version`, also sent as `ETag`. Send it back as `If-Match` to fail with 412 instead of overwriting a change made since."}},"required":["schema","pages","shapes","bindings","assets","version"],"description":"Every page, shape, binding and asset record of a board. Records are returned as stored."},"BoardShapeInput":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Optional `shape:…` id; one is minted when omitted."},"typeName":{"type":"string","enum":["shape"]},"type":{"type":"string","maxLength":256,"description":"The shape type: `arrow`, `bookmark`, `content-block`, `draw`, `element`, `embed`, `frame`, `geo`, `group`, `highlight`, `image`, `line`, `note`, `text`, `video`."},"x":{"type":"number"},"y":{"type":"number"},"rotation":{"type":"number"},"index":{"type":"string","maxLength":65536,"description":"Fractional index among the children of the parent. Omitted, the shape is placed above its siblings."},"parentId":{"type":"string","maxLength":256,"description":"A page or a shape on this board. Defaults to the first page."},"isLocked":{"type":"boolean"},"opacity":{"type":"number"},"props":{"type":"object","description":"Props of the shape type. Missing props take the app's defaults for the type; tldraw validates the result.","maxProperties":256,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/BoardJsonValue"}},"meta":{"type":"object","description":"Free-form meta of the record.","maxProperties":64,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}},"required":["type"],"additionalProperties":false,"description":"A shape to create. `x`, `y` and `rotation` default to 0, `isLocked` to false, `opacity` to 1 and `meta` to `{}`."},"BoardBindingInput":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Optional `binding:…` id; one is minted when omitted."},"typeName":{"type":"string","enum":["binding"]},"type":{"type":"string","maxLength":256},"fromId":{"type":"string","maxLength":256},"toId":{"type":"string","maxLength":256},"props":{"type":"object","description":"For an `arrow` binding, `terminal` (`start` or `end`) is required; `normalizedAnchor` defaults to the centre of the target, `isExact` and `isPrecise` to false.","maxProperties":256,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/BoardJsonValue"}},"meta":{"type":"object","description":"Free-form meta of the record.","maxProperties":64,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}},"required":["type","fromId","toId"],"additionalProperties":false,"description":"A binding to create. `fromId` names an arrow shape and `toId` the shape its terminal attaches to; either may be a shape created in the same request."},"BoardAssetInput":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Optional `asset:…` id; one is minted when omitted."},"typeName":{"type":"string","enum":["asset"]},"type":{"type":"string","enum":["image","video","bookmark"]},"props":{"type":"object","description":"Every prop of the asset type. An image `src` must be the `url` of an image asset of this project and a video `src` a LegendKeeper asset URL; a `data:` or `blob:` URI, or any other URL, answers 400 VALIDATION_ERROR unless the board already holds that `src`. A bookmark `src` is an http or https URL.","maxProperties":256,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/BoardJsonValue"}},"meta":{"type":"object","description":"Free-form meta of the record.","maxProperties":64,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}},"required":["type","props"],"additionalProperties":false},"BoardContentReplaceParams":{"type":"object","properties":{"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShapeInput"},"maxItems":500},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/BoardBindingInput"},"maxItems":500},"assets":{"type":"array","items":{"$ref":"#/components/schemas/BoardAssetInput"},"maxItems":500}},"required":["shapes"],"additionalProperties":false,"description":"Records are validated with tldraw's own validators for the schema in `BoardContent.schema`, the schema the app's board view uses. A failure answers 400 VALIDATION_ERROR with one `errors[]` entry per failing field, such as `shapes[2].props.w`. A `data:` or `blob:` URI in an image, video or bookmark asset or in a shape `url` answers 400 VALIDATION_ERROR naming the field: boards hold no inline image data."},"BoardShapeList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BoardShape"}},"version":{"type":"string"}},"required":["data","version"]},"BoardShapesCreated":{"type":"object","properties":{"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShape"}},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/BoardBinding"}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/BoardAsset"}},"version":{"type":"string","description":"The board `version`, also sent as `ETag`. Send it back as `If-Match` to fail with 412 instead of overwriting a change made since."}},"required":["shapes","bindings","assets","version"]},"BoardShapesCreateParams":{"type":"object","properties":{"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShapeInput"},"maxItems":500},"bindings":{"type":"array","items":{"$ref":"#/components/schemas/BoardBindingInput"},"maxItems":500},"assets":{"type":"array","items":{"$ref":"#/components/schemas/BoardAssetInput"},"maxItems":500}},"required":["shapes"],"additionalProperties":false,"description":"Records are validated with tldraw's own validators for the schema in `BoardContent.schema`, the schema the app's board view uses. A failure answers 400 VALIDATION_ERROR with one `errors[]` entry per failing field, such as `shapes[2].props.w`. A `data:` or `blob:` URI in an image, video or bookmark asset or in a shape `url` answers 400 VALIDATION_ERROR naming the field: boards hold no inline image data."},"BoardShapesUpdated":{"type":"object","properties":{"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShape"}},"version":{"type":"string","description":"The board `version`, also sent as `ETag`. Send it back as `If-Match` to fail with 412 instead of overwriting a change made since."}},"required":["shapes","version"]},"BoardShapePatch":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"The shape to update."},"type":{"type":"string","maxLength":256,"description":"Optional; when sent it must equal the shape's type."},"x":{"type":"number"},"y":{"type":"number"},"rotation":{"type":"number"},"index":{"type":"string","maxLength":65536},"parentId":{"type":"string","maxLength":256},"isLocked":{"type":"boolean"},"opacity":{"type":"number"},"props":{"type":"object","description":"Props to change; the others keep their values.","maxProperties":256,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/BoardJsonValue"}},"meta":{"type":"object","description":"Meta keys to change; the others keep their values.","maxProperties":64,"propertyNames":{"type":"string","maxLength":256},"additionalProperties":{"$ref":"#/components/schemas/JsonValue"}}},"required":["id"],"additionalProperties":false,"description":"A partial shape. Top-level fields sent replace the stored ones; `props` and `meta` merge one level deep, as tldraw's `updateShapes` does."},"BoardShapesUpdateParams":{"type":"object","properties":{"shapes":{"type":"array","items":{"$ref":"#/components/schemas/BoardShapePatch"},"minItems":1,"maxItems":500}},"required":["shapes"],"additionalProperties":false,"description":"Records are validated with tldraw's own validators for the schema in `BoardContent.schema`, the schema the app's board view uses. A failure answers 400 VALIDATION_ERROR with one `errors[]` entry per failing field, such as `shapes[2].props.w`. A `data:` or `blob:` URI in an image, video or bookmark asset or in a shape `url` answers 400 VALIDATION_ERROR naming the field: boards hold no inline image data."},"BoardShapesDeleted":{"type":"object","properties":{"shapeIds":{"type":"array","items":{"type":"string"},"description":"Every shape deleted: the named shapes and the shapes they contained."},"bindingIds":{"type":"array","items":{"type":"string"},"description":"Every binding deleted because one of its ends was deleted."},"version":{"type":"string","description":"The board `version`, also sent as `ETag`. Send it back as `If-Match` to fail with 412 instead of overwriting a change made since."}},"required":["shapeIds","bindingIds","version"]},"BoardShapesDeleteParams":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string","maxLength":256},"minItems":1,"maxItems":500,"description":"Shape ids to delete."}},"required":["ids"],"additionalProperties":false},"Asset":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["IMAGE","MAP","FOLDER","AUDIO"]},"folderId":{"type":["string","null"]},"isHidden":{"type":"boolean"},"description":{"type":["string","null"]},"url":{"type":"string","description":"The file URL of an IMAGE asset, always on a LegendKeeper asset host."},"width":{"type":"number","description":"Pixel width of an IMAGE asset, read from the stored file."},"height":{"type":"number","description":"Pixel height of an IMAGE asset, read from the stored file."},"createdAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."}},"required":["id","name","type"]},"AssetList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"AssetCreateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Folder name, 1–200 characters (this endpoint provisions a folder; images upload through createImageUpload and createImageAsset)."},"folderId":{"type":"string","maxLength":256,"description":"Parent folder ID (root if omitted). It must be the id of a FOLDER asset in this project; any other id answers 400 VALIDATION_ERROR at `folderId`."}},"required":["name"],"additionalProperties":false},"ImageUpload":{"type":"object","properties":{"uploadKey":{"type":"string","description":"Opaque key naming the upload. Pass it to createImageAsset once the upload succeeds."},"uploadUrl":{"type":"string","description":"The signed storage URL to send the file to."},"method":{"type":"string","enum":["PUT"],"description":"The HTTP method for the upload."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Headers the upload must send, exactly as given."},"expiresAt":{"type":"string","description":"ISO-8601 time after which `uploadUrl` is refused."}},"required":["uploadKey","uploadUrl","method","headers","expiresAt"]},"ImageUploadCreateParams":{"type":"object","properties":{"contentType":{"type":"string","enum":["image/jpeg","image/jpg","image/png","image/gif","image/webp"],"description":"The MIME type of the image. The upload must send it as `content-type`."},"contentLength":{"type":"integer","exclusiveMinimum":0,"description":"The size of the file in bytes, charged against the storage quota and the daily upload budget. The upload body must be exactly this many bytes. A size past the project owner's storage quota answers 413 STORAGE_QUOTA_EXCEEDED."},"contentHash":{"type":"string","minLength":64,"maxLength":64,"pattern":"^[a-f0-9]{64}$","description":"Optional lowercase hex SHA-256 of the file. When sent, storage rejects an upload whose bytes do not match it."}},"required":["contentType","contentLength"],"additionalProperties":false},"ImageAssetCreateParams":{"type":"object","properties":{"uploadKey":{"type":"string","minLength":1,"maxLength":512,"description":"The `uploadKey` from createImageUpload in this project. A key from another project, or one with no image stored under it, answers 400 VALIDATION_ERROR."},"name":{"type":"string","minLength":1,"maxLength":200,"description":"Asset name, 1–200 characters."},"description":{"type":"string","maxLength":10000,"description":"Asset description, stored on the asset and returned by getAsset. Omitted, the asset has no description."},"folderId":{"type":"string","maxLength":256,"description":"Folder to place the asset in (root if omitted). It must be the id of a FOLDER asset in this project; any other id answers 400 VALIDATION_ERROR at `folderId`."}},"required":["uploadKey","name"],"additionalProperties":false},"AssetUpdateParams":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"New name, 1–200 characters."},"description":{"type":"string","maxLength":10000},"folderId":{"type":["string","null"],"maxLength":256,"description":"Move to a folder; null moves to root. It must be the id of a FOLDER asset in this project that is neither the asset itself nor inside it; any other id answers 400 VALIDATION_ERROR at `folderId`."},"isHidden":{"type":"boolean"}},"additionalProperties":false},"Member":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"name":{"type":["string","null"]},"email":{"type":["string","null"],"description":"The member's email address. null unless the caller has the ADMIN role."},"role":{"type":"string","enum":["ADMIN","MEMBER","OWNER"]},"image":{"type":["string","null"]}},"required":["id"]},"MemberList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"InviteResult":{"type":"object","properties":{"success":{"type":"boolean"},"alreadyMember":{"type":"boolean","description":"`true` when the address belongs to a member of the project."},"alreadyInvited":{"type":"boolean","description":"`true` when the address has a pending invite."}},"required":["success"]},"MemberInviteParams":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","description":"Email address to invite."}},"required":["email"],"additionalProperties":false},"Invite":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":["string","null"]},"role":{"type":"string","enum":["ADMIN","MEMBER"]},"createdAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."},"expiresAt":{"type":["string","null"],"format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."}},"required":["id"]},"InviteList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"Tag":{"type":"object","properties":{"tag":{"type":"string"},"count":{"type":"integer","description":"The number of resources in the project that carry the tag."}},"required":["tag","count"]},"TagList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"SearchHitResource":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"iconGlyph":{"type":["string","null"]},"iconColor":{"type":["string","null"],"description":"Fill color of this resource's map pins. Also tints its cards and graph nodes. Written as `#RRGGBB`; a resource from an import or an older version may hold another CSS color string. Null when no color is stored."},"iconShape":{"type":"string","enum":["pin","diamond","flag","marker","shield","circle","banner","arch","none"],"description":"The shape drawn behind the glyph on a map pin, or `none` for the glyph alone."},"iconSize":{"type":"string","enum":["medium","small"],"description":"The size of the pin shape. Absent when `iconShape` is `none`."},"parentId":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"path":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"description":"Ancestors of the resource from the root down; absent for a root resource."}},"required":["id","name","tags"]},"SearchHighlight":{"type":"object","properties":{"segment":{"type":"string"},"index":{"type":"number"},"matchStart":{"type":"number"},"matchEnd":{"type":"number"}},"required":["segment","index","matchStart","matchEnd"]},"SearchHitDocument":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"highlights":{"type":"array","items":{"$ref":"#/components/schemas/SearchHighlight"},"description":"The matching passage with the offsets of the first match in it."},"isSolo":{"type":"boolean","description":"True when this is the only document of the resource in the results."}},"required":["id","name"],"description":"Present when the match is in the content of one of the resource's documents rather than its name or aliases."},"SearchResult":{"type":"object","properties":{"resource":{"$ref":"#/components/schemas/SearchHitResource"},"document":{"$ref":"#/components/schemas/SearchHitDocument"}},"required":["resource"]},"SearchResultList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"CalendarMonth":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's months."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, 1 or more characters."},"isIntercalary":{"type":"boolean","description":"Marks a festival or gap period that sits between regular months. Date arithmetic counts an intercalary month like any other month."},"length":{"type":"number","minimum":1,"description":"Days in the month, 1 or more."},"interval":{"type":"number","minimum":1,"description":"The month occurs every `interval` years: 1 is every year, 4 is every fourth year. A whole number, 1 or more. Any other value answers 400 VALIDATION_ERROR at the field."},"offset":{"type":"number","description":"Shifts which years a month with `interval` above 1 occurs in. Ignored when `interval` is 1."}},"required":["id","name","isIntercalary","length","interval","offset"],"description":"A month. Months run in array order; a year is every month whose `interval` includes that year, plus the leap days that fall in it."},"CalendarLeapDay":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's leap days."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, such as `Leap Day`."},"intercalary":{"type":"boolean","description":"Stored with the leap day; the app writes false. Date arithmetic does not read it."},"month":{"type":"number","minimum":0,"description":"Zero-based index into `months` of the month the leap day lengthens by one day. A value outside `months` answers 400 VALIDATION_ERROR at the field."},"addsWeekDay":{"type":"boolean","description":"Stored with the leap day; the app writes false. Date arithmetic does not read it."},"day":{"type":"number","minimum":0,"description":"Stored with the leap day; the app writes 1. Date arithmetic adds the leap day to the end of `month` and does not read this field."},"weekDay":{"type":"string","maxLength":256,"description":"Stored with the leap day; the app writes an empty string. Date arithmetic does not read it."},"interval":{"type":"string","maxLength":256,"description":"The years the leap day occurs in, as comma-separated terms. `4` is every fourth year; a `!` term removes years, so `400,!100,4` is the Gregorian rule (every fourth year, except every hundredth, except every four-hundredth). A term may carry its own offset as `4+1`. Any other string answers 400 VALIDATION_ERROR at `leapDays.N.interval`."},"offset":{"type":"number","description":"Year offset applied to every term of `interval`. 0 aligns the cycle with year 0."}},"required":["id","name","intercalary","month","addsWeekDay","day","weekDay","interval","offset"],"description":"An extra day added to one month in the years its `interval` selects."},"CalendarWeekday":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's weekdays."},"name":{"type":"string","maxLength":500,"description":"Display name, such as `Finnsday`."}},"required":["id","name"],"description":"A day of the week. Days cycle through `weekdays` in array order."},"CalendarNegativeEra":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's eras."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, such as `Common Era` or `Before Common Era`. Rendered by the `EE` format token."},"abbr":{"type":"string","maxLength":256,"default":"AD","description":"Abbreviation rendered by the `E` format token, such as `CE` or `BCE`. Defaults to `AD`."},"hideAbbr":{"type":"boolean","default":false,"description":"Leaves the abbreviation out of formatted dates. Defaults to false."},"startsAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"exclusiveMaximum":0,"description":"The earliest minute the calendar represents, a negative whole number. Dates from here to minute -1 belong to this era and count their years backwards."},"resetMode":{"type":"string","enum":["none"],"description":"Always `none`."}},"required":["id","name","startsAt","resetMode"],"description":"The era before the epoch. Absent, the calendar starts at the first forward era."},"CalendarEra":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's eras."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, such as `Common Era` or `Before Common Era`. Rendered by the `EE` format token."},"abbr":{"type":"string","maxLength":256,"default":"AD","description":"Abbreviation rendered by the `E` format token, such as `CE` or `BCE`. Defaults to `AD`."},"hideAbbr":{"type":"boolean","default":false,"description":"Leaves the abbreviation out of formatted dates. Defaults to false."},"startsAt":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The minute the era begins, a whole number 0 or more. Each era must start later than the one before it."},"resetMode":{"type":"string","enum":["year","calendar","none"],"description":"`none`: years keep counting from the calendar epoch. `year`: year numbering restarts at the era start, as regnal years do. `calendar`: year, month and day numbering all restart at the era start."}},"required":["id","name","startsAt","resetMode"],"description":"A forward era. Dates from `startsAt` until the next era's `startsAt` belong to it."},"CalendarMoon":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Stable id, unique among the calendar's moons."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, 1 or more characters."},"phase":{"type":"number","exclusiveMinimum":0,"description":"Length of one full lunar cycle in minutes. May be fractional."},"shift":{"type":"number","description":"Offset of the cycle in minutes. May be negative or fractional."},"color":{"type":"string","maxLength":64,"default":"#FFFFFF","description":"Display color as a hex code. Defaults to `#FFFFFF`."}},"required":["id","name","phase","shift"],"description":"A moon whose phases the calendar view shows."},"CalendarFormat":{"type":"object","properties":{"id":{"type":"string","maxLength":256,"description":"Name of the format preset, such as `american-verbose`."},"year":{"type":"string","maxLength":256,"description":"Template for a date shown to the year, such as `YYYY E`."},"month":{"type":"string","maxLength":256,"description":"Template for a date shown to the month, such as `MMMM YYYY E`."},"day":{"type":"string","maxLength":256,"description":"Template for a date shown to the day, such as `MMMM D^, YYYY E`."},"time":{"type":"string","maxLength":256,"description":"Template for a date shown to the minute, such as `MMMM D^, YYYY E, HH:mm`."}},"required":["id","year","month","day","time"],"description":"Templates for formatted dates, including `formattedStart` and `formattedEnd` on events. Tokens: `YYYY` year, `E` era abbreviation, `EE` era name, `MMMM` month name, `MMM` month abbreviation, `M` and `MM` month number, `D` and `DD` day number, `DDDD` weekday name, `DDD` weekday abbreviation, `H` and `HH` hour, `m` and `mm` minute. `^` after a number adds an ordinal suffix (`D^` renders `1st`). Text in square brackets is literal. Defaults to `{ id: \"american-verbose\", year: \"YYYY E\", month: \"MMMM YYYY E\", day: \"MMMM D^, YYYY E\", time: \"MMMM D^, YYYY, HH:mm\" }`."},"Calendar":{"type":"object","properties":{"id":{"type":"string","description":"The calendar id. A timeline document names its calendar by this id as `calendarId`."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, 1 or more characters."},"description":{"type":"string","maxLength":10000,"description":"Free text shown with the calendar."},"hasZeroYear":{"type":"boolean","description":"True when a year 0 exists. False makes year -1 directly precede year 1, as in the Gregorian calendar."},"maxMinutes":{"type":"number","description":"The latest minute the calendar represents."},"months":{"type":"array","items":{"$ref":"#/components/schemas/CalendarMonth"},"minItems":1,"maxItems":1000,"description":"The months of the year in order. At least one."},"leapDays":{"type":"array","items":{"$ref":"#/components/schemas/CalendarLeapDay"},"maxItems":1000,"description":"Leap days. May be empty."},"weekdays":{"type":"array","items":{"$ref":"#/components/schemas/CalendarWeekday"},"minItems":1,"maxItems":1000,"description":"The days of the week in order. At least one."},"epochWeekday":{"type":"number","minimum":0,"description":"Zero-based index into `weekdays` of the weekday of the epoch's first day. A value outside `weekdays` answers 400 VALIDATION_ERROR at `epochWeekday`."},"weekResetsEachMonth":{"type":"boolean","description":"True starts every month on the first weekday. False or absent lets weeks run on across month boundaries."},"hoursInDay":{"type":"number","minimum":1,"description":"Hours in a day, 1 or more."},"minutesInHour":{"type":"number","minimum":1,"description":"Minutes in an hour, 1 or more."},"negativeEra":{"$ref":"#/components/schemas/CalendarNegativeEra"},"positiveEras":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEra"},"minItems":1,"maxItems":1000,"description":"Forward eras in ascending `startsAt` order. At least one; the first usually starts at 0. Eras out of `startsAt` order answer 400 VALIDATION_ERROR at the field."},"moons":{"type":"array","items":{"$ref":"#/components/schemas/CalendarMoon"},"maxItems":1000,"description":"Moons. Absent or empty means none."},"format":{"$ref":"#/components/schemas/CalendarFormat"},"halfClock":{"type":"boolean","default":false,"description":"True renders times on a 12-hour clock with AM and PM when `hoursInDay` is even. Defaults to false."},"version":{"type":"string","description":"The calendar version, also sent as `ETag` by createCalendar and updateCalendar. Send it as `If-Match` to updateCalendar or deleteCalendar to fail with 412 instead of overwriting a change made since you read."}},"required":["id","name","hasZeroYear","maxMinutes","months","leapDays","weekdays","epochWeekday","hoursInDay","minutesInHour","positiveEras","version"],"description":"A calendar specification with its `id` and `version`. The built-in calendars are `gregorian`, `harptos`, `eberron`, `exandria`, `greyhawk`, `elder-scrolls`."},"CalendarList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Calendar"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]},"CalendarSpec":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"The calendar id, 1–100 characters. On createCalendar it is optional and minted when absent; an id already in the project or equal to a built-in id answers 409 DUPLICATE_ID. On updateCalendar it is optional and must equal the path id."},"name":{"type":"string","minLength":1,"maxLength":500,"description":"Display name, 1 or more characters."},"description":{"type":"string","maxLength":10000,"description":"Free text shown with the calendar."},"hasZeroYear":{"type":"boolean","description":"True when a year 0 exists. False makes year -1 directly precede year 1, as in the Gregorian calendar."},"maxMinutes":{"type":"number","description":"The latest minute the calendar represents."},"months":{"type":"array","items":{"$ref":"#/components/schemas/CalendarMonth"},"minItems":1,"maxItems":1000,"description":"The months of the year in order. At least one."},"leapDays":{"type":"array","items":{"$ref":"#/components/schemas/CalendarLeapDay"},"maxItems":1000,"description":"Leap days. May be empty."},"weekdays":{"type":"array","items":{"$ref":"#/components/schemas/CalendarWeekday"},"minItems":1,"maxItems":1000,"description":"The days of the week in order. At least one."},"epochWeekday":{"type":"number","minimum":0,"description":"Zero-based index into `weekdays` of the weekday of the epoch's first day. A value outside `weekdays` answers 400 VALIDATION_ERROR at `epochWeekday`."},"weekResetsEachMonth":{"type":"boolean","description":"True starts every month on the first weekday. False or absent lets weeks run on across month boundaries."},"hoursInDay":{"type":"number","minimum":1,"description":"Hours in a day, 1 or more."},"minutesInHour":{"type":"number","minimum":1,"description":"Minutes in an hour, 1 or more."},"negativeEra":{"$ref":"#/components/schemas/CalendarNegativeEra"},"positiveEras":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEra"},"minItems":1,"maxItems":1000,"description":"Forward eras in ascending `startsAt` order. At least one; the first usually starts at 0. Eras out of `startsAt` order answer 400 VALIDATION_ERROR at the field."},"moons":{"type":"array","items":{"$ref":"#/components/schemas/CalendarMoon"},"maxItems":1000,"description":"Moons. Absent or empty means none."},"format":{"$ref":"#/components/schemas/CalendarFormat"},"halfClock":{"type":"boolean","default":false,"description":"True renders times on a 12-hour clock with AM and PM when `hoursInDay` is even. Defaults to false."}},"required":["name","hasZeroYear","maxMinutes","months","leapDays","weekdays","epochWeekday","hoursInDay","minutesInHour","positiveEras"],"additionalProperties":false,"description":"A calendar specification: the months, weekdays, leap days, eras, moons, clock and date formats that timelines render dates in. Event times are stored as minutes from the epoch, so a calendar change re-renders existing events without moving them. Unknown fields answer 400 VALIDATION_ERROR.","example":{"id":"ooo","name":"The Calendar of Ooo","description":"Four kingdom months of thirty days and the five-day Mathematical festival, counted from the Great Mushroom War.","hasZeroYear":false,"maxMinutes":1800000000,"months":[{"id":"candy","name":"Candy","isIntercalary":false,"length":30,"interval":1,"offset":0},{"id":"ice","name":"Ice","isIntercalary":false,"length":30,"interval":1,"offset":0},{"id":"flame","name":"Flame","isIntercalary":false,"length":30,"interval":1,"offset":0},{"id":"lumpy-space","name":"Lumpy Space","isIntercalary":false,"length":30,"interval":1,"offset":0},{"id":"mathematical","name":"Mathematical","isIntercalary":true,"length":5,"interval":1,"offset":0}],"leapDays":[{"id":"gunter-day","name":"Gunter Day","intercalary":false,"month":3,"addsWeekDay":false,"day":1,"weekDay":"","interval":"4","offset":0}],"weekdays":[{"id":"finn","name":"Finnsday"},{"id":"jake","name":"Jakesday"},{"id":"bubblegum","name":"Bubblegumsday"},{"id":"marceline","name":"Marcelinesday"},{"id":"bmo","name":"BMOsday"}],"epochWeekday":0,"weekResetsEachMonth":false,"hoursInDay":24,"minutesInHour":60,"negativeEra":{"id":"before-war","name":"Before the Mushroom War","abbr":"BMW","hideAbbr":false,"startsAt":-180000000,"resetMode":"none"},"positiveEras":[{"id":"after-war","name":"After the Mushroom War","abbr":"AMW","hideAbbr":false,"startsAt":0,"resetMode":"none"}],"moons":[{"id":"the-moon","name":"The Moon","phase":40320,"shift":0,"color":"#E8E4D8"}],"format":{"id":"ooo","year":"YYYY E","month":"MMMM YYYY E","day":"MMMM D^, YYYY E","time":"MMMM D^, YYYY E, HH:mm"},"halfClock":false}},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isPublic":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time","pattern":"Z$","description":"ISO 8601 date-time in UTC, ending in `Z`."}},"required":["id"]},"ProjectList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"hasMore":{"type":"boolean","description":"True when more items exist beyond this page."},"nextCursor":{"type":["string","null"],"description":"Cursor for the next page, or null."}},"required":["data"]}},"parameters":{}},"paths":{"/api/v3/projects/{projectId}/resources":{"get":{"operationId":"listResources","tags":["Resources"],"summary":"List resources","description":"Lists a page of the project's resources as ResourceListItems, ordered by id. Pass `nextCursor` back as `cursor` for the next page. A caller who is not a project admin sees only resources reachable through non-hidden ancestors. Deleted resources are never listed.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","maxLength":2048,"description":"Pagination cursor from a previous `nextCursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size (1–100, default 50)."},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":256,"description":"Only return direct children of this resource. `templates` returns the top-level templates. See Templates."},"required":false,"name":"parentId","in":"query"}],"responses":{"200":{"description":"A page of resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceList"}}}},"400":{"description":"A cursor this endpoint did not issue, or a `limit` outside 1–100 (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createResource","tags":["Resources"],"summary":"Create a resource","description":"Creates a resource with the documents in `documents`. Body is ResourceCreateParams. The resource is appended after its last sibling unless `after` or `before` places it. See Resource order. The request is validated as a whole: on any 4xx, nothing is created. The response is the full Resource, with the new documents in `documents` in request order; read their content with getDocumentBlocks. A non-admin caller must create the resource under a resource they can edit, and not hidden.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceCreateParams"}}}},"responses":{"201":{"description":"The created resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Validation error, with block paths under `documents[i].blocks` (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND) or a tree the editor cannot hold (INVALID_CONTENT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller creating at the root, under a resource they cannot edit, or hidden (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown `parentId`, `after` or `before` (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/templates":{"get":{"operationId":"listTemplates","tags":["Templates"],"summary":"List templates","description":"Lists a page of the project's templates as ResourceListItems, ordered by id: every live resource under the `templates` root, at any depth. A top-level template has `parentId` `templates`; a nested template has its parent template's id. Pass `nextCursor` back as `cursor` for the next page. Only project members may call it. See Templates.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","maxLength":2048,"description":"Pagination cursor from a previous `nextCursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size (1–100, default 50)."},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"A page of templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceList"}}}},"400":{"description":"A cursor this endpoint did not issue, or a `limit` outside 1–100 (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/batch":{"post":{"operationId":"createManyResources","tags":["Resources"],"summary":"Create many resources","description":"Creates several resources in order. Body is ResourceBatchCreateParams; each item is validated as createResource validates its body. Every item is checked before any is created: the first failing item's 4xx answers the request, with error paths under `resources[i]`, and nothing is created. A batch counts as one write request against the write limits. A server error part-way through keeps the items created before it; give each item an `id` so that a retry answers 409 DUPLICATE_ID for those.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceBatchCreateParams"}}}},"responses":{"201":{"description":"The created resources, in input order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceBatch"}}}},"400":{"description":"Validation error at `resources[i]` (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND) or a tree the editor cannot hold (INVALID_CONTENT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller creating at the root, under a resource they cannot edit, or hidden (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown `parentId`, `after` or `before` (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"An `id` used twice in the batch or already used in the project (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller's item budget of 600 items a minute and 6,000 an hour is spent, with `Retry-After` (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/from-template":{"post":{"operationId":"createResourceFromTemplate","tags":["Resources"],"summary":"Create a resource from a template","description":"Creates a resource as a copy of a template. Body is ResourceFromTemplateParams. The copy takes the template's fields, properties and documents with their content, under new ids; it is placed as createResource places a resource. Each copied resource counts as one item against the createManyResources item budget. See Templates. The response is the new Resource.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceFromTemplateParams"}}}},"responses":{"201":{"description":"The created resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Validation error, or `templateId` names a resource that is not a template (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller creating at the root, under a resource they cannot edit, or under `templates` (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown `templateId`, `parentId`, `after` or `before` (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller's item budget of 600 items a minute and 6,000 an hour is spent, with `Retry-After` (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/save-as-template":{"post":{"operationId":"saveResourceAsTemplate","tags":["Resources"],"summary":"Save a resource as a template","description":"Creates a top-level template as a copy of the resource. Body is ResourceSaveAsTemplateParams; it may be empty. The copy takes the resource's fields, properties and documents with their content, under new ids. The resource itself does not change. Only project admins may call it. Each copied resource counts as one item against the createManyResources item budget. See Templates. The response is the new template as a Resource.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceSaveAsTemplateParams"}}}},"responses":{"201":{"description":"The created template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Validation error, or more resources than one copy holds (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A caller who is not a project admin (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown or deleted resource, or one the caller cannot view, or unknown `after` or `before` (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The caller's item budget of 600 items a minute and 6,000 an hour is spent, with `Retry-After` (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}":{"get":{"operationId":"getResource","tags":["Resources"],"summary":"Get a resource","description":"The resource with its `documents` (Document summaries) and `properties` (PropertyBlocks). A resource the caller cannot reach, because it or an ancestor is hidden or denies access, answers 404 NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"}],"responses":{"200":{"description":"The resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateResource","tags":["Resources"],"summary":"Update a resource","description":"Updates a resource. Body is ResourceUpdateParams. Only the fields sent change, and a value equal to the current one is not a change. An empty body answers 400 VALIDATION_ERROR. Only project admins may change `isHidden`. Changing `permissions` needs project admin or Full Access on the resource. A refused update answers 403 FORBIDDEN and changes nothing. The response is the full Resource.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceUpdateParams"}}}},"responses":{"200":{"description":"The updated resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller changing `isHidden`, or changing `permissions` without Full Access (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteResource","tags":["Resources"],"summary":"Delete a resource","description":"Marks the resource deleted. Its documents and properties go with it, and it leaves lists and search at once. A resource with child resources that are not deleted is deleted only with `cascade=true`; otherwise nothing is deleted. A caller who is not a project admin needs Can Edit or Full Access on the resource and, for a cascade, on every descendant it deletes; otherwise the request answers 403 FORBIDDEN and nothing is deleted.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"boolean","description":"Delete every descendant that is not deleted together with the resource. Default false. Without `true`, a resource with child resources that are not deleted answers 409 HAS_CHILDREN; children already deleted do not count. A cascade gives the resource and its descendants one shared `deletedAt`, which restoreResource uses to restore them together. A value other than `true` or `false` answers 400 VALIDATION_ERROR."},"required":false,"name":"cascade","in":"query"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller without Can Edit or Full Access on the resource or on a descendant of a cascade (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already deleted (ALREADY_DELETED), or has child resources and `cascade` is not `true` (HAS_CHILDREN)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/move":{"post":{"operationId":"moveResource","tags":["Resources"],"summary":"Move or reorder a resource","description":"Moves a resource to another parent or reorders it among its siblings. Body is ResourceMoveParams. With neither `after` nor `before`, the resource goes after the last sibling. Children move with the resource. See Resource order. An empty body answers 400 VALIDATION_ERROR. A caller who is not a project admin needs Can Edit or Full Access on the resource and on the destination parent, and cannot move it to the root; otherwise nothing changes. The response is the full Resource.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceMoveParams"}}}},"responses":{"200":{"description":"The moved resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A non-admin caller without Can Edit or Full Access on the resource, moving it to the root, or under a resource they cannot view (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown or deleted resource, `parentId`, `after` or `before` (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/restore":{"post":{"operationId":"restoreResource","tags":["Resources"],"summary":"Restore a deleted resource","description":"Restores a deleted resource together with every descendant deleted by the same operation, the descendants whose `deletedAt` equals the resource's. A descendant deleted separately stays deleted. A resource whose parent no longer exists is restored at the root, after the last root resource. Only project admins may restore; any other caller gets 404 NOT_FOUND for a resource it cannot view, which includes every deleted resource, and 403 FORBIDDEN otherwise. The response is the full Resource.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"The restored resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Resource"}}}},"400":{"description":"Malformed `Idempotency-Key` (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A caller who is not a project admin, on a resource it can view (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not deleted (NOT_DELETED), or the parent is deleted and must be restored first (PARENT_DELETED); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs":{"get":{"operationId":"listDocuments","tags":["Documents"],"summary":"List a resource's documents","description":"Every document of the resource as a Document summary (`id`, `name`, `type`, `rank`, `isHidden`, `isFullWidth`, timestamps, and `sources` on a timeline). The list is not paginated. Hidden documents are listed only for project admins; order the result by `rank` to match the app. A resource the caller cannot reach, because it or an ancestor is hidden or denies access, answers 404 NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"}],"responses":{"200":{"description":"The resource's documents","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createDocument","tags":["Documents"],"summary":"Create a document","description":"Creates a document in the resource. Body is DocumentCreateParams. The document is appended after the resource's existing documents and starts empty; a map starts with `mapImage` null. Set a map's image with updateDocument. A new resource already has one `blank` document, returned in createResource's `documents`; write content to it instead of creating a document, and call createDocument for each additional document.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentCreateParams"}}}},"responses":{"201":{"description":"The created document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}":{"get":{"operationId":"getDocument","tags":["Documents"],"summary":"Get a document","description":"The document summary. Read page content with getDocumentBlocks, board content with getBoardContent, map content with listFeatures and timeline content with listLanes and listEvents. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"responses":{"200":{"description":"The document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateDocument","tags":["Documents"],"summary":"Update a document","description":"Updates a document's metadata. Body is DocumentUpdateParams. Only the fields sent change; content is not touched. `calendarId` and `sources` apply to a timeline (`time`) document and `mapImage` to a map document. An empty body answers 400 VALIDATION_ERROR. Setting `mapImage` on a `blank` document converts it to a map document.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUpdateParams"}}}},"responses":{"200":{"description":"The updated document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a map document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteDocument","tags":["Documents"],"summary":"Delete a document","description":"Marks the document deleted together with its content; it no longer appears in listDocuments. Its content is kept: it waits in the project's trash until restoreDocument brings it back or the trash is emptied. Deleting a document that is already deleted answers 409 ALREADY_DELETED.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/restore":{"post":{"operationId":"restoreDocument","tags":["Documents"],"summary":"Restore a deleted document","description":"Brings a deleted document back in its old place in the resource, with its content; it appears in listDocuments again. When the document's resource is deleted, restore the resource with restoreResource, which brings back the documents it had when it was deleted. A document that was moved to another resource, or that the trash has erased, answers 404 NOT_FOUND. Restoring needs the same access as deleting the document. The response is the restored document.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"The restored document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"400":{"description":"Malformed `Idempotency-Key` (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not deleted (NOT_DELETED), or the resource is deleted (PARENT_DELETED); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/block-ids":{"post":{"operationId":"assignBlockIds","tags":["Documents"],"summary":"Assign block ids","description":"Assigns a stable id to every block in a page document that lacks one. Idempotent. Run this once on a legacy document before addressing its blocks; reads never assign ids. A document that is not a page or `blank` answers 400 KIND_MISMATCH. A `blank` document has no blocks, so the call assigns none and the document stays `blank`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"responses":{"200":{"description":"Count of newly assigned ids and the document version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockIdsResult"}}}},"400":{"description":"Not a page document (KIND_MISMATCH); malformed `Idempotency-Key` (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/properties":{"get":{"operationId":"listProperties","tags":["Properties"],"summary":"List a resource's properties","description":"Sidebar properties, sorted by rank. Each is a PropertyBlock. A property whose type the public model cannot express reads as `{ kind: \"unsupported\", id }` with its envelope; echo it unchanged to preserve it. A caller who is not a project admin does not see hidden properties. A resource the caller cannot reach, because it or an ancestor is hidden or denies access, answers 404 NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"}],"responses":{"200":{"description":"The resource's properties","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createProperty","tags":["Properties"],"summary":"Create a property","description":"Adds a property to the resource's sidebar. Body is a PropertyCreateRequest. A supplied `id` that is already used answers 409.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyCreateRequest"}}}},"responses":{"201":{"description":"The created property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyBlock"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or unsupported kind (UNSUPPORTED_KIND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource or anchor not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/properties/{propertyId}":{"get":{"operationId":"getProperty","tags":["Properties"],"summary":"Get a property","description":"The sidebar property as a PropertyBlock: its kind's fields plus the envelope (`id`, `rank`, `title`, `isTitleHidden`, `isHidden`). A hidden property answers 404 NOT_FOUND to a caller who is not a project admin. A resource the caller cannot reach, because it or an ancestor is hidden or denies access, answers 404 NOT_FOUND.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"}],"responses":{"200":{"description":"The property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyBlock"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateProperty","tags":["Properties"],"summary":"Update a property","description":"Body is a PropertyUpdateRequest. An empty body answers 400 VALIDATION_ERROR. The envelope of an `unsupported` property can be patched; its content cannot.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyUpdateRequest"}}}},"responses":{"200":{"description":"The updated property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyBlock"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteProperty","tags":["Properties"],"summary":"Delete a property","description":"Removes the property from the resource's sidebar. The property's rows go with it; blocks on the resource's pages are not affected.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks":{"get":{"operationId":"getDocumentBlocks","tags":["Documents"],"summary":"Get a document as blocks","description":"The whole document tree as Blocks. For a caller who is not a project admin, secret blocks and their contents are omitted. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. A `blank` document reads as an empty page and stays `blank`. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"responses":{"200":{"description":"The document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentBlocks"}}}},"400":{"description":"Not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"replaceDocumentBlocks","tags":["Documents"],"summary":"Replace a document","description":"Replaces the whole document tree. Body is DocumentBlocksWrite. The result is validated as a whole and nothing is written on 400. A write to a `blank` document converts it to a page document and saves the content in the same request. Responses carry the document `version` in the body and as `ETag`. Secret blocks and infobox properties marked `isHidden` are admin-only. For a caller who is not a project admin, the write keeps each admin-only block and property where it was; a body that contains one, or a write that would remove one, answers 403 FORBIDDEN and changes nothing.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentBlocksWrite"}}}},"responses":{"200":{"description":"The new document","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentBlocks"}}}},"400":{"description":"Validation error with block paths (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND), a tree the editor cannot hold (INVALID_CONTENT) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"insertBlock","tags":["Blocks"],"summary":"Insert a block","description":"Inserts a block with its subtree. Body is BlockInsertRequest. A write to a `blank` document converts it to a page document and saves the content in the same request. Responses carry the document `version` in the body and as `ETag`. Secret blocks and infobox properties marked `isHidden` are admin-only. For a caller who is not a project admin, the write keeps each admin-only block and property where it was; a body that contains one, or a write that would remove one, answers 403 FORBIDDEN and changes nothing.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockInsertRequest"}}}},"responses":{"201":{"description":"The inserted block with its subtree","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedBlock"}}}},"400":{"description":"Validation error with block paths (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND), a tree the editor cannot hold (INVALID_CONTENT) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Document or anchor not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}":{"get":{"operationId":"getBlock","tags":["Blocks"],"summary":"Get a block","description":"The block with its subtree. For a caller who is not a project admin, secret blocks and their contents are omitted. A block inside a secret answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"}],"responses":{"200":{"description":"The block","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedBlock"}}}},"400":{"description":"Not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The block id occurs more than once in a legacy document (AMBIGUOUS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"replaceBlock","tags":["Blocks"],"summary":"Replace a block","description":"Replaces the block and its subtree; the block keeps its id. Body is a Block. Requested ids in the subtree are kept, and ids of the replaced subtree may be reused. The same id twice in the body answers 400 VALIDATION_ERROR. Responses carry the document `version` in the body and as `ETag`. Secret blocks and infobox properties marked `isHidden` are admin-only. For a caller who is not a project admin, the write keeps each admin-only block and property where it was; a body that contains one, or a write that would remove one, answers 403 FORBIDDEN and changes nothing.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Block"}}}},"responses":{"200":{"description":"The replaced block","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedBlock"}}}},"400":{"description":"Validation error with block paths (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND), a tree the editor cannot hold (INVALID_CONTENT) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"An id in the body is used by a block outside the replaced subtree, named by its path, and nothing is written (DUPLICATE_ID); or the block id occurs more than once in a legacy document (AMBIGUOUS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateBlock","tags":["Blocks"],"summary":"Update a block's fields","description":"Updates the block's own fields. Body is a BlockPatch. Children are unchanged. Responses carry the document `version` in the body and as `ETag`. Secret blocks and infobox properties marked `isHidden` are admin-only. For a caller who is not a project admin, the write keeps each admin-only block and property where it was; a body that contains one, or a write that would remove one, answers 403 FORBIDDEN and changes nothing.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockPatch"}}}},"responses":{"200":{"description":"The updated block","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedBlock"}}}},"400":{"description":"Validation error with block paths (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND), a tree the editor cannot hold (INVALID_CONTENT) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The block id occurs more than once in a legacy document (AMBIGUOUS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteBlock","tags":["Blocks"],"summary":"Delete a block","description":"Removes the block and its subtree. A removal that leaves the document invalid, for example the paragraph a list item requires, answers 400 INVALID_CONTENT. Responses carry the document `version` in the body and as `ETag`. Removing a block that holds a secret or an infobox property marked `isHidden` answers 403 FORBIDDEN to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"The block cannot be removed (INVALID_CONTENT) or the document is not a page (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The block id occurs more than once in a legacy document (AMBIGUOUS)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/move":{"post":{"operationId":"moveBlock","tags":["Blocks"],"summary":"Move a block","description":"Moves a block with its subtree, which keeps its ids. Body is a BlockMoveRequest. Moving a block into itself answers 400 INVALID_CONTENT. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockMoveRequest"}}}},"responses":{"200":{"description":"The moved block","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedBlock"}}}},"400":{"description":"The block cannot be placed there (INVALID_CONTENT), the placement is malformed (VALIDATION_ERROR) or the document is not a page (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Block or anchor not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The block id occurs more than once in a legacy document (AMBIGUOUS); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/properties/{propertyId}/rows":{"get":{"operationId":"listPropertyRows","tags":["Properties"],"summary":"List property rows","description":"Every row of the property as a Row, sorted by rank. The list is not paginated. A hidden property answers 404 NOT_FOUND to a caller who is not a project admin. A resource the caller cannot reach, because it or an ancestor is hidden or denies access, answers 404 NOT_FOUND. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"}],"responses":{"200":{"description":"Rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowList"}}}},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createPropertyRow","tags":["Properties"],"summary":"Create a property row","description":"Adds a row to the property. Body is a RowCreateRequest: `key` plus a value, `content` or `text`, and an optional placement. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowCreateRequest"}}}},"responses":{"201":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Container or anchor row not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/properties/{propertyId}/rows/{rowId}":{"patch":{"operationId":"updatePropertyRow","tags":["Properties"],"summary":"Update a property row","description":"Updates a row of the property. Body is a RowPatchRequest: any of `key`, `content` and `text`. An empty body answers 400 VALIDATION_ERROR. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowPatchRequest"}}}},"responses":{"200":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deletePropertyRow","tags":["Properties"],"summary":"Delete a property row","description":"Removes the row from the property. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Property ID"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/rows":{"get":{"operationId":"listBlockRows","tags":["Blocks"],"summary":"List block rows","description":"Every row of the block as a Row, sorted by rank. The list is not paginated. A block inside a secret answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"}],"responses":{"200":{"description":"Rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowList"}}}},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createBlockRow","tags":["Blocks"],"summary":"Create a block row","description":"Adds a row to the block. Body is a RowCreateRequest: `key` plus a value, `content` or `text`, and an optional placement. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowCreateRequest"}}}},"responses":{"201":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Container or anchor row not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/rows/{rowId}":{"patch":{"operationId":"updateBlockRow","tags":["Blocks"],"summary":"Update a block row","description":"Updates a row of the block. Body is a RowPatchRequest: any of `key`, `content` and `text`. An empty body answers 400 VALIDATION_ERROR. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowPatchRequest"}}}},"responses":{"200":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteBlockRow","tags":["Blocks"],"summary":"Delete a block row","description":"Removes the row from the block. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/properties/{propertyId}/rows":{"get":{"operationId":"listBlockPropertyRows","tags":["Blocks"],"summary":"List infobox property rows","description":"Every row of the infobox property as a Row, sorted by rank. The list is not paginated. An infobox inside a secret answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"}],"responses":{"200":{"description":"Rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowList"}}}},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createBlockPropertyRow","tags":["Blocks"],"summary":"Create a infobox property row","description":"Adds a row to the infobox property. Body is a RowCreateRequest: `key` plus a value, `content` or `text`, and an optional placement. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowCreateRequest"}}}},"responses":{"201":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Container or anchor row not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/properties/{propertyId}/rows/{rowId}":{"patch":{"operationId":"updateBlockPropertyRow","tags":["Blocks"],"summary":"Update a infobox property row","description":"Updates a row of the infobox property. Body is a RowPatchRequest: any of `key`, `content` and `text`. An empty body answers 400 VALIDATION_ERROR. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RowPatchRequest"}}}},"responses":{"200":{"description":"The row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Row"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteBlockPropertyRow","tags":["Blocks"],"summary":"Delete a infobox property row","description":"Removes the row from the infobox property. Responses carry the document `version` in the body and as `ETag`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"Row id"},"required":true,"name":"rowId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a keyValue container (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/properties":{"get":{"operationId":"listBlockProperties","tags":["Blocks"],"summary":"List an infobox's properties","description":"The infobox's rows as PropertyBlocks, sorted by rank. An infobox inside a secret answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. Responses carry the document `version` in the body and as `ETag`. An infobox property marked `isHidden` answers 404 NOT_FOUND to a caller who is not a project admin, and only a project admin may set or clear `isHidden` (otherwise 403 FORBIDDEN).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"}],"responses":{"200":{"description":"Properties","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockPropertyList"}}}},"400":{"description":"Not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not an infobox, or not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createBlockProperty","tags":["Blocks"],"summary":"Add a property to an infobox","description":"Adds a property to the infobox. Body is a PropertyCreateRequest, the same shape as createProperty. A duplicate id answers 409. Responses carry the document `version` in the body and as `ETag`. An infobox property marked `isHidden` answers 404 NOT_FOUND to a caller who is not a project admin, and only a project admin may set or clear `isHidden` (otherwise 403 FORBIDDEN).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyCreateRequest"}}}},"responses":{"201":{"description":"The property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedProperty"}}}},"400":{"description":"Validation error (VALIDATION_ERROR), unsupported kind (UNSUPPORTED_KIND) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Infobox or anchor not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/blocks/{blockId}/properties/{propertyId}":{"get":{"operationId":"getBlockProperty","tags":["Blocks"],"summary":"Get an infobox property","description":"The infobox row as a PropertyBlock. A block that is not an infobox answers 404 NOT_FOUND. An infobox inside a secret answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin. Responses carry the document `version` in the body and as `ETag`. An infobox property marked `isHidden` answers 404 NOT_FOUND to a caller who is not a project admin, and only a project admin may set or clear `isHidden` (otherwise 403 FORBIDDEN).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"}],"responses":{"200":{"description":"The property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedProperty"}}}},"400":{"description":"Not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateBlockProperty","tags":["Blocks"],"summary":"Update an infobox property","description":"Updates an infobox row. Body is a PropertyUpdateRequest. An empty body answers 400 VALIDATION_ERROR. Patching `rank` moves the row into rank order. Responses carry the document `version` in the body and as `ETag`. An infobox property marked `isHidden` answers 404 NOT_FOUND to a caller who is not a project admin, and only a project admin may set or clear `isHidden` (otherwise 403 FORBIDDEN).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PropertyUpdateRequest"}}}},"responses":{"200":{"description":"The property","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionedProperty"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteBlockProperty","tags":["Blocks"],"summary":"Remove an infobox property","description":"Removes the row from the infobox. Removing the last property leaves one empty row. Responses carry the document `version` in the body and as `ETag`. An infobox property marked `isHidden` answers 404 NOT_FOUND to a caller who is not a project admin, and only a project admin may set or clear `isHidden` (otherwise 403 FORBIDDEN).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Block id; run assignBlockIds first on legacy documents"},"required":true,"name":"blockId","in":"path"},{"schema":{"type":"string","description":"Infobox property id"},"required":true,"name":"propertyId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a page document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/lanes":{"get":{"operationId":"listLanes","tags":["Timelines"],"summary":"List a timeline's lanes","description":"Every lane of the timeline as a Lane (`id`, `name`, `rank`, `size`, `style`), including lanes of timelines the document chains as sources. The list is not paginated; order it by `rank`. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"responses":{"200":{"description":"The timeline's lanes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaneList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createLane","tags":["Timelines"],"summary":"Create a lane","description":"Creates a lane on the timeline. Body is LaneCreateParams. A document that is not a timeline (`time`) or `blank` answers 400 KIND_MISMATCH. A write to a `blank` document converts it to a time document and saves the content in the same request. The document is given the default calendar (`gregorian`) and no lanes other than the one created.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaneCreateParams"}}}},"responses":{"201":{"description":"The created lane","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lane"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED); duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/lanes/{laneId}":{"get":{"operationId":"getLane","tags":["Timelines"],"summary":"Get a lane","description":"The lane by id, from this document only; lanes of chained source timelines are not resolved here. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Lane ID"},"required":true,"name":"laneId","in":"path"}],"responses":{"200":{"description":"The lane","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lane"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateLane","tags":["Timelines"],"summary":"Update a lane","description":"Body is LaneUpdateParams. Only the fields sent change. A document that is not a timeline (`time`) or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Lane ID"},"required":true,"name":"laneId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaneUpdateParams"}}}},"responses":{"200":{"description":"The updated lane","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lane"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteLane","tags":["Timelines"],"summary":"Delete a lane","description":"Removes the lane and every event on it. A document that is not a timeline (`time`) or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Lane ID"},"required":true,"name":"laneId","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/events":{"get":{"operationId":"listEvents","tags":["Timelines"],"summary":"List a timeline's events","description":"A page of the timeline's events, including events of timelines the document chains as sources. Events are ordered by `start`, then by id, so events sharing a start time keep a stable order across pages. Pass `nextCursor` back as `cursor` for the next page. A caller who is not a project admin does not see hidden events. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","maxLength":2048,"description":"Pagination cursor from a previous `nextCursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size (1–100, default 50)."},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"A page of the timeline's events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventList"}}}},"400":{"description":"A cursor this endpoint did not issue, or a `limit` outside 1–100 (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createEvent","tags":["Timelines"],"summary":"Create an event","description":"Creates an event on a lane of the timeline. Body is EventCreateParams. The new event is given a `rank`. A document that is not a timeline (`time`) answers 400 KIND_MISMATCH. A `blank` document has no lanes for `laneId` to name; create a lane first, which converts it to a timeline.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventCreateParams"}}}},"responses":{"201":{"description":"The created event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED); duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/events/{eventId}":{"get":{"operationId":"getEvent","tags":["Timelines"],"summary":"Get an event","description":"The event by id, with `formattedStart` and `formattedEnd` rendered in the document's calendar. A hidden event answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"name":"eventId","in":"path"}],"responses":{"200":{"description":"The event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateEvent","tags":["Timelines"],"summary":"Update an event","description":"Body is EventUpdateParams. Only the fields sent change. A document that is not a timeline (`time`) answers 400 KIND_MISMATCH. A `blank` document has no lanes for `laneId` to name; create a lane first, which converts it to a timeline.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"name":"eventId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventUpdateParams"}}}},"responses":{"200":{"description":"The updated event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteEvent","tags":["Timelines"],"summary":"Delete an event","description":"Removes the event from its lane. A document that is not a timeline (`time`) answers 400 KIND_MISMATCH. A `blank` document has no lanes for `laneId` to name; create a lane first, which converts it to a timeline.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"name":"eventId","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a timeline document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/features":{"get":{"operationId":"listFeatures","tags":["Features"],"summary":"List a map's features","description":"Pins, labels, regions, paths and folders on a map document, each as a Feature. The list is not paginated. A caller who is not a project admin does not see hidden features. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","enum":["pin","label","region","path","folder"],"description":"Only return features of this type."},"required":false,"name":"type","in":"query"}],"responses":{"200":{"description":"The map's features","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureList"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createFeature","tags":["Features"],"summary":"Create a feature","description":"Creates a feature on the map. Body is FeatureCreateParams. A document that is not a map or `blank` answers 400 KIND_MISMATCH. A write to a `blank` document converts it to a map document and saves the content in the same request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureCreateParams"}}}},"responses":{"201":{"description":"The created feature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Feature"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a map document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED); duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/features/{featureId}":{"get":{"operationId":"getFeature","tags":["Features"],"summary":"Get a feature","description":"The feature by id. A hidden feature answers 404 NOT_FOUND to a caller who is not a project admin. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Feature ID"},"required":true,"name":"featureId","in":"path"}],"responses":{"200":{"description":"The feature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Feature"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateFeature","tags":["Features"],"summary":"Update a feature","description":"Body is FeatureUpdateParams. Only the fields sent change. A document that is not a map or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Feature ID"},"required":true,"name":"featureId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureUpdateParams"}}}},"responses":{"200":{"description":"The updated feature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Feature"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a map document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteFeature","tags":["Features"],"summary":"Delete a feature","description":"Removes the feature. Deleting a folder does not delete the features nested under it. A document that is not a map or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"Feature ID"},"required":true,"name":"featureId","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Not a map document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Document already deleted (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/board":{"get":{"operationId":"getBoardContent","tags":["Boards"],"summary":"Get a board's content","description":"Every page, shape, binding and asset record of the board, with the tldraw schema that writes are validated against. A document that is not a board or `blank` answers 400 KIND_MISMATCH. A `blank` document reads as an empty board and stays `blank`. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"}],"responses":{"200":{"description":"The board's content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardContent"}}}},"400":{"description":"Not a board document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"replaceBoardContent","tags":["Boards"],"summary":"Replace a board's content","description":"Body is BoardContentReplaceParams. Deletes every shape, binding and asset of the board and stores the ones sent, which are built as createBoardShapes builds them; pages are kept. Sending ids read from getBoardContent keeps them. The write is atomic: nothing is stored when any record fails validation. A document that is not a board or `blank` answers 400 KIND_MISMATCH. A write to a `blank` document converts it to a board document and saves the content in the same request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardContentReplaceParams"}}}},"responses":{"200":{"description":"The board's content after the write","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardContent"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a board document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/board/shapes":{"get":{"operationId":"listBoardShapes","tags":["Boards"],"summary":"List a board's shapes","description":"Every shape record of the board, ordered by `index`. The list is not paginated. A document that is not a board or `blank` answers 400 KIND_MISMATCH. A `blank` document reads as an empty board and stays `blank`. A hidden document, or a document of a resource the caller cannot reach, answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","maxLength":256,"description":"Only shapes on this page, at any depth. A `pageId` that names no page of the board answers 404 NOT_FOUND."},"required":false,"name":"pageId","in":"query"}],"responses":{"200":{"description":"The board's shapes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapeList"}}}},"400":{"description":"Not a board document (KIND_MISMATCH); validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createBoardShapes","tags":["Boards"],"summary":"Create shapes, bindings and assets","description":"Body is BoardShapesCreateParams. At least one record is required. Bindings and image shapes may name records created in the same request. An id that already exists on the board answers 409 DUPLICATE_ID. The write is atomic: nothing is stored when any record fails validation. A document that is not a board or `blank` answers 400 KIND_MISMATCH. A write to a `blank` document converts it to a board document and saves the content in the same request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesCreateParams"}}}},"responses":{"201":{"description":"The created records","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesCreated"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a board document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateBoardShapes","tags":["Boards"],"summary":"Update shapes","description":"Body is BoardShapesUpdateParams. A shape id that is not on the board answers 404 NOT_FOUND and changes nothing. The write is atomic: nothing is stored when any record fails validation. A document that is not a board or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesUpdateParams"}}}},"responses":{"200":{"description":"The updated shapes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesUpdated"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a board document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/resources/{resourceId}/docs/{documentId}/board/shapes/delete":{"post":{"operationId":"deleteBoardShapes","tags":["Boards"],"summary":"Delete shapes","description":"Body is BoardShapesDeleteParams. Deletes the shapes, every shape they contain, and every binding attached to a deleted shape, as the app does; assets are kept. A shape id that is not on the board answers 404 NOT_FOUND and deletes nothing. A document that is not a board or `blank` answers 400 KIND_MISMATCH.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Resource ID"},"required":true,"name":"resourceId","in":"path"},{"schema":{"type":"string","description":"Document ID"},"required":true,"name":"documentId","in":"path"},{"schema":{"type":"string","description":"A `version` from a previous response. The write fails with 412 when the document has changed since."},"required":false,"name":"if-match","in":"header"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesDeleteParams"}}}},"responses":{"200":{"description":"The deleted shape and binding ids","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardShapesDeleted"}}}},"400":{"description":"Validation error (VALIDATION_ERROR) or not a board document (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/assets":{"get":{"operationId":"listAssets","tags":["Assets"],"summary":"List assets","description":"A page of the assets (images, maps and folders) in one folder of the project's library: the root when `folderId` is omitted, else that folder's direct contents. Assets are ordered by id. Pass `nextCursor` back as `cursor` for the next page. A caller who is not a project admin does not see hidden assets.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","maxLength":2048,"description":"Pagination cursor from a previous `nextCursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size (1–100, default 50)."},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","maxLength":256,"description":"List a folder's contents (root if omitted)."},"required":false,"name":"folderId","in":"query"}],"responses":{"200":{"description":"A page of assets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetList"}}}},"400":{"description":"A cursor this endpoint did not issue, or a `limit` outside 1–100 (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createAssetFolder","tags":["Assets"],"summary":"Create an asset folder","description":"Creates a folder in the project's asset library. Body is AssetCreateParams. Images are created through createImageUpload and createImageAsset. Any member may create a folder.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetCreateParams"}}}},"responses":{"201":{"description":"The created folder","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Validation error, including a `folderId` that is not a folder in this project (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/assets/uploads":{"post":{"operationId":"createImageUpload","tags":["Assets"],"summary":"Create an image upload","description":"Step one of uploading an image. Body is ImageUploadCreateParams. The response carries a signed `uploadUrl`, the `headers` to send with it and an `uploadKey`. Send the file with `PUT` to `uploadUrl` before `expiresAt`, then call createImageAsset with the `uploadKey`. Any project member may call it.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageUploadCreateParams"}}}},"responses":{"200":{"description":"The signed upload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageUpload"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Storage quota reached (STORAGE_QUOTA_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED), or the daily upload budget is exhausted (UPLOAD_RATE_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/assets/images":{"post":{"operationId":"createImageAsset","tags":["Assets"],"summary":"Create an image asset","description":"Step two of uploading an image. Body is ImageAssetCreateParams. The server reads the stored file and records its real size, content type and pixel dimensions. A file past the project owner's storage quota answers 413 STORAGE_QUOTA_EXCEEDED and no asset is created. Any project member may call it.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageAssetCreateParams"}}}},"responses":{"201":{"description":"The created image asset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"400":{"description":"Validation error, including an unusable `uploadKey` or a `folderId` that is not a folder in this project (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Storage quota reached (STORAGE_QUOTA_EXCEEDED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/assets/{assetId}":{"get":{"operationId":"getAsset","tags":["Assets"],"summary":"Get an asset","description":"The asset by id. A hidden asset answers 404 NOT_FOUND to a caller who is not a project admin.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Asset ID"},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"The asset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Asset"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateAsset","tags":["Assets"],"summary":"Update an asset","description":"Body is AssetUpdateParams. Only the fields sent change and the response has no body. An empty body answers 400 VALIDATION_ERROR. A refused `folderId` changes no field. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Asset ID"},"required":true,"name":"assetId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetUpdateParams"}}}},"responses":{"204":{"description":"Updated"},"400":{"description":"Validation error, including a refused `folderId` (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteAsset","tags":["Assets"],"summary":"Delete an asset","description":"Deletes the asset. Deleting a folder deletes everything inside it at any depth. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Asset ID"},"required":true,"name":"assetId","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/members":{"get":{"operationId":"listMembers","tags":["Members"],"summary":"List project members","description":"Every member of the project as a Member (`id` is the user id) with their `role`: OWNER, ADMIN or MEMBER. Pending invites are not members; see listInvites. The list is not paginated.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"Members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"inviteMember","tags":["Members"],"summary":"Invite a member by email","description":"Body is MemberInviteParams. Creates a pending MEMBER invite that expires after 7 days and emails the address an accept link. An address that belongs to a member or has a pending invite answers `{ success: true }` with `alreadyMember` or `alreadyInvited`, sends no email and counts against no invite limit. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberInviteParams"}}}},"responses":{"200":{"description":"Invite result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteResult"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The project holds 100 unexpired pending invites; an invite that is revoked, accepted or expires frees a place (TOO_MANY_PENDING_INVITES); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"An invite limit or a key or project tier is exhausted (RATE_LIMITED). An invite that creates a pending invite counts against three limits: 50 an hour and 200 a day per project, and 200 a day per inviting user across projects. Past any of them, `Retry-After` gives the wait in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/members/{userId}":{"delete":{"operationId":"removeMember","tags":["Members"],"summary":"Remove a member","description":"Removes the user from the project. The caller may remove a member whose role ranks below their own (MEMBER < ADMIN < OWNER): the owner removes admins and members; an admin removes members. Any member other than the owner may remove themselves. Removing the owner, or a member of equal or higher rank, answers 403 FORBIDDEN.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"User ID"},"required":true,"name":"userId","in":"path"}],"responses":{"204":{"description":"Removed"},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The caller does not rank above the member and is not the member, or the target is the owner (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/invites":{"get":{"operationId":"listInvites","tags":["Invites"],"summary":"List a project's pending invites","description":"Every invite of the project whose status is pending, with the invited `email`, `role` and `expiresAt`. Accepted, declined and revoked invites are not listed. An invite past its `expiresAt` stays listed, and can be revoked, until someone tries to accept it. The list is not paginated. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"Pending invites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/invites/{inviteId}":{"delete":{"operationId":"revokeInvite","tags":["Invites"],"summary":"Revoke a pending invite","description":"Marks the invite revoked so its token can no longer be accepted. An invite past its `expiresAt` can still be revoked. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Invite ID"},"required":true,"name":"inviteId","in":"path"}],"responses":{"204":{"description":"Revoked"},"400":{"description":"The invite is not pending: it was accepted or declined (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already revoked (ALREADY_DELETED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/tags":{"get":{"operationId":"listTags","tags":["Tags"],"summary":"List the project's tags","description":"Every distinct tag on the project's resources, with the number of resources that carry it, ordered by `count` descending and then by `tag`. Resources in the trash are not counted. The list is not paginated. Requires the ADMIN role.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"Tags","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/search":{"get":{"operationId":"search","tags":["Search"],"summary":"Full-text search across resources","description":"Resources whose name, aliases or content match `q`, best match first. A resource can appear once per matching document. A caller who is not a project admin gets only resources they can reach and no matches from hidden documents, and a public caller only public content.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","maxLength":500,"description":"Search query. An empty or missing `q` answers an empty list."},"required":false,"description":"Search query. An empty or missing `q` answers an empty list.","name":"q","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Max results (default 32)."},"required":false,"description":"Max results (default 32).","name":"limit","in":"query"}],"responses":{"200":{"description":"Matching resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResultList"}}}},"400":{"description":"Validation error (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/calendars":{"get":{"operationId":"listCalendars","tags":["Calendars"],"summary":"List the project's calendars","description":"The project's custom calendars followed by the built-in calendars, each as a Calendar with its `version`. A timeline document names one of these by `calendarId`. The list is not paginated.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"Calendars","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarList"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createCalendar","tags":["Calendars"],"summary":"Create a calendar","description":"Creates a custom calendar in the project. Body is a CalendarSpec. The response is the Calendar with its `version`. Any project member may create a calendar.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9._-]{1,255}$","description":"Optional. 1–255 characters from `A-Z a-z 0-9 . _ -`. A repeat with the same key within 24 hours returns the first response instead of running the write again. See Idempotency."},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarSpec"}}}},"responses":{"201":{"description":"The created calendar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Calendar"}}}},"400":{"description":"Validation error naming the field (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate id (DUPLICATE_ID); a request with this `Idempotency-Key` is still in flight (IN_PROGRESS) or was for a different request (IDEMPOTENCY_KEY_REUSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}/calendars/{calendarId}":{"put":{"operationId":"updateCalendar","tags":["Calendars"],"summary":"Replace a calendar","description":"Body is a CalendarSpec that replaces the whole calendar; fields left out take their defaults or are removed. Timelines on the calendar keep their events, which are stored in minutes, and render them in the new calendar. A built-in calendar cannot be changed or deleted; create a copy with createCalendar instead. The response is the Calendar with its new `version`. Any project member may update a calendar.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Calendar ID"},"required":true,"name":"calendarId","in":"path"},{"schema":{"type":"string","description":"A calendar `version` from listCalendars, createCalendar or updateCalendar. The write fails with 412 when the calendar has changed since. Omitting it, or sending `*`, skips the version check."},"required":false,"name":"if-match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarSpec"}}}},"responses":{"200":{"description":"The updated calendar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Calendar"}}}},"400":{"description":"Validation error naming the field (VALIDATION_ERROR) or a built-in calendar (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Calendar not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The write would grow the document past its size limit (DOCUMENT_TOO_LARGE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteCalendar","tags":["Calendars"],"summary":"Delete a calendar","description":"Removes the calendar from the project. Timeline documents that name it keep their `calendarId` and their events; while the id names no calendar they render in the Gregorian calendar, and creating a calendar with that id again restores it. A built-in calendar cannot be changed or deleted; create a copy with createCalendar instead. Any project member may delete a calendar.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"},{"schema":{"type":"string","description":"Calendar ID"},"required":true,"name":"calendarId","in":"path"},{"schema":{"type":"string","description":"A calendar `version` from listCalendars, createCalendar or updateCalendar. The write fails with 412 when the calendar has changed since. Omitting it, or sending `*`, skips the version check."},"required":false,"name":"if-match","in":"header"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"A built-in calendar (KIND_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED), or the owner's plan does not allow the write, for a session (SUBSCRIPTION_LAPSED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Calendar not found (NOT_FOUND)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"412":{"description":"Version mismatch (VERSION_MISMATCH)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects":{"get":{"operationId":"listProjects","tags":["Projects"],"summary":"List your projects","description":"A page of the projects the caller is a member of, ordered by id. With an API key the page holds only the key's project. Pass `nextCursor` back as `cursor` for the next page.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","maxLength":2048,"description":"Pagination cursor from a previous `nextCursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size (1–100, default 50)."},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"A page of your projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectList"}}}},"400":{"description":"A cursor this endpoint did not issue, or a `limit` outside 1–100 (VALIDATION_ERROR)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v3/projects/{projectId}":{"get":{"operationId":"getProject","tags":["Projects"],"summary":"Get a project","description":"The project by id: `id`, `name`, `isPublic` and `createdAt`. A caller who is not a member answers 403 FORBIDDEN, the same as for a project that does not exist.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project ID","example":"proj_abc123"},"required":true,"name":"projectId","in":"path"}],"responses":{"200":{"description":"The project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"description":"Unauthenticated (UNAUTHENTICATED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The project owner is not on a paid plan, for an API key (PAID_PLAN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not a member, or no such project (FORBIDDEN); forbidden (FORBIDDEN, WRONG_PROJECT, INSUFFICIENT_SCOPE)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited (RATE_LIMITED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error (INTERNAL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{}}