Embed a Gallery with the SDK
The playbook-sdk is a lightweight,
framework-agnostic frontend library that renders a responsive masonry gallery —
with search, board navigation, a full-screen viewer, and downloads — backed by
your Playbook workspace. It talks to the same REST API documented
here, so anything the gallery shows, you can also drive directly over HTTP.
Install
npm install playbook-sdk
Or drop it in from a CDN:
<script src="https://unpkg.com/playbook-sdk@latest/dist/playbook-sdk.min.js"></script>
Authenticate
The gallery runs in your visitors' browsers, and anything in a web page can be read by whoever opens it. So the SDK is never given your API token. Your server keeps that token and exchanges it for a short-lived, read-only token limited to the one board the gallery shows; the SDK fetches that from your server.
Add an endpoint to your server that does the exchange. This one is plain Node, with no dependencies:
import { createServer } from "node:http";
const { PLAYBOOK_TOKEN, PLAYBOOK_ORG, PLAYBOOK_BOARD } = process.env;
createServer(async (req, res) => {
if (req.method !== "GET" || req.url !== "/playbook/token") {
res.writeHead(404).end();
return;
}
// If the gallery is not public, check the visitor's session here first.
const upstream = await fetch(
`https://api.playbook.com/v1/${PLAYBOOK_ORG}/access_tokens`,
{
method: "POST",
headers: {
Authorization: `Bearer ${PLAYBOOK_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ board_token: PLAYBOOK_BOARD, expires_in: 900 }),
},
);
if (!upstream.ok) {
res.writeHead(502).end();
return;
}
const { data } = await upstream.json();
res.writeHead(200, {
"Content-Type": "application/json",
"Cache-Control": "no-store",
});
res.end(JSON.stringify({ token: data.access_token }));
}).listen(3000);
PLAYBOOK_TOKEN is an API token from Developer → SDK,
and PLAYBOOK_BOARD is the token of the board to show. The token your endpoint
returns can read that board and its sub-boards for up to an hour and nothing
else; see Tokens for browser code
for exactly what it can do.
Initialize
Add a container element, then initialize the SDK with your organization slug and
a getAccessToken function that calls your endpoint:
<div id="gallery"></div>
import PlaybookSDK from "playbook-sdk";
const getAccessToken = () =>
fetch("/playbook/token")
.then((res) => res.json())
.then((body) => body.token);
const gallery = PlaybookSDK.init({
containerId: "gallery",
organizationSlug: "your-org-slug",
boardId: "your-board-token",
getAccessToken,
});
That's it — a live, searchable gallery renders into #gallery. The SDK calls
getAccessToken before its first request and again when the token expires, and
keeps the token in memory only. boardId is the board the token was created
for, or one of its sub-boards; browsing and search stay inside it.
getAccessToken needs playbook-sdk 1.1.0 or later. Earlier versions take a
static authToken, which puts a long-lived token in the page; it still works,
with a console warning, and should be replaced.
Customize
Toggle features, tune the responsive column layout, and hook into events:
PlaybookSDK.init({
containerId: "gallery",
organizationSlug: "your-org-slug",
getAccessToken, // defined above
// Toggle built-in features
enableSearch: true,
enableBoards: true,
enableModal: true,
enableDownload: true,
// Responsive columns (breakpoint in px → column count)
columnBreakpoints: {
default: 1,
768: 2,
1024: 3,
},
// Events
onAssetClick: (asset) => console.log("Clicked:", asset.title),
onSearch: (query) => console.log("Searching:", query),
onDownload: (asset) => console.log("Downloaded:", asset.token),
});
Control it programmatically
init returns a handle you can drive from your own UI:
gallery.refresh(); // reload assets
gallery.search("logo"); // run a search
gallery.selectBoardById("brand-assets"); // switch board
const assets = gallery.getAssets(); // current assets
Style it
The rendered markup uses pb--prefixed classes you can override:
.pb-masonry-item img {
border-radius: 16px !important;
}
.pb-board-btn.active {
background-color: var(--brand-color) !important;
}
Next steps
- Get access: create an API token for your organization, and keep it on your server.
- Go deeper: the SDK is powered by the Playbook REST API — use it directly for server-side or custom workflows.
- Add AI: connect an assistant to the same workspace via the MCP server.