Skip to main content

Assets Block

Assets Block

Enterprise Digital Asset Management for modern applications

The Assets Block is a complete Digital Asset Management (DAM) solution that provides centralized media storage, on-the-fly image transformations, global CDN delivery, rich metadata management, and version control. Build powerful media libraries for e-commerce, content publishing, and brand management.

Key Features

  • Media Library - Centralized storage for images, videos, documents, and any file type
  • Asset Transformations - On-the-fly resizing, cropping, format conversion, and optimization
  • CDN Delivery - Global content delivery network for fast asset serving worldwide
  • Metadata Management - Rich metadata with custom fields, tags, and categories
  • Version Control - Track asset versions, revisions, and maintain audit history
  • Access Control - Fine-grained permissions with expiring links and watermarking
  • Smart Search - Full-text search across filenames, metadata, and tags
  • Folder Organization - Hierarchical folder structure with virtual collections

API Endpoint

ServiceURL
Assetshttps://assets.api.us.23blocks.com

Environment Routing: One URL, one environment. All shared-platform API keys are live keys:

  • pk_live_* / sk_live_* → your production tenant. Need a separate staging environment? It is available as a paid add-on on deployments in your own cloud account — see 23blocks in a Box.

Quick Start

Installation

npm install @23blocks/sdk

Basic Usage

import { create23BlocksClient } from '@23blocks/sdk';

const client = create23BlocksClient({
urls: { assets: 'https://assets.api.us.23blocks.com' },
apiKey: 'your-api-key',
});

// Upload an asset
const asset = await client.assets.upload({
file: fileBlob,
folder: 'products/images',
metadata: {
title: 'Product Hero Image',
tags: ['product', 'hero', 'featured'],
alt: 'Product front view'
}
});

// Get transformed URL
const thumbnailUrl = client.assets.getUrl(asset.id, {
width: 400,
height: 400,
format: 'webp',
quality: 85
});

// Search assets
const results = await client.assets.search({
query: 'product hero',
folder: 'products',
tags: ['featured']
});

Authentication

Required Headers

All API requests require authentication:

Authorization: Bearer [JWT_TOKEN]
X-API-Key: [COMPANY_API_KEY]
Content-Type: application/json

For asset uploads, use multipart/form-data:

Content-Type: multipart/form-data

API Reference

Upload Asset

Upload a new asset to the media library.

curl -X POST https://assets.api.us.23blocks.com/assets \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-F "file=@/path/to/image.jpg" \
-F "folder=products/images" \
-F "metadata[title]=Product Hero" \
-F "metadata[tags][]=product" \
-F "metadata[tags][]=featured" \
-F "metadata[alt]=Product front view"

Response:

{
"data": {
"id": "asset_abc123",
"type": "asset",
"attributes": {
"unique_id": "asset_abc123",
"filename": "product-hero.jpg",
"original_filename": "image.jpg",
"content_type": "image/jpeg",
"size": 1245678,
"folder": "products/images",
"url": "https://cdn.23blocks.com/assets/products/images/product-hero.jpg",
"metadata": {
"title": "Product Hero",
"tags": ["product", "featured"],
"alt": "Product front view"
},
"dimensions": {
"width": 2400,
"height": 1600
},
"version": 1,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
}
}

Get Asset

Retrieve asset metadata by ID.

curl -X GET https://assets.api.us.23blocks.com/assets/asset_abc123 \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"

Update Asset Metadata

Update metadata for an existing asset.

curl -X PATCH https://assets.api.us.23blocks.com/assets/asset_abc123 \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "asset",
"attributes": {
"metadata": {
"title": "Updated Product Hero",
"tags": ["product", "featured", "sale"]
}
}
}
}'

Upload New Version

Upload a new version of an existing asset.

curl -X POST https://assets.api.us.23blocks.com/assets/asset_abc123/versions \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-F "file=@/path/to/updated-image.jpg" \
-F "comment=Updated product photography"

Response:

{
"data": {
"id": "asset_abc123",
"type": "asset",
"attributes": {
"version": 2,
"versions": [
{
"version": 1,
"url": "https://cdn.23blocks.com/assets/.../v1/product-hero.jpg",
"created_at": "2024-01-15T10:30:00Z"
},
{
"version": 2,
"url": "https://cdn.23blocks.com/assets/.../v2/product-hero.jpg",
"comment": "Updated product photography",
"created_at": "2024-01-16T14:20:00Z"
}
]
}
}
}

List Version History

Get all versions of an asset.

curl -X GET https://assets.api.us.23blocks.com/assets/asset_abc123/versions \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"

Rollback to Version

Restore a previous version as the current version.

curl -X POST https://assets.api.us.23blocks.com/assets/asset_abc123/rollback \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"version": 1
}'

List Assets

List assets with filtering and pagination.

curl -X GET "https://assets.api.us.23blocks.com/assets?folder=products&tags=featured&page=1&per_page=20" \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"

Query Parameters:

ParameterTypeDescription
folderstringFilter by folder path
tagsstringFilter by tags (comma-separated)
content_typestringFilter by MIME type (e.g., image/*)
searchstringFull-text search query
created_afterdatetimeFilter by creation date
created_beforedatetimeFilter by creation date
sortstringSort field (created_at, updated_at, filename)
orderstringSort order (asc or desc)
pageintegerPage number (default: 1)
per_pageintegerItems per page (default: 20, max: 100)

Search Assets

Search across all assets using full-text search.

curl -X POST https://assets.api.us.23blocks.com/assets/search \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"query": "product hero",
"filters": {
"folder": "products",
"tags": ["featured"],
"content_type": "image/*"
},
"facets": ["tags", "folder", "content_type"]
}'

Response:

{
"data": [...],
"meta": {
"total": 45,
"facets": {
"tags": [
{"value": "product", "count": 30},
{"value": "featured", "count": 15}
],
"folder": [
{"value": "products/images", "count": 25},
{"value": "products/videos", "count": 20}
]
}
}
}

Delete Asset

Delete an asset and all its versions.

curl -X DELETE https://assets.api.us.23blocks.com/assets/asset_abc123 \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"

Image Transformations

Transform images on-the-fly by appending parameters to the asset URL.

URL Format

https://cdn.23blocks.com/assets/{path}?w={width}&h={height}&f={format}&q={quality}

Transformation Parameters

ParameterDescriptionExample
wWidth in pixelsw=400
hHeight in pixelsh=300
fOutput format (jpg, png, webp, avif)f=webp
qQuality (1-100)q=85
fitResize mode (cover, contain, fill, inside, outside)fit=cover
cropCrop position (center, top, bottom, left, right)crop=center
blurBlur amount (1-100)blur=10
sharpenSharpen amount (1-100)sharpen=20
grayscaleConvert to grayscalegrayscale=true
rotateRotation angle (0, 90, 180, 270)rotate=90

Examples

Thumbnail (200x200, WebP):

https://cdn.23blocks.com/assets/products/hero.jpg?w=200&h=200&fit=cover&f=webp

Responsive Hero Image:

https://cdn.23blocks.com/assets/products/hero.jpg?w=1200&h=600&fit=cover&q=85

Grayscale with Blur:

https://cdn.23blocks.com/assets/products/hero.jpg?grayscale=true&blur=5

SDK Usage

// Generate transformed URL
const thumbnailUrl = client.assets.transform(asset.id, {
width: 400,
height: 400,
fit: 'cover',
format: 'webp',
quality: 85
});

// Generate multiple sizes (responsive images)
const responsive = client.assets.responsive(asset.id, {
sizes: [400, 800, 1200, 1600],
format: 'webp'
});
// Returns: { 400: url, 800: url, 1200: url, 1600: url }

Folder Management

Create Folder

curl -X POST https://assets.api.us.23blocks.com/folders \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "folder",
"attributes": {
"name": "Product Photos",
"path": "products/photos",
"metadata": {
"description": "High-resolution product photography"
}
}
}
}'

List Folders

curl -X GET "https://assets.api.us.23blocks.com/folders?parent=products" \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"

Move Assets to Folder

curl -X POST https://assets.api.us.23blocks.com/assets/move \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"asset_ids": ["asset_abc123", "asset_def456"],
"destination_folder": "products/archive"
}'

Access Control

Create a time-limited shareable link with optional watermarking.

curl -X POST https://assets.api.us.23blocks.com/assets/asset_abc123/share \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"expires_in": 86400,
"watermark": {
"text": "Preview Only",
"position": "bottom-right",
"opacity": 0.5
},
"max_downloads": 10,
"password": "optional-password"
}'

Response:

{
"data": {
"share_url": "https://cdn.23blocks.com/share/xyz789...",
"expires_at": "2024-01-16T10:30:00Z",
"downloads_remaining": 10
}
}

Set Asset Permissions

curl -X PATCH https://assets.api.us.23blocks.com/assets/asset_abc123/permissions \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"public": false,
"allowed_users": ["user_123", "user_456"],
"allowed_roles": ["editor", "admin"]
}'

Collections

Create virtual collections to organize assets across folders.

Create Collection

curl -X POST https://assets.api.us.23blocks.com/collections \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "collection",
"attributes": {
"name": "2024 Spring Campaign",
"description": "Assets for spring marketing campaign",
"asset_ids": ["asset_abc123", "asset_def456"]
}
}
}'

Add Assets to Collection

curl -X POST https://assets.api.us.23blocks.com/collections/coll_xyz/assets \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"asset_ids": ["asset_ghi789"]
}'

Webhooks

Subscribe to asset events for real-time notifications.

Available Events

EventDescription
asset.createdNew asset uploaded
asset.updatedAsset metadata updated
asset.deletedAsset deleted
asset.version.createdNew version uploaded
asset.transformedTransformation generated
asset.sharedShare link created
collection.createdCollection created
collection.updatedCollection modified

Webhook Payload

{
"event": "asset.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": "asset_abc123",
"type": "asset",
"attributes": {
"filename": "product-hero.jpg",
"folder": "products/images",
"url": "https://cdn.23blocks.com/assets/..."
}
}
}

SDK Reference

TypeScript/JavaScript

import { create23BlocksClient } from '@23blocks/sdk';

const client = create23BlocksClient({
urls: { assets: 'https://assets.api.us.23blocks.com' },
apiKey: 'your-api-key',
});

// Upload with progress tracking
const asset = await client.assets.upload({
file: fileBlob,
folder: 'products',
metadata: { title: 'Product Photo' },
onProgress: (progress) => {
console.log(`${progress.percent}% uploaded`);
}
});

// Batch operations
const results = await client.assets.batch({
operations: [
{ action: 'move', asset_id: 'asset_1', folder: 'archive' },
{ action: 'tag', asset_id: 'asset_2', tags: ['featured'] },
{ action: 'delete', asset_id: 'asset_3' }
]
});

React Hook

import { useAssets } from '@23blocks/react';

function MediaLibrary() {
const { assets, loading, upload, search } = useAssets({
folder: 'products'
});

const handleUpload = async (files: FileList) => {
for (const file of files) {
await upload(file, {
folder: 'products',
metadata: { title: file.name }
});
}
};

return (
<div>
<input type="file" multiple onChange={(e) => handleUpload(e.target.files)} />
<input
type="search"
placeholder="Search assets..."
onChange={(e) => search(e.target.value)}
/>
{assets.map(asset => (
<img key={asset.id} src={asset.thumbnailUrl} alt={asset.metadata.title} />
))}
</div>
);
}

Error Handling

Status CodeError TypeDescription
400validation_errorInvalid request parameters
401authentication_errorInvalid or missing credentials
403authorization_errorInsufficient permissions
404not_foundAsset or folder not found
409conflictAsset already exists
413payload_too_largeFile exceeds size limit
415unsupported_media_typeFile type not allowed
429rate_limit_exceededToo many requests
500internal_errorServer error

Rate Limits

PlanUploads/minTransformations/minAPI Calls/min
Free101001,000
Pro1001,00010,000
EnterpriseUnlimitedUnlimitedCustom

Use This Block with AI Agents

This block ships an official Claude Code plugin from the public 23blocks marketplace (19 plugins, 205 skills). Your agent gets full working knowledge of this API — endpoints, identity registration, and conventions.

# one-time: add the 23blocks marketplace
claude plugin marketplace add https://github.com/23blocks-OS/ai-agents

# install this block's plugin
claude plugin install assets-block

Configure BLOCKS_API_URL, BLOCKS_API_KEY, and BLOCKS_AUTH_TOKEN. Register identity first: each block is autonomous — register the user with this block's identity endpoint before private calls (only user_unique_id is required; email/phone are optional notification-routing fields).

Full reference: AI Agents & Claude Code Plugins · github.com/23blocks-OS/ai-agents