Skip to main content

Advanced Asset Management

Learn how to organize, group, tag, and share assets programmatically using the Playbook API.

Prerequisites

  • Access Token: OAuth2 token with asset management permissions
  • Organization Slug: Your organization identifier
  • Asset Tokens: IDs of assets you want to manage

Asset Grouping

Group multiple assets together to create variants, versions, or related content collections.

Creating Asset Groups

Group assets under a parent asset to create a cohesive set:

curl -X POST "https://api.playbook.com/v1/my-org/assets/group_assets?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '{
"parent_asset_token": "hero-image-main",
"child_asset_tokens": ["hero-variant-1", "hero-variant-2", "hero-variant-3"]
}'

Response:

{
"data": {
"id": 123,
"token": "hero-image-main",
"title": "Hero Image",
"is_group": true,
"group_id": null
}
}

Use Cases for Asset Groups

1. Image Variants

  • Group different sizes/formats of the same image
  • Mobile, desktop, and retina versions
  • Different color variations

2. Version Control

  • Track iterations of design work
  • Group drafts with final versions
  • Maintain revision history

3. Related Content

  • Package assets that belong together
  • Group photos from the same shoot
  • Organize components of a larger project

Ungrouping Assets

Remove assets from their groups when you need to separate them:

curl -X POST "https://api.playbook.com/v1/my-org/assets/ungroup_assets?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '{
"child_asset_tokens": ["hero-variant-1", "hero-variant-2"]
}'

Response:

{
"data": [
{
"id": 124,
"token": "hero-variant-1",
"is_group": false,
"group_id": null
},
{
"id": 125,
"token": "hero-variant-2",
"is_group": false,
"group_id": null
}
]
}

Retrieving Group Children

Get all assets within a group:

curl "https://api.playbook.com/v1/my-org/assets/hero-image-main/children?access_token=TOKEN"

Response:

{
"data": [
{
"id": 124,
"token": "hero-variant-1",
"title": "Hero Mobile",
"group_id": 123,
"group_sort": 1
},
{
"id": 125,
"token": "hero-variant-2",
"title": "Hero Desktop",
"group_id": 123,
"group_sort": 2
}
],
"pagy": {
"current_page": 1,
"total_count": 2
}
}

Tagging Assets

Tags help categorize and filter assets for better organization.

Adding Tags to Assets

curl -X POST "https://api.playbook.com/v1/my-org/assets/logo-png/change_tags?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '["branding", "logo", "approved", "v2"]'

Response:

{
"data": {
"id": 200,
"token": "logo-png",
"tags": ["branding", "logo", "approved", "v2"]
}
}

Tag Management Best Practices

1. Consistent Naming

// Good: lowercase, hyphenated
["brand-assets", "social-media", "high-priority"]

// Avoid: mixed case, spaces
["Brand Assets", "social_media", "High Priority"]

2. Hierarchical Tags

// Organize with prefixes
["status:approved", "status:needs-review", "status:archived"]
["category:logo", "category:icon", "category:banner"]
["project:website", "project:mobile-app"]

3. Tag-Based Workflows

# Batch update multiple assets
for token in logo-main logo-alt logo-mobile; do
curl -X POST "https://api.playbook.com/v1/my-org/assets/$token/change_tags?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '["branding", "approved", "q4-2024"]'
done

Searching by Tags

Use the search endpoint with tag filters:

curl "https://api.playbook.com/v1/my-org/search?access_token=TOKEN&query=&filters[tags][]=branding&filters[tags][]=approved&filters[tags_op]=and"

Create permanent, shareable URLs for assets that don't expire.

curl -X POST "https://api.playbook.com/v1/my-org/assets/add_permalinks?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '["logo-png", "banner-jpg", "icon-svg"]'

Response:

{
"data": [
{
"id": 200,
"token": "logo-png",
"permalink": "https://playbook.com/p/abc123def"
},
{
"id": 201,
"token": "banner-jpg",
"permalink": "https://playbook.com/p/def456ghi"
},
{
"id": 202,
"token": "icon-svg",
"permalink": "https://playbook.com/p/ghi789jkl"
}
]
}

1. External Integrations

// Store permalinks in your CMS
const asset = {
id: 'header-image',
playbookPermalink: 'https://playbook.com/p/abc123def',
displayName: 'Header Background'
};

2. Email Campaigns

<!-- Use permalinks in email templates -->
<img src="https://playbook.com/p/abc123def" alt="Product Banner">

3. Documentation

<!-- Reference assets in markdown docs -->
![Company Logo](https://playbook.com/p/def456ghi)
curl -X POST "https://api.playbook.com/v1/my-org/assets/remove_permalinks?access_token=TOKEN" \
-H "Content-Type: application/json" \
-d '["logo-png", "banner-jpg"]'

Sharing Assets

Create temporary or password-protected shared links for specific assets.

curl -X POST "https://api.playbook.com/v1/my-org/assets/design-mockup/share?access_token=TOKEN"

Response:

{
"data": {
"url": "https://playbook.com/s/xyz789abc/design-mockup"
}
}
FeatureShared LinkPermalink
ExpirationCan be revokedPermanent
Password ProtectionYes (via UI)No
AnalyticsView trackingBasic metrics
Best ForClient reviews, approvalsLong-term references

Complete Asset Management Workflow

Here's a complete example of managing assets for a product launch:

const PLAYBOOK_API = 'https://api.playbook.com';
const ACCESS_TOKEN = 'your_token_here';
const ORG_SLUG = 'my-org';

async function manageLaunchAssets() {
// 1. Upload product images
const uploadedAssets = await uploadProductImages();

// 2. Group variants together
await fetch(`${PLAYBOOK_API}/v1/${ORG_SLUG}/assets/group_assets?access_token=${ACCESS_TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
parent_asset_token: uploadedAssets.main,
child_asset_tokens: uploadedAssets.variants
})
});

// 3. Tag for organization
const tags = ['product-launch', 'q4-2024', 'approved'];
for (const token of [uploadedAssets.main, ...uploadedAssets.variants]) {
await fetch(`${PLAYBOOK_API}/v1/${ORG_SLUG}/assets/${token}/change_tags?access_token=${ACCESS_TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(tags)
});
}

// 4. Create permalinks for marketing team
const permalinkResponse = await fetch(
`${PLAYBOOK_API}/v1/${ORG_SLUG}/assets/add_permalinks?access_token=${ACCESS_TOKEN}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify([uploadedAssets.main])
}
);

const { data } = await permalinkResponse.json();
console.log('Permalink created:', data[0].permalink);

// 5. Share with external reviewers
const shareResponse = await fetch(
`${PLAYBOOK_API}/v1/${ORG_SLUG}/assets/${uploadedAssets.main}/share?access_token=${ACCESS_TOKEN}`,
{ method: 'POST' }
);

const shareData = await shareResponse.json();
console.log('Share link:', shareData.data.url);
}

Error Handling

Common Errors

422: Cannot group asset already in a group

{
"error": "Cannot group into an asset that is already part of a group"
}

Solution: Ungroup the child assets first.

422: Permalink limit exceeded

{
"error": "Permalink limit exceeded for your plan"
}

Solution: Remove unused permalinks or upgrade your plan.

404: Assets not found

{
"error": "Child assets not found"
}

Solution: Verify asset tokens are correct and accessible.


Best Practices

  1. Group Thoughtfully: Don't over-group. Keep groups to logically related assets.
  2. Tag Consistently: Establish tagging conventions early and document them.
  3. Permalinks for Stability: Use permalinks for external references that need to remain stable.
  4. Shared Links for Collaboration: Use shared links for temporary external access.
  5. Audit Regularly: Periodically review and clean up unused groups, tags, and permalinks.


Next Steps