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"
Permalinks
Create permanent, shareable URLs for assets that don't expire.
Creating Permalinks
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"
}
]
}
Permalink Use Cases
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 -->

Removing Permalinks
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.
Creating a Shared Link
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"
}
}
Share vs. Permalink
| Feature | Shared Link | Permalink |
|---|---|---|
| Expiration | Can be revoked | Permanent |
| Password Protection | Yes (via UI) | No |
| Analytics | View tracking | Basic metrics |
| Best For | Client reviews, approvals | Long-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
- Group Thoughtfully: Don't over-group. Keep groups to logically related assets.
- Tag Consistently: Establish tagging conventions early and document them.
- Permalinks for Stability: Use permalinks for external references that need to remain stable.
- Shared Links for Collaboration: Use shared links for temporary external access.
- Audit Regularly: Periodically review and clean up unused groups, tags, and permalinks.
Related API Endpoints
Next Steps
- Learn about Custom Fields for advanced metadata
- Explore Webhooks to automate asset workflows
- Read about AI Search for intelligent asset discovery