Skip to main content

Brand portal

Distribute approved brand assets — logos, fonts, templates — to partners and teams, with a single source that's always current. Approve once on a board; everyone downstream sees the update immediately.

A brand portal built on the Playbook API

The flow

  1. Keep a board of approved assets (curated with custom fields).
  2. Publish it as a public portal, or share it for a link-gated one.
  3. Embed the portal in your intranet or marketing site.
  4. Serve downloads with token-scoped API keys.

1. Curate approved assets

Filter your library down to what's cleared for distribution and collect it on a "Brand kit" board. An approval custom field makes this reliable:

curl "https://api.playbook.com/v1/$ORG/search?query=&filters[fields][Approval%20Status]=Approved" \
-H "Authorization: Bearer $PLAYBOOK_TOKEN"

2. Publish the portal

curl -X POST "https://api.playbook.com/v1/$ORG/boards/brand-kit/publish" \
-H "Authorization: Bearer $PLAYBOOK_TOKEN"
{ "data": { "url": "https://playbook.com/p/your-org/brand-kit" } }

A published board is a public, always-current gallery — update the board and the portal updates with it, no redeploy. For a link-gated portal instead, use POST /v1/$ORG/boards/brand-kit/share. See the published vs. shared comparison.

3. Embed it

Drop the portal straight into your intranet or brand site:

<iframe
src="https://playbook.com/p/your-org/brand-kit"
style="width:100%;height:900px;border:0"
title="Brand portal"
></iframe>

4. Scope partner access

Issue separate API tokens per integration so each only sees what it should, and revoke without touching the others. Fetch the approved set on your own domain and render a branded download page:

brand-kit.tsx
const ORG = "your-org";
const TOKEN = process.env.PLAYBOOK_TOKEN!; // a token scoped for the portal

type Asset = { token: string; title: string; display_url: string; raw_url: string };

async function getBrandKit(): Promise<Asset[]> {
const res = await fetch(
`https://api.playbook.com/v1/${ORG}/boards/brand-kit/assets?per_page=100`,
{ headers: { Authorization: `Bearer ${TOKEN}` } },
);
return (await res.json()).data;
}

export default async function BrandKit() {
const assets = await getBrandKit();
return (
<ul>
{assets.map((a) => (
<li key={a.token}>
<img src={a.display_url} alt={a.title} width={120} />
<a href={a.raw_url} download>Download {a.title}</a>
</li>
))}
</ul>
);
}