Playbook
Server Details
Media backend: search, organize, upload, and share creative files and folders
TDQS
Scored across 76 tools
Most tools target a distinct resource+action and the descriptions go out of their way to say when to prefer one over another (ai_search vs search_assets, publish_board vs share_board vs deploy_app, get_asset vs get_assets, the three upload routes). The main confusion comes from deliberate single/batch pairs (create_upload_url/create_upload_urls, finish_upload/finish_uploads, upload_from_url/upload_from_urls, add_page_element/apply_page_operations), which are explainable but still mean near-duplicate tools sitting side by side. Board/collection terminology drift (params named collection_token for boards) adds minor friction.
Nearly all names are snake_case verb_noun (list_assets, create_board, delete_custom_field, update_page_element, archive_assets), with a predictable single/batch pluralization pattern. A few deviations (ai_search, preview_app, resolve_share_link) and the inconsistent 'board' vs 'collection' vocabulary keep it from a perfect score.
76 tools is well past the point where an agent can hold the surface in view, and several tools exist only as batch aliases of others, which inflates the count beyond the domain's real needs. The scope is genuinely broad (assets, boards, pages, apps, imports, versions, sharing), which prevents a 1, but this is a heavy surface for one MCP server.
Coverage is unusually thorough: full asset lifecycle (upload via three routes, versions, revert, archive, group, tags, approval, status), boards and hierarchy, sharing/publishing, page layout design, hosted apps with versioning, imports, and docs. Remaining gaps are modest — no comment edit/delete, no asset-version deletion, no explicit unpublish/unshare — and workarounds or omissions are low-impact.
Publisher details
- Operator
- Playbook Digital, Inc. · Publisher source
- Operator website
- https://www.playbook.com
- Vendor relationship
- Not applicable
- Documentation
- https://dev.playbook.com/docs/guides/mcp/ · Publisher source
- Trust center
- Not applicable
- Restrictions
- Requires a Playbook account. Sign in through the browser (OAuth) or pass a Playbook API token as a Bearer header; no custom OAuth app or admin approval. Rate limit: 120 requests per 60 seconds. · Publisher source
Available Tools
76 toolsadd_asset_permalinksAdd asset permalinksAInspect
Give assets a permalink: a permanent, PUBLIC URL that needs no login and never expires, unlike the signed display_url, which dies at the end of the next day. Use it when a URL has to keep working — an external site, a deck, a doc, a hand-off to another system. Publishing is the point: the file is copied to a public bucket and anyone holding the URL can fetch it, so a sensitive file becomes public. It serves files, not web pages: an HTML file behind a permalink is sandboxed and its scripts never run, so never use it to host a page or app — deploy_app is for that. The copy runs in the background. This call waits up to about 20 seconds for it and returns the finished URLs under created; anything still copying comes back under pending with no URL. Read those with get_asset_permalinks shortly after — never publish them again; a URL does not work until it is reported there. A large video can take minutes. Assets that already have one are left untouched and are NOT in created — they are listed under already_had_permalink; read their URL with get_asset_permalinks. Assets that all already have one publish nothing and come back listed under already_had_permalink, not as a failure. A permalink only exists for real uploaded files: a link asset, a note, a colour swatch, or an upload still ingesting (is_skeleton: true) is listed under no_file_to_publish and nothing is created — poll get_asset until the upload finishes before asking. failed_to_publish means the file could not be copied at all and the permalink was withdrawn; retrying will not help. Capped per plan (10 Free, 100 on trials, 1,000 Pro, 5,000 Team/Business); going over returns 422 and publishes NOTHING — the whole batch is refused, not the overflow, and the count is taken before the unpublishable assets are skipped, so near the cap send only real files. If the call fails partway, the response still reports what was published or queued plus a remaining list — call again with exactly that list, never with the original one. Send the whole set in one call, up to 200 tokens. The response reports quota after the writes, and list_organizations reports the same headroom without publishing anything, so check it there before a batch you are not sure fits. Requires write scope and update permission on every asset; one unknown token fails the whole call.
Inputs: asset_tokens (required), organization.
add_page_elementAdd page elementAInspect
Insert one element into a slot of a board's published page, or into a column of a section element when parent_element_id is given. Returns the slot as it now stands plus element_id. Supply element.id yourself: re-sending the same add then converges (200, nothing inserted), while the same id with DIFFERENT content is 409 element_exists — pick another id or use update_page_element. Props that carry HTML or a URL must be strings. An asset_token prop takes a token from list_assets; the server copies that asset into the page's library and stores the copy's token. To add several elements, or a section plus its contents, prefer apply_page_operations (atomic). Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), element (required), slot_id (required), at_index (required), +7 more.
ai_searchAI searchARead-onlyInspect
AI-powered visual search for assets in a Playbook workspace. Understands what is depicted inside assets — colors, subjects, scenes, objects, and compositions. Use this when the user describes visual content: 'ocean waves in blue', 'product shots on white background', 'videos with people outdoors'. Works regardless of filename or tags. Prefer this over search_assets for any content-descriptive query. Scope it to a board with collection_token (plus nested_assets for a parent board) — unscoped it searches the whole workspace, which for a moodboard, pitch reel or client hand-off returns mostly assets from other projects. Also filters by uploader and by date range. To find what a PERSON uploaded, call list_members to resolve their name to a token, then pass that token as uploaded_by. Putting a person's name in query does NOT match the person who uploaded an asset — it searches the asset's own text and will return unrelated files.
Inputs: query (required), fields, date_to, statuses, +9 more.
apply_page_operationsApply page operationsADestructiveInspect
Apply up to 50 page edits to a board's published page in order and ATOMICALLY — the first failure rolls everything back, and the error carries operation_index naming the failing operation. Each operation is { type: add|update|move|delete|reorder, ...} with exactly the arguments of the matching single tool (add_page_element etc., minus organization/token/subboard_token/expected_version_token, which are batch-level); operations in get_page_elements_catalog is the authoritative argument map, and unknown keys are refused. Ids the server mints inside a batch cannot be addressed by later operations of the same batch, so give every new element (and a new section's columns) your own id. Returns the whole document (slots) and one summary per operation. Top-level converged appears only when EVERY operation converged, and never on a batch containing an update. One batch edits one document: the main page, or one nested board's section. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), operations (required), organization, subboard_token, +1 more.
archive_assetsArchive assetsADestructiveIdempotentInspect
Archive one or more assets (up to 1000 per call): each moves into the Archive of the library it belongs to. An asset is taken out of its group unless the group is archived in the same call, and a group left with fewer than two assets is dissolved, as with ungroup_assets. search_assets leaves archived assets out unless include_archived is set. Use unarchive_assets to bring them back. Requires the write scope and update permission on every asset; archives nothing if any asset is in a trashed library.
Inputs: asset_tokens (required), organization.
change_asset_tagsChange asset tagsADestructiveIdempotentInspect
Add and/or remove tags on a single asset. Pass add_tags and/or remove_tags as string arrays. Tags not in either list are left untouched.
Inputs: token (required), add_tags, remove_tags, organization.
copy_assetsCopy assetsAInspect
Copy one or more assets into a target board. Accepts an array of asset tokens and the destination board token. Returns immediately (202 Accepted) — the copy runs asynchronously, so the new assets may take a few seconds to appear. Requires a token with the write scope.
Inputs: asset_tokens (required), collection_token (required), organization.
create_asset_versionCreate asset versionADestructiveInspect
Upload a file from a public URL as a NEW VERSION of an existing asset — the asset keeps its token, boards, and links, and its live bytes are REPLACED (head_version_number moves forward; the current head is snapshotted first). Requires a write-scope token and versioning enabled on the workspace plan. The URL must be a public https:// address (private/loopback/metadata hosts are refused). NOT idempotent — each call uploads fresh bytes and mints a new version even for an identical file, so on a timeout do NOT blind-retry; re-list versions with list_asset_versions to check whether it landed. v1 uploads a single request up to a size cap; files that need multipart upload on this workspace's storage (>=5MB on Backblaze) or exceed the cap are refused with an error directing you to the Playbook web or desktop app. The optional comment is recorded on the snapshot of the REPLACED head (not on the new content), matching revert.
Inputs: uri (required), token (required), title, width, +4 more.
create_boardCreate boardAInspect
Create a new board in a workspace. Optionally nest it under an existing parent board by passing parent_collection_token.
Inputs: title (required), description, organization, parent_collection_token.
create_colorsCreate colorsADestructiveInspect
Add colour swatches to a Playbook board — the building blocks of a palette or a brand's colour spec. Send two or more codes and Playbook merges them into a palette (a group asset), returned as group; send one and group comes back null. A colour is a hex code ("#FF0000", "#F00"), CMYK ("CMYK(0%, 100%, 100%, 0%)"), a two-stop gradient ("#FF0000\u2192#0000FF"), or a Pantone name written WITHOUT the "PANTONE " prefix, exactly as it appears in Playbook's Pantone list — "185 C", not "PANTONE 185 C". Anything else is rejected with 406. Returns the finished swatches immediately (nothing is uploaded, so there is no polling step). Requires a token with the write scope. Tip: validate collection_token with get_board first — an unknown token silently falls back to an anonymous default board.
Inputs: color_codes (required), titles, organization, parent_token, +1 more.
create_commentCreate commentAInspect
Post a top-level comment on an asset or board. Exactly one of asset_token or board_token must be provided.
Inputs: description (required), asset_token, board_token, organization.
create_custom_fieldCreate custom fieldADestructiveIdempotentInspect
Create a custom field on a workspace, or REPLACE the options of one that already exists. Matching is by name: if a select field with this name exists, its option list is overwritten and every option missing from options is deleted, taking that value off every asset holding it. Always pass the complete intended option set, and check list_custom_fields first when the field may already exist. The workspace's built-in 'Status' field cannot be replaced through this tool; use update_asset_status to assign its value to an asset. For a select field (the default) or a multi_select field options cannot be empty. For a date, person, url or text field pass field_type and no options; an existing field with the same name and type is returned unchanged, and a name already used by a field of another type is refused. A NEW field is refused once the workspace reaches its plan's custom field quota — replacing the options of an existing field still works at the limit, so check list_custom_fields before assuming the workspace needs another field. A field's VALUE is set on an asset with update_asset's fields argument ({ "Priority": "High" }); there is no separate set-value tool. Field and option names are matched EXACTLY; update_asset answers an unknown one with an error naming the valid ones, and list_custom_fields has the spelling. Requires a write-scope token and workspace owner/admin permission.
Inputs: name (required), options, field_type, organization.
create_noteCreate noteADestructiveInspect
Add a note to a Playbook board — a sticky-note asset that holds text rather than a file. Use it to annotate a board: a brief, a caption, a to-do, context for the assets around it. Returns the finished note immediately (nothing is uploaded, so there is no polling step). Requires a token with the write scope. Tip: validate collection_token with get_board first — an unknown token silently falls back to an anonymous default board.
Inputs: text (required), tags, color, title, +6 more.
create_upload_urlCreate upload URLAInspect
Step 1 of 2 for uploading a file you already HOLD — one generated locally, returned as base64 by an image API, or sitting on disk. Returns a one-time address to send the bytes to, plus the exact HTTP requests to make; the caller sends the bytes and finish_upload then turns them into an asset. Requires a token with the write scope and a caller that can make HTTP requests. Prefer upload_from_url whenever the file is already at a URL Playbook can fetch — that route is one call and needs nothing from you. Come here when it is not: no URL at all, a URL behind a login, an expired signed URL, a host that blocks datacenter addresses, or an ingest that failed with "Source URL too large to fetch; upload manually" (Playbook's fetcher runs to a five-minute streaming budget, which this path does not have — though it has a size ceiling of its own, below). When neither a reachable URL nor HTTP requests are available, share_board with enable_uploads returns a link a person can drop the file on. Files above 104857600 bytes are refused: these tools transfer in a single request, and splitting a larger file into chunks is what the Playbook web and desktop apps are for.
Inputs: size (required), filename (required), media_type (required), organization.
create_upload_urlsCreate upload URLsAInspect
Batch form of create_upload_url: request upload addresses for up to 50 files in one call, then send each file's bytes and finish them all with finish_uploads. Give every item a uuid of your own — it is echoed back beside that item's address, and with several similar files it is the only reliable way to tell which address belongs to which file. Returns a batch_id that finish_uploads needs: it holds a reservation against the workspace's quota until the batch completes — so prepare a batch only when you are ready to finish it, and pass the batch_id back. Use upload_from_urls instead when the files are already at URLs Playbook can fetch. If any single file cannot be handled the whole call is refused rather than half of it succeeding.
Inputs: files (required), organization.
delete_appDelete hosted appADestructiveInspect
Take a hosted app offline and delete it. Its public address stops working within a minute and its slug becomes free for any workspace to take. NOT reversible: the files are gone, and bringing the app back means deploying them again with deploy_app. The board and its assets are untouched. Requires write scope and permission to edit the board the app shows.
Inputs: slug (required), organization.
delete_assetDelete assetADestructiveInspect
Soft-delete an asset. This is reversible from the Playbook trash for a limited time.
Inputs: token (required), organization.
delete_boardDelete boardBDestructiveInspect
Delete a board and all of its contents. Destructive.
Inputs: token (required), organization.
delete_custom_fieldDelete custom fieldADestructiveInspect
Delete a custom field of any type, with all of its options. This strips the field's value from every asset that carried one, and is not reversible. The workspace's built-in 'Status' field is protected and cannot be deleted. Takes the field token from list_custom_fields, not its name. Requires a write-scope token and workspace owner/admin permission.
Inputs: token (required), organization.
delete_page_elementDelete page elementADestructiveIdempotentInspect
Remove an element from a board's published page and return the slot as it now stands. An id that is nowhere on the page succeeds with converged: true, which means nothing was removed. An id that exists but in a different slot than slot_id is a 404. Deleting a section removes its contents with it. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), slot_id (required), element_id (required), organization, +2 more.
deploy_appDeploy hosted appADestructiveInspect
Start from a recipe: read_documentation hosted_apps, then the hosted_apps_recipe_* topic closest to the request (gallery, upload against a brief, review), and change that app rather than writing one from scratch. Keep content that changes — briefs, captions, prices, names — on the board (its description, asset titles and fields), not in the files, so the team edits it in Playbook without a redeploy. Put a small web app that you wrote live at its own address, or replace the files of the app this workspace already has under the same slug. A hosted app is static files — HTML, CSS, JavaScript, no build step — that show ONE board and its sub-boards: a gallery, a portfolio, a catalogue. Returns the app's url, and warnings when Playbook spots a likely mistake in the files: fix each one and deploy again. The hosted_apps topic has the contract. In short, the page reads the board through its own address: a GET of the RELATIVE URL playbook/api/<path> returns the Playbook REST API's answer to /v1/{organization}/<path> (e.g. playbook/api/assets?nested_assets=true), and playbook/app answers { board }. The page needs and gets no token; every URL in the app must be relative. access sets who may open it: public (the default for a new app: anyone with the address), members (people who can view the board in Playbook, after signing in), or password (visitors who give password). Ask the user which they want when the board is not meant for everyone. Whoever gets in sees everything on the board, unapproved assets and uploader names included, and boards added under it later too, so confirm the board with the user before deploying. The board's own share settings do not protect the app, but its share link's watermark is on every image the app reads, and while that link allows downloads visitors can download originals through playbook/download, with the link's password if it has one; a sub-board whose own share link has a password gives its files that password and that link's terms (see the topic). Everything in files is served to every visitor: never put a token, a key, or content read from another board into them. Visitors may upload into the board (playbook/upload, see the topic): allowed while the board's share link has Allow uploads or the upload-only page on, with no password, no email form and no past expiry, or, in an app that is not public, for a signed-in visitor who may upload to the board. In a members app the page may also change the board's assets as the signed-in visitor, with their permissions: title, description, status, fields, tags, approval and comments (see the topic), and read an asset's comments as that visitor sees them; public and password apps cannot read comments. Nothing else is written: no deletes, moves or board changes, and public and password apps change nothing but uploads. A redeploy without access keeps the app's access. Limits: an index.html is required; text files only (.html .css .js .mjs .json .svg .txt .webmanifest); at most 50 files and 1 MB in total — images stay in Playbook and are never part of the app. The workspace's plan caps how many apps it may have: a new app over the cap is refused with the reason, while replacing the files of an existing app never is. A deploy replaces the whole file set, so send every file each time, not only the changed ones; to change a few files of an existing app, edit_app_source is lighter. Every deploy, even of the same files, is kept as a new numbered version, and past 50 the oldest is dropped. The app reads the board as whoever deployed it last. If the call times out, check list_app_versions before deploying again: a deploy that landed is already live, and a repeat adds another version. Requires write scope and permission to edit the board.
Inputs: name (required), slug (required), files (required), board_token (required), +5 more.
edit_app_sourceEdit hosted app sourceADestructiveInspect
Change some files of a hosted app without resending the rest, and put the result live as a new version. files adds or replaces files by path, with their full contents as text; delete_files removes paths, and a path the app does not have is ignored without an error, so take paths from get_app_source. Every other file is kept as it is in expected_version. expected_version must be the app's live head_version_number, from list_apps or list_app_versions: if the app changed since, the call fails with stale_app and the live number, so read the files again and redo the change. The result must still meet deploy_app's limits: an index.html, text files only, at most 50 files and 1 MB. Like a deploy, the change makes the app read the board as you; if someone else deployed it last, signed-in visitors have to reload before their next change. The new files can take about a minute to be served. The previous version stays in the history (Playbook keeps the last 50), so revert_app can undo this. An app not deployed since Playbook began keeping versions has no stored files: the call fails with source_unavailable, and deploying its files once with deploy_app starts its history. Requires write scope and permission to edit the board the app shows.
Inputs: slug (required), expected_version (required), files, comment, +2 more.
edit_asset_version_commentEdit asset version commentADestructiveIdempotentInspect
Edit the comment/note on an existing asset version, addressed by version_number. Requires a write-scope token and versioning enabled. Does NOT create a version and does NOT change the asset's bytes or head. Pass an empty string to clear the comment. Use list_asset_versions to find the version_number; an unknown or out-of-range number returns not found. Note the newest stored version is head_version_number − 1 (head_version_number is the next, not-yet-assigned number).
Inputs: token (required), comment (required), version_number (required), organization.
finish_uploadFinish uploadAInspect
Step 2 of 2: turn bytes you have already sent to storage into a Playbook asset. Call it only after every step returned by create_upload_url has succeeded — this call does not transfer anything, it records what landed. Pass the signed_gcs_id from create_upload_url unchanged. If a step failed, do NOT call this; start over with a fresh create_upload_url.
Inputs: media_type (required), signed_gcs_id (required), size, title, +7 more.
finish_uploadsFinish uploadsAInspect
Batch form of finish_upload: turn bytes already sent to storage into assets, all on the same board. Include only the items whose byte transfers actually succeeded. IMPORTANT — this call is NOT atomic: it creates the assets one at a time and does not roll back, so a failure partway through leaves the earlier ones created while the call reports an error. Never retry it after a failure; see the recovery steps in the error itself.
Inputs: assets (required), batch_id (required), organization, collection_token.
get_app_sourceGet hosted app sourceARead-onlyInspect
Read the files of a hosted app as Playbook stores them. Without path, returns the version's version_number and its files, each with path and bytes. With path, also returns that file's text in file.content, a slice starting at offset; while file.next_offset is not null, call again with offset set to it to read the rest. Reads the live version unless version names an older one (see list_app_versions); a version or path that is not there answers not found. Read an app's files before changing it with edit_app_source rather than rewriting them from memory. An app not deployed since Playbook began keeping versions has no stored files: the call fails with source_unavailable, and deploying its files once with deploy_app starts its history.
Inputs: slug (required), path, limit, offset, +2 more.
get_assetGet assetARead-onlyInspect
Get full details of a specific asset by its token. For more than one asset use get_assets, which reads up to 100 in a single call — calling this in a loop is the slow way to read a board. This one always returns ai_agent_payload, where get_assets makes it opt-in. Returns metadata including approval state, title, media type, tags, statuses, description, URLs, and dimensions. Signed display URLs expire after about 24 hours; permalink, when present, does not expire. colors holds the image's primary colours as hex codes, most dominant first, so a board's palette can be built from its assets' colors without downloading the images. It is empty for anything with no rendered preview (notes, colour swatches, links), which means not analysed, not colourless. List and search results do not carry it; ask for an asset by token. A video's stream_url is null until an HLS encode has finished; reading never starts one — retry_video_processing does.
Inputs: token (required), organization.
get_asset_download_urlsGet asset download URLsARead-onlyInspect
Get a signed URL of the ORIGINAL file of one or more assets: the uploaded bytes, unchanged, where display_url, previews and image permalinks are re-encoded renders. This is the way to hand a full-quality video, PDF, font or source image to another system, or to fetch it yourself. The URL needs no login and expires within about a day; file contents do not travel through this server. A URL that has to keep working longer is a permalink (add_asset_permalinks). An asset with no file of its own — a note, a colour swatch, a group, an upload still ingesting — is listed under no_file; a link asset returns the address it points to, with a null size. Tokens that do not exist or are not visible to this token are under not_found, and a token whose read failed for another reason is under failed with the reason. Requires download permission on each asset. Each asset read counts as one API request against the plan's quota. Up to 25 assets per call.
Inputs: asset_tokens (required), organization.
get_asset_permalinksGet asset permalinksARead-onlyInspect
Read the permanent public URL of one or more assets, optionally rendered at a size you choose. Reads only — it never publishes anything, so an asset that has no permalink yet is reported under not_published; run add_asset_permalinks on those first. An asset under pending is still being published: its URL is withheld until the file is in place, so read it again shortly instead of publishing it again. This is the URL to use anywhere the link has to outlive the session: a document, a deck, a web page, a hand-off to another system. For a throwaway image to look at right now, use get_asset_previews instead — it needs no permalink and costs no quota. width/height resize IMAGES only (one of the two keeps the aspect ratio); PDFs, video and everything else are served at their stored size and ignore both.
Inputs: asset_tokens (required), width, height, organization.
get_asset_previewsGet asset previewsARead-onlyInspect
Render one or more assets as images at a size you choose, and get a URL per asset. This is how you LOOK at Playbook assets: the display_url on an asset is the full-size render (5000px is normal), which is wasteful to fetch and too large for most vision models. Ask for 1024 wide and you get a 1024px image. The URLs are SHORT-LIVED — they die at the end of the next hour, so 1-2 hours depending on when you call. They suit fetching now or showing in the current reply; anything that must keep working later — a stored link, a document, a hand-off — needs get_asset_permalinks. A SIZE IS REQUIRED — pass width, height, or both; without one this would hand back the same full-size render you already have. IMAGES ONLY: it renders the asset's original file, so a video or a PDF comes back with a URL that will not load, and an asset with no file at all (a note, a colour swatch, a link) is listed under no_file_to_render rather than given a URL. Check media_type starts with image/ first. Tokens missing from the response entirely are under not_found — unknown, or not visible to this token. One render per token per call, so ask for the assets you actually need to see rather than a whole board.
Inputs: asset_tokens (required), width, format, height, +1 more.
get_assetsGet assetsARead-onlyInspect
Get full details for up to 100 assets in ONE call — the batch form of get_asset. Use it after list_assets or a search to read the fields those rows do not carry: description, colors, source_url, custom fields, dimensions and comment counts. Prefer it over calling get_asset in a loop; a 60-asset board is one call, not sixty. Tokens that do not exist, or that you cannot see, come back in not_found rather than failing the whole call — check it, because a missing asset is otherwise indistinguishable from one you forgot to ask for. Grouped child assets ARE returned here, unlike in list_assets, which lists only top-level rows.
Inputs: asset_tokens (required), organization, get_ai_payload.
get_boardGet boardARead-onlyInspect
Get details of a specific board by its token. Returns the board's title, description, asset count, parent board, and child board count. published_page says whether the board's public page is live (active), its url (null unless live) and the template its page design uses (can be set on a page that is not live). asset_count covers the board AND every board nested under it (each group/stack counted once); list_assets on a board returns only assets sitting directly on it unless you pass nested_assets: true, so compare the count against that, not the plain listing.
Inputs: token (required), organization.
get_commentsGet commentsBRead-onlyInspect
List comments on an asset or board. Specify entity_type as 'asset' or 'board' and provide the token.
Inputs: token (required), entity_type (required), page, organization.
get_importGet import statusARead-onlyInspect
Read an import run's progress: status (pending, active, completed, canceled), cancel_reason, scanning (still listing folders), the target board_token (files are in sub-boards named after each folder), and files counts (total, pending, completed, skipped, failed). skipped includes files already on the board unchanged. cancel_reason on canceled: overlimit — out of storage or assets, or the next file would have crossed into storage overage the workspace has not agreed to (nothing past that point was stored); incomplete — some files failed; failed_to_start — could not start, e.g. sustained provider rate limiting; oauth_credential_deleted / target_collection_deleted — the connection or board was removed; blocked — blocked by an admin. Poll no more than every 15–30 seconds.
Inputs: token (required), organization.
get_page_elements_catalogGet page elements catalogARead-onlyInspect
The vocabulary for designing a board's published page — read it BEFORE publishing with a template or writing any page element. Returns: templates (the valid template ids for publish_board, each with its display name, default background/typography and the slots it mounts itself — a floor, not an inventory), element_types (the names of every element type), enum_sets, background_colors and typographies (the values update_page_settings accepts), operations (the argument map for apply_page_operations), and limits. The same for every workspace. The props of the element types are large (~40 KB together), so they come back only for the types named in the element_types argument, under elements: each type with the camelCase props it accepts, flagged html, url, asset_token or dead — a dead prop is stored but no longer rendered. A designed page is built from sections (up to 3 columns, each holding note and asset rows) under a banner hero, and its look comes from the style prop on notes and assets — gradients, cards, shadows, tilts, big type; read style on note before relying on color. There is no carousel or slideshow element: present a deck as ordered sections, or as a grid with horizontalView and autoScroll.
Inputs: element_types.
get_page_layoutGet page layoutARead-onlyInspect
Read the stored design of a board's published page: template, the page's own background_color and typography (null = inherited), slots (the page's regions and their elements), subboards_settings (one full second document per nested board shown on the page) and version_token. Returned verbatim — the ids and camelCase keys are exactly what the page element tools take back. slots: null is NORMAL for a page nobody has edited yet: it still renders its template's defaults. Address such a page by slot NAME (see templates in get_page_elements_catalog); the first write stores the defaults and returns real ids. 404 page_layout_not_found means the board has no page design — publish it with publish_board and a template first. Reads never change anything and are not gated by the page-layout write flag.
Inputs: token (required), organization.
group_assetsGroup assetsADestructiveInspect
Merge assets into a group. A group is a container asset that holds other assets as variants — different formats or crops of the same thing, or a set of colour swatches, which Playbook shows as a palette. The group has no file of its own and takes its preview from its first displayable child. Pass the asset the others should join as parent_asset_token; if it is already a group they are added to it, otherwise a new group is created around it. Children move to the parent's board. Requires a token with the write scope. Two rejections to plan around: every child must be ungrouped or already in this same group — one that belongs to a different group fails the whole call, so ungroup it first — and parent_asset_token must not itself be sitting inside a group. To add to an existing group, pass the GROUP's own token, not the token of one of its members.
Inputs: child_asset_tokens (required), parent_asset_token (required), organization.
import_from_dropboxImport from DropboxAInspect
Import Dropbox folders into a board. Use this for files that live in the user's Dropbox, including private and team folders — upload_from_url cannot reach those. Google Drive and Dropbox are connected ONCE, by a person, in the Playbook web app — there is no tool that connects them. Connections belong to a Playbook user: this server only sees connections made by the same Playbook account it is signed in as. When list_import_sources has no source with the needed provider, its connect_url is where a person connects that service; the source is listed once they have. FOLDERS: pass the folder URL from the Dropbox address bar (https://www.dropbox.com/home/… on a personal account, /work/… for a team member), its path (/Clients/Acme), or an id: key. Shared links (dropbox.com/scl/…) are refused; the address-bar URL or the path is required. Every folder is checked against the connected Dropbox account first; one it cannot find is refused with the account's email. RE-SYNC: importing the same folder into the same board_token skips files already there unchanged (compared by Dropbox content hash), so a recurring sync should reuse the board. A file changed in Dropbox is added as a SECOND asset next to the old one, and renaming the Dropbox folder or its sub-board imports that folder again in full. Files that were first imported before this skipping shipped are downloaded again on every re-sync; the copies are usually merged away, but a workspace with duplicate merging turned off, or an asset kept in a group, ends up with real duplicates. Import into a new board to get skipping for them. WHERE FILES LAND: each folder becomes a sub-board NAMED AFTER THE FOLDER inside the target board, with its sub-folders nested below — not the target board itself. Find it with list_board_children on board_token, or list_assets with nested_assets. The import is ASYNCHRONOUS: this returns a run in pending; poll get_import until status is completed or canceled. Plans without unrestricted imports allow one active import per workspace; the refusal names the active import's token, so poll that instead of retrying. Storage overage cannot be agreed to here: the call is refused when the workspace has no storage left before overage it has not agreed to, and the import is canceled (overlimit) before storing a file that would cross it. A rate-limit error carries a retry delay — wait that long. Requires a write-scope token and workspace owner/admin permission.
Inputs: folders (required), source_token (required), board_token, organization.
import_from_google_driveImport from Google DriveAInspect
Import Google Drive folders into a board. Use this for files that live in the user's Google Drive, including private folders — upload_from_url cannot reach those. Google Drive and Dropbox are connected ONCE, by a person, in the Playbook web app — there is no tool that connects them. Connections belong to a Playbook user: this server only sees connections made by the same Playbook account it is signed in as. When list_import_sources has no source with the needed provider, its connect_url is where a person connects that service; the source is listed once they have. Every folder is checked against the connected Google account first; one it cannot see is refused with the account's email, which usually means the folder must be shared with that account. RE-SYNC: importing the same folder into the same board_token skips files already there unchanged, so a recurring sync should reuse the board. But a file changed in Drive is added as a SECOND asset next to the old one, and renaming the Drive folder or its sub-board imports that folder again in full. WHERE FILES LAND: each folder becomes a sub-board NAMED AFTER THE FOLDER inside the target board, with its sub-folders nested below — not the target board itself. Find it with list_board_children on board_token, or list_assets with nested_assets. The import is ASYNCHRONOUS: this returns a run in pending; poll get_import until status is completed or canceled. Plans without unrestricted imports allow one active import per workspace; the refusal names the active import's token, so poll that instead of retrying. Storage overage cannot be agreed to here: the call is refused when the workspace has no storage left before overage it has not agreed to, and the import is canceled (overlimit) before storing a file that would cross it. A rate-limit error carries a retry delay — wait that long. Requires a write-scope token and workspace owner/admin permission.
Inputs: folders (required), source_token (required), board_token, organization.
list_appsList hosted appsARead-onlyInspect
List the hosted apps of a workspace: small web apps, each showing one board, that were deployed with deploy_app. Returns each app's slug, name, url, the board_token of the board it shows, access (who may open it: public, password or members), enabled and head_version_number. An app with enabled: false was switched off: its address answers 404 and no tool here switches it back on. head_version_number is the live version: Playbook keeps the files of an app's last 50 deploys, which get_app_source reads, edit_app_source changes, list_app_versions lists and revert_app puts back live.
Inputs: organization.
list_app_versionsList hosted app versionsARead-onlyInspect
List the kept versions of a hosted app, newest first; Playbook keeps the last 50. Each has a number, created_at, created_by, file_count, bytes, comment and, for a rollback, reverted_from_number. Also returns head_version_number, the version that is live. Read a version's files with get_app_source and put one back live with revert_app.
Inputs: slug (required), organization.
list_assetsList assetsARead-onlyInspect
List assets in a Playbook workspace, optionally filtered to a specific board. Set nested_assets with a board token to include its entire subtree. Use cursor pagination for a stable full crawl/reconcile; it is not a change feed and does not report deletions. For 'what is new in this board since X', pass created_after with collection_token and nested_assets. Signed display URLs expire after about 24 hours; store permalink when a permanent URL is required. Set uploaded_by to list everything one person added — prefer this over the search tools when you want a COMPLETE list, since it walks the database directly and is not subject to the search engine's result ceiling. Resolve the person with list_members first.
Inputs: page, cursor, fields, per_page, +7 more.
list_asset_versionsList asset versionsARead-onlyInspect
The entry point for anything about an asset's earlier states — version history, previous or older versions, what changed and when, and picking one to restore or roll back to with revert_asset (annotate one with edit_asset_version_comment). Lists the version history of an asset, newest first. Each version has a version_number (the key to revert to or annotate), md5 (content md5; may be a storage-placeholder value for async uploads), size, media_type, source (UPLOAD or REVERT), comment, created_at, created_by_token, a revertable flag, and thumbnails. Also returns head_version_number — the number the next version write will take (1 for a never-versioned asset). Reads are always available regardless of plan. On Free/Pro plans, versions older than the revert window are gated: primary_gcs_id is null and thumbnails is empty (the full-resolution original is not available on those plans). Use the live asset's display_url to preview current content.
Inputs: token (required), page, per_page, organization.
list_board_childrenList child boardsARead-onlyInspect
List the direct child boards of a given board. Use this to navigate the board hierarchy one level at a time — more efficient than list_boards with depth when you only need one node's immediate children. asset_count covers the board AND every board nested under it (each group/stack counted once); list_assets on a board returns only assets sitting directly on it unless you pass nested_assets: true, so compare the count against that, not the plain listing.
Inputs: token (required), organization.
list_board_descendantsList board descendantsARead-onlyInspect
List EVERY board nested under a given board — children, their children, and so on — in one paginated call, instead of walking list_board_children level by level. Each board carries its absolute tree_depth. asset_count covers the board AND every board nested under it (each group/stack counted once); list_assets on a board returns only assets sitting directly on it unless you pass nested_assets: true, so compare the count against that, not the plain listing.
Inputs: token (required), page, per_page, organization.
list_boardsList boardsARead-onlyInspect
List boards (collections) in a Playbook workspace. Supports title search via query and hierarchy depth control via depth ('1' = top-level only, 'all' = full tree). Results are paginated — use page to navigate. asset_count covers the board AND every board nested under it (each group/stack counted once); list_assets on a board returns only assets sitting directly on it unless you pass nested_assets: true, so compare the count against that, not the plain listing.
Inputs: page, depth, query, per_page, +1 more.
list_custom_fieldsList custom fieldsARead-onlyInspect
List a workspace's custom fields — the structured metadata vocabulary its assets use (Priority, Season, Usage Rights), each with its field_type and the options it allows. Call this FIRST before setting or filtering a field value: it is the only source of the exact field and option spelling. A field's VALUE is set on an asset with update_asset's fields argument ({ "Priority": "High" }); there is no separate set-value tool. Field and option names are matched EXACTLY; update_asset answers an unknown one with an error naming the valid ones, and list_custom_fields has the spelling. The list also contains the workspace's built-in 'Status' field, whose value is set with update_asset_status instead. A select field holds one of its options, a multi_select field any number of them (set with a list); a date, person, url or text field has no options and holds one free value per asset — see update_asset's fields parameter for the value formats. Returns every field in one call — this endpoint is not paginated.
Inputs: organization.
list_documentationList documentationARead-onlyInspect
List all available Playbook documentation topics. Returns a catalog of guides and references. Use the topic slug with read_documentation to read the full content.
Inputs: no named parameters.
list_group_childrenList group childrenARead-onlyInspect
List the assets inside a group. list_assets and the search tools return only top-level rows, so this is how a group's members are read. A group is a container asset that holds other assets as variants — different formats or crops of the same thing, or a set of colour swatches, which Playbook shows as a palette. The group has no file of its own and takes its preview from its first displayable child. token must be a group — an asset whose is_group is true in get_asset or get_assets; anything else is refused as not a group. Results are paginated, newest first.
Inputs: token (required), page, fields, per_page, +1 more.
list_import_sourcesList import sourcesARead-onlyInspect
List the storage accounts connected for import, each with its provider (google_drive or dropbox), the token import_from_google_drive / import_from_dropbox takes (use a source of the matching provider), and the account email it reads from (briefly null right after connecting). Google Drive and Dropbox are connected ONCE, by a person, in the Playbook web app — there is no tool that connects them. Connections belong to a Playbook user: this server only sees connections made by the same Playbook account it is signed in as. When list_import_sources has no source with the needed provider, its connect_url is where a person connects that service; the source is listed once they have. Requires workspace owner/admin permission.
Inputs: organization.
list_membersList workspace membersARead-onlyInspect
List the people in a Playbook workspace, or find one by name. Pass query to search by name or email — the match is fuzzy, so a partial or misspelled name works ('quackenbsh' finds 'Zephyrine Quackenbush'). Returns each member's token, which is the value the uploader filters on ai_search, search_assets, and list_assets require. Call this FIRST whenever a request names a person ('what did Max upload', 'files from Sarah') — a person's name typed into a search query does NOT match the person who uploaded an asset. A name can match several members; each comes back with its own token.
Inputs: page, query, per_page, organization.
list_organizationsList workspacesARead-onlyInspect
List all Playbook workspaces (organizations) the authenticated user belongs to. Returns each workspace's slug (used as identifier in other tools), name, and the user's role. permalink_quota reports how many permanent public URLs the plan still allows (left of total) — check it here before a large add_asset_permalinks call, since going over the cap refuses the entire batch.
Inputs: no named parameters.
move_assetsMove assetsADestructiveIdempotentInspect
Move one or more assets to a target board. Accepts an array of asset tokens and the destination board token. Requires a token with the write scope. The caller must have update permission on every source asset. Moves nothing if the destination board is read-only, if an asset or the destination is in a trashed library, or if moving archived assets out would exceed the workspace's asset limit.
Inputs: asset_tokens (required), collection_token (required), organization.
move_page_elementMove page elementADestructiveIdempotentInspect
Move an element to another position, another slot, or into/out of a section column on a board's published page. Returns both affected slots. A move that would change nothing converges. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), at_index (required), element_id (required), to_slot_id (required), +8 more.
preview_appPreview hosted appARead-onlyInspect
Look at a hosted app as a visitor sees it: returns screenshots of its live address on a phone (390×844) and a desktop (1280×800) as JPEG images, taken once the page has loaded. Use it after deploy_app or edit_app_source and before giving the user the link: check the layout, the text, the empty and error states, and fix what looks wrong. New files can take about a minute to be served, so a preview right after a change may still show the old version. An app that is not public is opened without its password or a sign-in, as a visitor who changes nothing: what the page shows only to a signed-in member, such as comments, is missing. Requires permission to edit the board the app shows.
Inputs: slug (required), organization.
publish_boardPublish boardADestructiveIdempotentInspect
Create or update a board's public page, optionally changing its expiry, download restriction, or password. Returns the public URL. This is different from share_board — a published board is a standalone public landing page, while share_board returns an invite-style shareable link. Pass template to give the page a designed layout: valid ids are the keys of templates in get_page_elements_catalog (an unknown id is refused with the valid list). A template publish creates the page design that get_page_layout and the page element tools read and edit. Omit template on a board that is NOT live and has no page design yet, and it is published with standard so it is editable straight away (a workspace's own version of that template applies if it has one). A live page, or a board that already has a design, is never given a template implicitly. template_applied in the response names the template this call applied, and is absent when the design was left alone. An explicit template is refused with 409 page_design_exists when the page has stored element edits, rather than overwriting them: republish WITHOUT template to keep that design, and edit it with the page element tools. That refusal does NOT cover a design that is only page settings (background colour, typography set with update_page_settings) — a template publish replaces those. A page still following its template (never edited) switches to the new one. Exposure: this makes the board and its assets publicly accessible on the internet to anyone with the URL.
Inputs: token (required), password, template, organization, +2 more.
read_documentationRead documentationARead-onlyInspect
Read a specific Playbook documentation page. Use list_documentation first to see available topics. Returns the text of a public Playbook developer-docs page (https://dev.playbook.com), including code examples and endpoints.
Inputs: topic (required).
remove_asset_permalinksRemove asset permalinksADestructiveInspect
Revoke assets' permalinks, freeing the plan's permalink allowance. Destructive and NOT reversible in place: adding a permalink back mints a DIFFERENT URL, so anything embedding the old one stays broken. NOT an emergency takedown: the asset stops reporting a permalink at once, but the file already published stays fetchable to anyone holding the URL until the public copy is purged, which runs on a safety delay of about a week — so this call does not stop a leak that is already under way. Assets that have no permalink are skipped and are NOT in the response; if none of them has one the call is a 406. The response reports the freed-up quota. Requires write scope and update permission on every asset; one unknown token fails the whole call.
Inputs: asset_tokens (required), organization.
reorder_page_slotReorder page slotADestructiveIdempotentInspect
Set the order of a slot's top-level elements on a board's published page. ordered_ids must be EXACTLY the slot's current top-level element ids — none missing, none repeated, none extra (ids nested in a section count as extra) — otherwise 422 reorder_id_mismatch names the offending ids and nothing changes. An order that already holds converges. To move one element, move_page_element is simpler. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), slot_id (required), ordered_ids (required), organization, +2 more.
retry_video_processingRetry video processingAInspect
Start the HLS encode of a video whose stream_url is null. Starts one unless one has already finished — whether the last attempt failed, died on its way to the encoder, or was never made at all. A workspace that encodes every video on upload needs it only for an encode that failed or stalled. Other workspaces encode on request, and this is the request: reading the asset does not start one. stream_url fills in a few minutes after the call. CALL IT ONCE, NOT IN A LOOP: it cannot tell a running encode from a dead one, so calling it again while one is under way queues a second job. To wait for a result, poll get_asset and watch stream_url. An error back means the encode already succeeded, or the workspace's plan does not stream video.
Inputs: token (required), organization.
revert_appRevert hosted app to a versionADestructiveInspect
Put an earlier version of a hosted app back live. Its files are deployed again as a new version, so the version you leave stays in the history and the rollback can itself be undone the same way; Playbook keeps the last 50 versions, so past that the oldest is dropped. version is the number to restore, from list_app_versions; expected_version is the live head_version_number: if the app changed since, the call fails with stale_app. A version that is not kept, or an app with no stored versions, answers not found. The app's address, name and access do not change, but like a deploy it then reads the board as you; if someone else deployed it last, signed-in visitors have to reload before their next change. The restored files can take about a minute to be served. Requires write scope and permission to edit the board the app shows.
Inputs: slug (required), version (required), expected_version (required), comment, +1 more.
revert_assetRevert asset to a versionADestructiveIdempotentInspect
Revert an asset to a prior version by version_number. Requires a write-scope token and versioning enabled on the workspace plan. A content-changing revert does NOT move the head back to N — it snapshots the current head as a new REVERT version and rotates the bytes to the target, so head_version_number moves FORWARD (old head + 1). A revert whose target content already matches the current head is a no-op (no new version, head unchanged) — this also covers a client-timeout retry of a just-completed revert. Note head_version_number is the next, not-yet-assigned number, so passing version_number equal to it is a benign no-op; the newest stored version is head_version_number − 1. On Free/Pro plans, reverting to a version older than the revert window is refused (revert_window_exceeded). Call list_asset_versions first to pick a valid, revertable version_number.
Inputs: token (required), version_number (required), comment, organization.
search_assetsSearch assetsARead-onlyInspect
Search for assets in a Playbook workspace by metadata: filename, title, or tags. Use this when the user knows the name of an asset or is searching by tag or file type. Does NOT understand visual content — use ai_search for queries about what is depicted in the asset. Supports filtering by media type (image, video, document, audio), board, uploader, and status or custom field value. This is also the ONLY tool that finds assets BY a custom field value ('everything marked High') — pass the value as statuses, which ai_search also accepts. A filter-only call automatically searches all text (query: '*'), and any statuses call without an explicit media type searches every media type. To find what a PERSON uploaded, call list_members to resolve their name to a token, then pass that token as uploaded_by. Putting a person's name in query does NOT match the person who uploaded an asset — it searches the asset's own text and will return unrelated files.
Inputs: page, query, fields, statuses, +8 more.
set_asset_approvalSet asset approvalADestructiveIdempotentInspect
Approve or unapprove up to 1000 assets, including assets from different boards. Set approved_after only when unapproving to schedule when the assets become visible again. This controls visibility on shared and published pages and requires approval-management permission.
Inputs: approved (required), asset_tokens (required), organization, approved_after.
unarchive_assetsUnarchive assetsADestructiveIdempotentInspect
Move archived assets (up to 1000 per call) out of the Archive into a board you choose. The original board is not remembered, so a destination is required. Find archived assets with search_assets and include_archived: true. Fails without moving anything if any token is not archived (the error names them, so drop those and retry), if the destination is itself in the Archive, if bringing the assets back would exceed the workspace's asset limit, or if the destination board is read-only.
Inputs: asset_tokens (required), collection_token (required), organization.
ungroup_assetsUngroup assetsADestructiveInspect
Pull assets out of the group they belong to, leaving them as standalone assets on the board. A group is a container asset that holds other assets as variants — different formats or crops of the same thing, or a set of colour swatches, which Playbook shows as a palette. The group has no file of its own and takes its preview from its first displayable child. Requires a token with the write scope. Every token must name an asset that is currently inside a group — one that is not makes the whole call fail. IMPORTANT: a group left with fewer than two assets is dissolved — its last asset is freed too and the group asset is deleted. So ungrouping one member of a two-member group frees both, and the returned list names only the assets you asked for, not every asset that changed. Re-read the group with get_asset if you need its current state.
Inputs: child_asset_tokens (required), organization.
update_assetUpdate assetADestructiveIdempotentInspect
Update an asset's editable metadata: title, description, tags (replaces existing), status, custom field values, or move it to a different board. Only the fields you pass are changed — omit a field to leave it as-is. fields is where custom field VALUES are set; call list_custom_fields first for the exact spelling.
Inputs: token (required), tags, title, fields, +6 more.
update_asset_statusUpdate asset statusBDestructiveIdempotentInspect
Set the status label on an asset (e.g. 'Approved', 'In Review', 'Rejected'). The status value is created on the workspace if it doesn't already exist.
Inputs: token (required), status (required), organization.
update_boardUpdate boardADestructiveIdempotentInspect
Update an existing board's title, description, or parent. Pass only the fields you want to change. To rename a board, pass just title. To move it under a different parent, pass parent_collection_token.
Inputs: token (required), title, description, organization, +1 more.
update_page_elementUpdate page elementADestructiveIdempotentInspect
Replace an element's content on a board's published page. This is a FULL-element replace, not a field patch: every top-level key you send replaces the stored one WHOLESALE, so { props: { text } } DROPS every other stored prop. Read the element with get_page_layout, change what you need, and send its whole props back; top-level keys you omit are left alone. elementType cannot change, and element.id must be omitted or equal element_id. The response never reports converged, even when nothing changed. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), element (required), slot_id (required), element_id (required), +3 more.
update_page_settingsUpdate page settingsADestructiveIdempotentInspect
Change a board's published page's own background colour and/or typography. A PARTIAL update: a setting you do not name is left as it is; one sent as null is CLEARED and the page inherits it again (from the template; a cleared nested-board section inherits the page first). Legal values are background_colors and typographies in get_page_elements_catalog. Elements are untouched. If the board followed a workspace template, a real change detaches it so a later template roll-out does not revert it. Requires modify on the board and page-layout API writes enabled for the workspace — otherwise 403 page_layout_api_disabled, which only Playbook can turn on; retrying does not help. Concurrency: pass the version_token from get_page_layout as expected_version_token; if the page changed since, the call answers 409 stale_document and applies NOTHING — read again, re-decide, re-send. A successful write that sent a token returns the NEW version_token: send that on your next write, because your own write already made the old one stale. Of the 409s only lock_wait_timeout and page_layout_library_locked are safe to repeat unchanged. converged: true in the response means nothing changed (the goal state already held); materialized: true means the page had no stored document and this call saved the template's defaults. Both keys are ABSENT when false. The public page can keep showing the old version for up to an hour after a successful write, so a reload may not show the change.
Inputs: token (required), typography, organization, subboard_token, +2 more.
upload_from_urlUpload from URLAInspect
Upload a single asset to a Playbook board by giving Playbook a public URL to fetch. Returns immediately with a skeleton asset; the byte fetch runs asynchronously in the background. Requires a token with the write scope. Playbook fetches the URL itself, anonymously — a link behind a login or a signed URL that has expired will not work here, and neither will a file that exists only on someone's machine. For those, use share_board with enable_uploads. It returns a link a person can drop files on without signing in, and whatever they add lands on that board for you to collect with list_assets. It needs a live human and it shows the board's existing contents to anyone holding the link, so reach for it only once no fetchable URL is available. The fetch runs to a time budget (five minutes of streaming), so a source that is very large or very slow fails with "Source URL too large to fetch; upload manually" — when that happens, send the bytes yourself with create_upload_url rather than retrying. Tip: validate collection_token with get_board first — an unknown token silently falls back to an anonymous default board.
Inputs: uri (required), tags, title, status, +6 more.
upload_from_urlsUpload from URLsAInspect
Upload up to 100 assets in one call by giving Playbook public URLs to fetch. All assets land in the same board. Returns an array of skeleton assets immediately; the byte fetches run asynchronously per asset in the background. Requires a token with the write scope. Playbook fetches each URL itself, anonymously — links behind a login, expired signed URLs, and files that exist only on someone's machine cannot be ingested here. For those, use share_board with enable_uploads. It returns a link a person can drop files on without signing in, and whatever they add lands on that board for you to collect with list_assets. It needs a live human and it shows the board's existing contents to anyone holding the link, so reach for it only once no fetchable URL is available. Each fetch runs to a time budget (five minutes of streaming), so a source that is very large or very slow fails with "Source URL too large to fetch; upload manually" — when that happens, send those bytes yourself with create_upload_urls rather than retrying. Tip: validate collection_token with get_board first — an unknown token silently falls back to an anonymous default board.
Inputs: assets (required), collection_token (required), organization.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Digital asset manager - upload, organize, search, and generate on-brand images and videos
AI-native digital asset management: semantic search, generative image edits, and CDN delivery.
Official ImageKit media library server: search, upload, organize, tag, share and manage assets.
Upload, generate, organize, search, and transform images, videos, and files with AI-powered tools.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI assistants to search design inspiration, generate and edit images and videos, use reference media, remove backgrounds, create product detail images and marketing posters, and access saved creative assets through remote OAuth or legacy local setups.18543 npmMIT

postward-media-mcpofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to manage media assets on any S3-compatible storage, including uploads, downloads, tagging, and collections, via presigned URLs.MIT- AlicenseNot gradedqualityBmaintenanceProvides a local creator asset library MCP server that scans folders to catalog media files, batch-renames them, applies tags, tracks asset lineage between source and finished works, and offers keyword- and BGE-vector-based semantic search. It also lets other content-production MCP servers auto-register their generated outputs into the library for later retrieval and reuse.MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients and AI agents to search and retrieve images and videos from a stock media library, with filtering by media type, orientation, category, dimensions, colors, safe search, ordering, and pagination.334 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.