{"openapi":"3.1.0","info":{"title":"Полка agent HTTP API","version":"0.17.0","summary":"Save a self-contained HTML page to the token owner's Полка shelf and get an unlisted link.","description":"Полка (Polka) keeps pages, reports and prototypes made with AI agents and gives an unlisted link to them. This API is for agents and scripts that do not speak MCP; MCP clients connect to https://polochka.app/mcp instead (see https://polochka.app/llms.txt). The human creates the token in the browser; never ask them to paste it into a chat. Errors are JSON {code, message}; message is Russian and meant for the human.","license":{"name":"AGPL-3.0-only","identifier":"AGPL-3.0-only"}},"externalDocs":{"description":"Agent guide (plain text)","url":"https://polochka.app/llms.txt"},"servers":[{"url":"https://polochka.app"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/publish":{"post":{"operationId":"publish","summary":"Save one HTML page and get a link","description":"Saves the page privately on the token owner's shelf and, when the token has the share scope, returns an unlisted link in the same call. Requires capture. Retry network errors, 429 and 5xx with the same key.","security":[{"bearerAuth":["capture"]}],"requestBody":{"required":true,"description":"JSON body, at most 8 MB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishRequest"},"examples":{"html":{"summary":"A static report with a 7-day link","value":{"key":"0b5f3a4e-3c2d-4f7a-9f55-6d1f0c9e8a21","title":"Quarterly report","html":"<!doctype html><html><head><meta charset=\"utf-8\"><title>Quarterly report</title><style>body{font-family:system-ui;margin:40px}</style></head><body><h1>Quarterly report</h1></body></html>","expiresInDays":7}}}}}},"responses":{"200":{"description":"Saved. state tells whether a link was issued; check moderation before presenting the link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResponse"},"examples":{"shared":{"value":{"artifactId":"5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","revisionId":"9a1e3f0b-6c1d-4e0a-8f4b-3b9d2e7c5a10","state":"shared","url":"https://polochka.app/s#Q2x1ZS1zaGFyZS10b2tlbi1leGFtcGxlLW5vdC1yZWFs","expiresAt":"2026-09-30T12:00:00.000Z","shelfUrl":"https://polochka.app/works/5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","interactiveReady":false,"scriptsRunForRecipients":false}},"held":{"summary":"The link waits for a moderator","value":{"artifactId":"5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","revisionId":"9a1e3f0b-6c1d-4e0a-8f4b-3b9d2e7c5a10","state":"shared","url":"https://polochka.app/s#Q2x1ZS1zaGFyZS10b2tlbi1leGFtcGxlLW5vdC1yZWFs","expiresAt":"2026-09-30T12:00:00.000Z","shelfUrl":"https://polochka.app/works/5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","interactiveReady":false,"scriptsRunForRecipients":false,"moderation":"held","moderationMessage":"Ссылка создана, но пока на проверке у модератора Полки: получатели увидят работу после одобрения.","expiresNote":"Ссылка выдана на 7 дней вместо 30: новым аккаунтам Полки ссылки выдаются не дольше чем на 7 дней."}},"saved":{"summary":"Saved privately: the token has no share scope","value":{"artifactId":"5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","revisionId":"9a1e3f0b-6c1d-4e0a-8f4b-3b9d2e7c5a10","state":"saved","url":null,"expiresAt":null,"shelfUrl":"https://polochka.app/works/5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11","interactiveReady":false,"scriptsRunForRecipients":false,"linkUnavailableReason":"Saved privately. This connection was not granted the link permission (Управлять ссылками); the owner can share it from the shelf or reconnect with that permission."}}}}}},"400":{"description":"Fields failed validation (the message names them), invalid UTF-8, or html longer than 7,000,000 characters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"fields":{"value":{"code":"invalid","message":"Проверьте поля запроса: key, title."}}}}}},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"The token lacks the scope, or the request came from a browser page on another origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"scope":{"value":{"code":"forbidden","message":"У подключения нет разрешения для этого действия."}}}}}},"409":{"description":"The same key was already used for different content.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"key":{"value":{"code":"conflict","message":"Ключ уже относится к другой операции."}}}}}},"413":{"description":"The page is larger than 5 MB, the body larger than 8 MB, or the shelf is out of space.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"size":{"value":{"code":"quota","message":"Страница больше 5 МБ. Уменьшите её: уберите встроенные шрифты и крупные картинки."}}}}}},"422":{"description":"Not HTML, contains NUL, or component was sent where the installation does not run scripts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"component":{"value":{"code":"unsupported","message":"Здесь скрипты не запускаются: пришлите статичный HTML-снимок того, что показывает компонент, в поле html."}}}}}},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}},"503":{"description":"The request collided with another action on the same works; nothing was committed. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"busy":{"value":{"code":"busy","message":"Полка сейчас занята другим действием с этими работами. Повторите через несколько секунд."}}}}}}}}},"/api/v1/sign-in-link":{"post":{"operationId":"signInLink","summary":"A one-time link that signs the owner's browser in","description":"When the owner asks to open Полка in a browser («Открой мою Полку»). For a claimed shelf returns kind hint: url = <origin>/signin?shelf=… (no secret), the shelf's sign-in page. For a provisional shelf returns kind link: url = <origin>/enter#<token>, one use within 5 minutes after the user confirms — only for an OAuth connection granted the sign_in permission. Give the url to the user exactly as returned and never open it yourself. At most 5 per connection per hour.","security":[{"bearerAuth":["context"]}],"responses":{"200":{"description":"The link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInLinkResponse"}}}},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"A provisional shelf and a connection without the sign_in permission (or a static token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"token":{"value":{"code":"forbidden","message":"Ссылки для входа выдают только агенты, подключённые через OAuth (Claude, ChatGPT, Codex). Для этого подключения откройте Полку в браузере и войдите."}}}}}},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/status/{artifactId}":{"get":{"operationId":"status","summary":"Metadata of one saved work","description":"Title, folder, ownerAccountId, acceptedRevisionId (the version a curator accepted, or null), latest revision, HTML profile, interactive build state and trash state, with shelfUrl. No bytes and no share links. A token without the read scope sees only works saved through its own connection.","security":[{"bearerAuth":["context"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"string","maxLength":2048,"pattern":"\\/works\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)"}],"description":"The work's id, or the address of its page on the owner's shelf (<origin>/works/<id>) as the owner pastes it."},"example":"5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11"}],"responses":{"200":{"description":"The work.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"400":{"description":"artifactId is not a UUID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"id":{"value":{"code":"invalid","message":"Проверьте поля запроса: artifactId."}}}}}},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"The token lacks the scope, or the request came from a browser page on another origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"scope":{"value":{"code":"forbidden","message":"У подключения нет разрешения для этого действия."}}}}}},"404":{"description":"No such work, or it is not visible to this token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"not_found","message":"Материал недоступен. Ссылка могла измениться или доступ был закрыт."}}}}}},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}},"503":{"description":"The request collided with another action on the same works; nothing was committed. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"busy":{"value":{"code":"busy","message":"Полка сейчас занята другим действием с этими работами. Повторите через несколько секунд."}}}}}}}}},"/api/v1/works/{artifactId}/edits":{"post":{"operationId":"editWork","summary":"Patch the text of a saved work","description":"Saves a new version of the work by replacing text in its latest version: each edit's oldText must occur exactly once in the file (first exactly, then after normalization: NFKC per character, typographic quotes and dashes, special spaces, trailing whitespace of lines); only the matched spans change. Requires revise. With moveLink (and the share scope) the work's open link, and the reader comments on it, move to the new version. Read the comments with the MCP tool polka_comments. Retry network errors, 429 and 5xx with the same key.","security":[{"bearerAuth":["revise"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"string","maxLength":2048,"pattern":"\\/works\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:[/?#]|$)"}],"description":"The work's id, or the address of its page on the owner's shelf (<origin>/works/<id>) as the owner pastes it."},"example":"5d0c7a61-8a52-4b7e-9d0e-2f7b1b7f4c11"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditsRequest"},"examples":{"typo":{"summary":"Fix a sentence a reader commented on","value":{"key":"7c1e9a52-0f3b-4d6e-8a21-5b9f0c2d7e44","baseRevisionId":"9a1e3f0b-6c1d-4e0a-8f4b-3b9d2e7c5a10","edits":[{"oldText":"Выручка выросла на 12%.","newText":"Выручка выросла на 14%."}],"moveLink":true}}}}}},"responses":{"200":{"description":"Saved as a new version. link says whether the open link now shows it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditsResponse"}}}},"400":{"description":"Fields failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"fields":{"value":{"code":"invalid","message":"Проверьте поля запроса: edits."}}}}}},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"The token lacks the scope, or the request came from a browser page on another origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"scope":{"value":{"code":"forbidden","message":"У подключения нет разрешения для этого действия."}}}}}},"404":{"description":"No such work or file, or it is in the trash.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"not_found","message":"Материал недоступен. Ссылка могла измениться или доступ был закрыт."}}}}}},"409":{"description":"baseRevisionId is not the latest version: currentRevisionId names it. Read it and send the edits again. (The same key with a different body is also 409, without currentRevisionId.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseMismatch"}}}},"422":{"description":"An edit cannot be applied: editIndex names it (0-based) and reason says why (not_found, ambiguous, overlap with otherEditIndex, empty_old_text, no_change). Add surrounding text to oldText and retry with a new key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditProblem"}}}},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}},"503":{"description":"The request collided with another action on the same works; nothing was committed. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"busy":{"value":{"code":"busy","message":"Полка сейчас занята другим действием с этими работами. Повторите через несколько секунд."}}}}}}}}},"/api/v1/projects":{"post":{"operationId":"beginProject","summary":"Begin saving a folder of linked pages as one project","description":"Body: {key, title, manifest, folderId?, artifactId?, baseRevisionId?}. The manifest lists every file (path, mime, size, sha256) with runtime project-v1 and entrypoint README.md, index.md or index.html: up to 400 files, 48 MB in all, each file up to 5 MB; Markdown, HTML, CSS, JavaScript, JSON, SVG, PNG, JPEG, WebP, GIF, WOFF2 and text. Video (video/mp4, video/webm) may be up to 200 MB a file and 400 MB in all, on top of the 48 MB, on a shelf that has video enabled (403 otherwise); send it to …/media/{index}. Returns uploadId and the index of each path; a repeated key returns the same upload. Scope capture, or revise with artifactId and baseRevisionId for a new version. The ready-made client is GET /api/v1/cli/polka-publish-project.mjs.","security":[{"bearerAuth":["capture"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The upload: uploadId, receipt (when already saved) and files [{index, path}]."},"400":{"description":"The manifest or a field is invalid."},"413":{"description":"The shelf is out of space or has too many uploads in progress."}}}},"/api/v1/projects/{uploadId}/files/{index}":{"put":{"operationId":"putProjectFile","summary":"Send one file of a project","description":"The bytes of the file at this index, as application/octet-stream. Size and SHA-256 must match the manifest. Project files have their own rate limit per token (twice the file limit per 10 minutes).","security":[{"bearerAuth":["capture"]}],"parameters":[{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"index","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":399}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Stored."},"404":{"description":"No such upload for this token."}}}},"/api/v1/projects/{uploadId}/media/{index}":{"put":{"operationId":"putProjectMedia","summary":"Send one video file of a project as a stream","description":"The bytes of a video/mp4 or video/webm file at this index, as application/octet-stream with a Content-Length. The store receives them as they arrive, so a file of up to 200 MB is fine; size and SHA-256 must match the manifest, the first bytes must be an MP4 or WebM header, and nothing is stored otherwise (422). Safe to repeat.","security":[{"bearerAuth":["capture"]}],"parameters":[{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"index","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":399}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Stored."},"404":{"description":"No such upload for this token."},"411":{"description":"No Content-Length."},"415":{"description":"The file at this index is not a video: send it to …/files/{index}."},"422":{"description":"The bytes are not the file the manifest names, or not a video."}}}},"/api/v1/projects/{uploadId}/reuse":{"post":{"operationId":"reuseProjectFiles","summary":"Keep the unchanged files of a new project version without sending them","description":"For an upload begun with artifactId and baseRevisionId: every file whose path, mime, size and SHA-256 are those of a file in the base version is copied inside the store. Returns reused [index]; send only the other files. Safe to repeat.","security":[{"bearerAuth":["revise"]}],"parameters":[{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"reused: the indexes now stored."},"404":{"description":"No such upload for this token."}}}},"/api/v1/task-token":{"post":{"operationId":"createTaskToken","summary":"A short token for one job (service accounts)","description":"Only a service account's own token may ask (SERVICE_ACCOUNTS=on). Body: {scopes? a subset of its own, minutes 5–60 (default 15), taskId?}. Returns {token, expiresAt, scopes, taskId?}: a child of the service token that stops when the parent does, and cannot ask for another. Each issue is audited with the service account and taskId.","security":[{"bearerAuth":["context"]}],"responses":{"200":{"description":"The task token, shown once."},"400":{"description":"A field is invalid."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"Not a service account, or more scopes than its own."},"404":{"description":"Service accounts are off on this installation."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/events":{"get":{"operationId":"listEvents","summary":"What happened to the works of the token's shelf","description":"A feed to poll, oldest first. Without after it returns no events and nextCursor, the current end of the feed; keep that cursor and pass it back as after. after=0 reads the shelf's history from the start. Events: revision.saved, revision.accepted, owner.changed, artifact.metadata_updated, artifact.moved, artifact.trashed, artifact.restored, each {id, action, artifactId, revisionId?, actorType human|agent, at}. An event appears once its transaction and every older one have committed, so a cursor never skips one. Event ids and cursors are opaque strings. No content of a work and no share links. A token limited to folders sees only their works. Scope read.","security":[{"bearerAuth":["read"]}],"parameters":[{"name":"after","in":"query","required":false,"schema":{"type":"string","pattern":"^(0|[0-9]{1,20}:[0-9]{1,18})$"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"events, nextCursor and more (another page waits)."},"400":{"description":"A parameter is invalid."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"404":{"description":"The token has no read scope."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/snapshot":{"get":{"operationId":"shelfSnapshot","summary":"The shelf as it stood at a moment","description":"at (ISO 8601 with a zone, not in the future), limit 1–100 (default 50), cursor (nextCursor of the previous page). Returns the works that existed and were not in the trash then, each with the version that was latest then (revision) and the version accepted then (acceptedRevisionId); null means none had been accepted by then. Moves to and from the trash come from the journal. Title and folder are the current ones; encode a «+» offset as %2B or use Z; a moment in the last minute may still change. No bytes, no share links. Scope read.","security":[{"bearerAuth":["read"]}],"parameters":[{"name":"at","in":"query","required":true,"schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"items and nextCursor."},"400":{"description":"A parameter is invalid, or at is in the future."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"404":{"description":"The token has no read scope."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/works":{"get":{"operationId":"listWorks","summary":"List and search the works on the token's shelf","description":"Newest first. query searches titles and the text of the latest version; since (ISO 8601 with a zone) returns only works changed after that moment; limit is 1–100 (default 25); state is active or trashed. Returns items [{id, title, kind, folderId, revision, snippet?}] and nextCursor to pass back as cursor. No bytes and no share links. Scope read.","security":[{"bearerAuth":["read"]}],"parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","maxLength":160}},{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"folderId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["active","trashed"]}},{"name":"shelfIds","in":"query","required":false,"schema":{"type":"string"},"description":"Search these shelves too, comma-separated: your own and department shelves the owner allowed this token at issue (allowedShelfIds). Active works only; every item says its shelfId."}],"responses":{"200":{"description":"A page of works and nextCursor."},"400":{"description":"A parameter is invalid."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"404":{"description":"The token has no read scope."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/works/{artifactId}":{"get":{"operationId":"getWork","summary":"One work of the shelf with its versions","description":"Metadata as in listWorks (shelfId, acceptedRevisionId, ownerAccountId) plus revisions: [{id, number, filename, mime, size, totalSize, createdAt, accepted}], newest first, up to 100. No bytes and no share links. Scope read.","security":[{"bearerAuth":["read"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The work and its versions."},"400":{"description":"artifactId is not valid."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"404":{"description":"No such work on this token's shelf, or no read scope."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/works/{artifactId}/file":{"get":{"operationId":"readWorkFile","summary":"One file of a version by its path","description":"path (required) and revisionId (the latest by default). Text as UTF-8, anything else as base64, with mime, size and sha256; at most 256 KiB (larger files and videos: the per-index download or polka pull). Scope source:read.","security":[{"bearerAuth":["source:read"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"revisionId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The file."},"404":{"description":"No such work, version or path for this token."},"413":{"description":"The file is larger than 256 KiB."}}}},"/api/v1/works/{artifactId}/changes":{"post":{"operationId":"changeWorkFiles","summary":"Save the next version with files added, replaced or removed","description":"Body {key, baseRevisionId, put: [{path, encoding: utf8|base64, data}], remove: [path]}. The type of a put file comes from its extension; every other file of the base version is copied by the server; the entrypoint cannot be removed; only for a project work (runtime project-v1): a page or a bundle is refused (use the edits or publish routes). A different latest version returns 409 with currentRevisionId; the same key and body return the same version. A link does not move. Scope revise.","security":[{"bearerAuth":["revise"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"artifactId, revisionId, number, htmlProfile, shelfUrl."},"400":{"description":"A field is invalid, a path is doubled or collides."},"404":{"description":"No such work, version or path for this token."},"409":{"description":"The base is not the latest version."},"422":{"description":"The entrypoint removal, a work that is not a project, or an unknown file type."}}}},"/api/v1/works/{artifactId}/files":{"get":{"operationId":"listWorkFiles","summary":"List the files of a saved version (polka pull)","description":"The latest version by default, or ?revisionId=. Returns title, revisionId, number, latestRevisionId, runtime, entrypoint and files [{index, path, mime, size, sha256}]. Scope source:read. The ready-made client is GET /api/v1/cli/polka-pull.mjs.","security":[{"bearerAuth":["source:read"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"revisionId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The version and its files."},"404":{"description":"No such work or version for this token."}}}},"/api/v1/works/{artifactId}/revisions/{revisionId}/files/{index}":{"get":{"operationId":"getWorkFile","summary":"Download one file of a saved version","description":"The file's bytes as application/octet-stream; X-Polka-Sha256 is its SHA-256. Scope source:read.","security":[{"bearerAuth":["source:read"]}],"parameters":[{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"revisionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"index","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":399}}],"responses":{"200":{"description":"The bytes."},"410":{"description":"Blocked or deleted by moderation."}}}},"/api/v1/cli/polka-pull.mjs":{"get":{"operationId":"downloadPullCli","summary":"Download the dependency-free pull CLI","description":"A single-file Node 22+ script that downloads a version of a work into a folder and records it in .polka.json, so polka-publish-project.mjs of that folder saves the next version and sends only changed files. It reads the token only from POLKA_TOKEN.","security":[],"responses":{"200":{"description":"The script, pointed at this installation.","content":{"text/javascript":{"schema":{"type":"string"}}}}}}},"/api/v1/export":{"get":{"operationId":"exportShelf","summary":"The whole personal shelf, for another installation","description":"Pages of the inventory (docs/specs/SHELF_TRANSFER.md): format polka-shelf-export/1, source {origin, shelfId, accountEmail, polkaVersion}, shelf {cardMd, folders}, items [{id, title, folderId, updatedAt, trashedAt, ownerIsSelf, acceptedRevisionId, acceptedAt, revisions [{id, number, createdAt, filename, mime, size, sha256, totalSize, storageKind, manifest, manifestSha256, unavailable, files [{index, path, mime, size, sha256}]}]}] and nextCursor. Every version of every work, the trash included; limit 1–50 works (default 50), fewer when a page reaches 1000 versions. No share links, no comments. Scopes read and source:read, the whole personal shelf (a token limited to folders is refused). The ready-made client is GET /api/v1/cli/polka-export.mjs.","security":[{"bearerAuth":["read","source:read"]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"A page of the inventory and nextCursor (null on the last page)."},"400":{"description":"A parameter is invalid."},"401":{"description":"No Authorization header, or the token is wrong, expired or revoked. The WWW-Authenticate header says Bearer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"missing":{"value":{"code":"unauthorized","message":"Нужен заголовок Authorization: Bearer <токен агента>."}}}}},"headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"polka\", error=\"invalid_token\""}}},"403":{"description":"A scope is missing, the token is limited to folders, or the shelf is not a personal one."},"429":{"description":"Rate limit: 120 requests per token and 300 per IP address in 10 minutes. Retry with the same key after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"rate":{"value":{"code":"quota","message":"Слишком много попыток. Попробуйте через 10 минут."}}}}},"headers":{"Retry-After":{"description":"Seconds until the limit window resets.","schema":{"type":"integer","minimum":1}}}}}}},"/api/v1/export/revisions/{revisionId}/files/{index}":{"get":{"operationId":"exportShelfFile","summary":"Download one file of any version of the shelf","description":"The file's bytes as application/octet-stream; X-Polka-Sha256 is its SHA-256. Works in the trash too. Counted apart from the other calls. Scopes read and source:read.","security":[{"bearerAuth":["read","source:read"]}],"parameters":[{"name":"revisionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"index","in":"path","required":true,"schema":{"type":"integer","minimum":0,"maximum":399}}],"responses":{"200":{"description":"The bytes."},"403":{"description":"As for exportShelf."},"404":{"description":"No such version or file on this shelf."},"410":{"description":"Blocked or deleted by moderation."}}}},"/api/v1/cli/polka-sessions.mjs":{"get":{"operationId":"downloadSessionsCli","summary":"Download the dependency-free agent sessions CLI","description":"A single-file Node 22+ script that sends the person's Claude Code and Codex sessions to their personal shelf (docs/specs/AGENT_SESSIONS.md): secrets are replaced on the machine, the server gets a session index, a secrets report (type, keyed fingerprint, where) and a shortened transcript. It reads the token only from POLKA_TOKEN or the file its login command writes (mode 600); the token needs the sessions scope.","security":[],"responses":{"200":{"description":"The script, pointed at this installation.","content":{"text/javascript":{"schema":{"type":"string"}}}}}}},"/api/v1/cli/polka-export.mjs":{"get":{"operationId":"downloadExportCli","summary":"Download the dependency-free shelf export CLI","description":"A single-file Node 22+ script that writes the whole personal shelf into a folder (polka-export.json and blobs/<sha256>), resumable; scripts/shelf-import.ts on another installation reads it. It reads the token only from POLKA_TOKEN.","security":[],"responses":{"200":{"description":"The script, pointed at this installation.","content":{"text/javascript":{"schema":{"type":"string"}}}}}}},"/api/v1/projects/{uploadId}/finalize":{"post":{"operationId":"finalizeProject","summary":"Save the project once every file is sent","description":"Saves one version of the project and returns its receipt with shelfUrl. Every page, document and script is screened and indexed for search.","security":[{"bearerAuth":["capture"]}],"parameters":[{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The receipt: artifactId, revisionId, number, shelfUrl."},"409":{"description":"A file is missing, or a newer version appeared since baseRevisionId."}}}},"/api/v1/cli/polka-publish-project.mjs":{"get":{"operationId":"downloadProjectCli","summary":"Download the dependency-free project CLI","description":"A single-file Node 22+ script that publishes a folder as one project on this installation. It reads the token only from POLKA_TOKEN; --dry-run lists what would be sent and skipped.","security":[],"responses":{"200":{"description":"The script, pointed at this installation.","content":{"text/javascript":{"schema":{"type":"string"}}}}}}},"/api/v1/cli/polka-publish.mjs":{"get":{"operationId":"downloadCli","summary":"Download the dependency-free CLI","description":"A single-file Node 22+ script that calls POST /api/v1/publish on this installation. It reads the token only from POLKA_TOKEN.","security":[],"responses":{"200":{"description":"The script, pointed at this installation.","content":{"text/javascript":{"schema":{"type":"string"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An agent token of the shelf owner: created by the human at https://polochka.app/settings/agents (section «Для разработчиков», shown once), or the OAuth access token of an MCP connection (audience https://polochka.app/mcp). Send it only in this header; keep it in an environment variable, never in a chat, command line or log. Scopes: context, read, source:read, capture, revise, share, manage, sign_in, sessions. publish needs capture; the link needs share."}},"schemas":{"PublishRequest":{"type":"object","properties":{"key":{"description":"Idempotency key: a fresh UUID per artifact. Reuse it only to retry the same request; the retry returns the same work and the same link. The same key with a different body is 409.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"description":"Title on the owner's shelf.","type":"string","minLength":1,"maxLength":160},"html":{"description":"One self-contained HTML document, at most 5 MB in UTF-8: CSS in <style>, images and fonts as data: URIs, no external URLs (the viewer has no network). Send exactly one of html and component.","type":"string","minLength":1,"maxLength":7000000},"component":{"description":"React component source as-is (default export rendered full-page). Only where the installation runs scripts; otherwise 422 unsupported.","type":"string","minLength":1,"maxLength":7000000},"componentLanguage":{"description":"Only with component. Default jsx.","type":"string","enum":["jsx","tsx"]},"folderId":{"description":"Optional folder on the shelf.","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"artifactId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"baseRevisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expiresInDays":{"description":"Link lifetime. A new account gets at most 7 days: 30 becomes 7 and expiresNote says so.","default":30,"anyOf":[{"type":"number","const":1},{"type":"number","const":7},{"type":"number","const":30}]}},"required":["key","title"],"additionalProperties":false,"description":"Send exactly one of html and component."},"PublishResponse":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"revisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"state":{"description":"shared: url is a live link. saved: the work is saved privately and url is null; linkUnavailableReason says why.","type":"string","enum":["shared","saved"]},"url":{"description":"The unlisted link (…/s#…) to give the human. Anyone with it can open the work until it expires or is revoked.","anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"expiresAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"shelfUrl":{"description":"The work on the owner's shelf. Opens only for the signed-in owner; not a share link.","type":"string","format":"uri"},"interactiveReady":{"type":"boolean"},"scriptsRunForRecipients":{"type":"boolean"},"moderation":{"description":"Present only while the link waits for a Полка moderator: recipients see a review screen until approval. Relay moderationMessage to the human; do not present the link as ready.","type":"string","enum":["held","paused","blocked"]},"moderationMessage":{"type":"string"},"expiresNote":{"description":"The link was issued for fewer days than requested (new account).","type":"string"},"linkMoved":{"type":"boolean"},"linkUnavailableReason":{"type":"string"},"interactiveUnavailableReason":{"type":"string"},"claimUrl":{"type":"string","format":"uri"}},"required":["artifactId","revisionId","state","url","expiresAt","shelfUrl","interactiveReady","scriptsRunForRecipients"],"additionalProperties":false},"StatusResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string"},"kind":{"type":"string","enum":["page","link","image","text","file"]},"linkHost":{"type":"string"},"folderId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"folderName":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"updatedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"trashedAt":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},{"type":"null"}]},"lifecycleVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"shelfId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"ownerAccountId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"acceptedRevisionId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"revision":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"filename":{"type":"string"},"mime":{"type":"string"},"size":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalSize":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"storageKind":{"type":"string","enum":["single","bundle"]},"htmlProfile":{"anyOf":[{"type":"string","enum":["static","limited","unsupported"]},{"type":"null"}]},"inlineBuild":{"anyOf":[{"type":"object","properties":{"state":{"type":"string","enum":["pending","ready","unsupported","failed"]},"runtimeProfile":{"type":["string","null"]}},"required":["state","runtimeProfile"],"additionalProperties":false},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"}},"required":["id","number","filename","mime","size","totalSize","storageKind","htmlProfile","inlineBuild","createdAt"],"additionalProperties":false},"shelfUrl":{"type":"string","format":"uri"}},"required":["id","title","kind","folderId","folderName","createdAt","updatedAt","trashedAt","lifecycleVersion","shelfId","ownerAccountId","acceptedRevisionId","revision","shelfUrl"],"additionalProperties":false},"SignInLinkResponse":{"type":"object","properties":{"kind":{"type":"string","enum":["hint","link"]},"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"expiresInSeconds":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"instructions":{"type":"string"}},"required":["kind","url","expiresAt","expiresInSeconds","instructions"],"additionalProperties":false},"EditsRequest":{"type":"object","properties":{"key":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"baseRevisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"edits":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"oldText":{"type":"string","maxLength":1000000},"newText":{"type":"string","maxLength":1000000}},"required":["oldText","newText"],"additionalProperties":false}},"path":{"type":"string","minLength":1,"maxLength":200},"moveLink":{"default":false,"type":"boolean"}},"required":["key","baseRevisionId","edits"],"additionalProperties":false},"EditsResponse":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"previousRevisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"revisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"htmlProfile":{"anyOf":[{"type":"string","enum":["static","limited","unsupported"]},{"type":"null"}]},"shelfUrl":{"type":"string","format":"uri"},"interactiveReady":{"type":"boolean"},"interactiveUnavailableReason":{"type":"string"},"link":{"type":"object","properties":{"moved":{"type":"boolean"},"reason":{"type":"string"},"shareId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"artifactId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"revisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"derivativeId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"},"state":{"type":"string","enum":["active","closed"]},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"moderation":{"type":"string","enum":["held","paused","blocked"]},"moderationMessage":{"type":"string"}},"required":["moved"],"additionalProperties":false}},"required":["artifactId","previousRevisionId","revisionId","number","htmlProfile","shelfUrl"],"additionalProperties":false},"EditProblem":{"type":"object","properties":{"code":{"type":"string","const":"edit_failed"},"message":{"type":"string"},"editIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"otherEditIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"reason":{"type":"string","enum":["empty_old_text","not_found","ambiguous","overlap","no_change"]},"occurrences":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","editIndex","reason"],"additionalProperties":false},"BaseMismatch":{"type":"object","properties":{"code":{"type":"string","const":"conflict"},"message":{"type":"string"},"currentRevisionId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["code","message","currentRevisionId"],"additionalProperties":false},"Problem":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}}}}