Assets & Images
CellCMS provides a complete asset pipeline for images and files with on-the-fly image transforms, metadata extraction, and pluggable storage backends.
Uploading Assets
Upload images and files via multipart form data:
curl -X POST https://api.cellcms.com/api/v1/assets/production \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@photo.jpg"
Response:
{
"_id": "asset-uuid",
"_type": "image",
"assetId": "asset-uuid",
"path": "project-id/production/asset-uuid.jpg",
"url": "/api/v1/assets/asset-uuid",
"metadata": {
"width": 1920,
"height": 1080,
"format": "jpeg",
"hasAlpha": false,
"palette": {
"dominant": "#2b5797",
"vibrant": "#ff6600"
}
}
}
Limits:
- Maximum file size: 50 MB
- Supported image formats: JPEG, PNG, WebP, AVIF, GIF, TIFF, SVG
- Any file type can be uploaded (PDFs, videos, etc.) — image transforms only apply to supported image formats
Uploading via the Client SDK
// The client SDK doesn't have a built-in upload method,
// but you can use the fetch API directly:
const formData = new FormData()
formData.append('file', fileInput.files[0])
const response = await fetch(
`${apiUrl}/api/v1/assets/production`,
{
method: 'POST',
headers: { Authorization: `Bearer ${token}` },
body: formData,
}
)
const asset = await response.json()
Uploading via Studio
In the document editor, click on an image or file field to open the upload dialog. You can drag and drop files or click to browse.
Image Transforms
CellCMS transforms images on the fly using Sharp. Add query parameters to any asset URL to get a transformed version.
Transform Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
w | number | Width in pixels | ?w=400 |
h | number | Height in pixels | ?h=300 |
fit | string | Resize behavior | ?fit=cover |
format | string | Output format | ?format=webp |
q | number | Quality (1–100) | ?q=80 |
blur | number | Gaussian blur radius | ?blur=10 |
dpr | number | Device pixel ratio | ?dpr=2 |
Fit Modes
| Mode | Description |
|---|---|
cover | Crop to fill the exact dimensions (default) |
contain | Resize to fit within dimensions, preserving aspect ratio |
fill | Stretch to fill exact dimensions |
Output Formats
| Format | Best For |
|---|---|
webp | Modern browsers, best compression |
avif | Modern browsers, smallest files |
jpeg | Universal compatibility |
png | Transparency, lossless |
Examples
Thumbnail (200×200, cropped):
/api/v1/assets/abc123?w=200&h=200&fit=cover
Responsive hero image (WebP, 80% quality):
/api/v1/assets/abc123?w=1200&format=webp&q=80
Retina display (2x DPR):
/api/v1/assets/abc123?w=400&dpr=2
This delivers an 800px image that displays at 400px on retina screens.
Blurred placeholder:
/api/v1/assets/abc123?w=20&blur=10&q=30
Format conversion (PNG → WebP):
/api/v1/assets/abc123?format=webp&q=85
Responsive Images in HTML
<picture>
<source
srcset="/api/v1/assets/abc123?w=800&format=avif&q=80"
type="image/avif"
/>
<source
srcset="/api/v1/assets/abc123?w=800&format=webp&q=80"
type="image/webp"
/>
<img
src="/api/v1/assets/abc123?w=800&q=85"
srcset="
/api/v1/assets/abc123?w=400&q=80 400w,
/api/v1/assets/abc123?w=800&q=80 800w,
/api/v1/assets/abc123?w=1200&q=80 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
alt="Description"
loading="lazy"
/>
</picture>
Metadata
When an image is uploaded, CellCMS automatically extracts metadata using Sharp:
{
"width": 1920,
"height": 1080,
"format": "jpeg",
"hasAlpha": false,
"palette": {
"dominant": "#2b5797",
"vibrant": "#ff6600"
}
}
| Field | Description |
|---|---|
width | Image width in pixels |
height | Image height in pixels |
format | Detected format (jpeg, png, webp, etc.) |
hasAlpha | Whether the image has an alpha channel |
palette | Extracted color palette (dominant and vibrant colors) |
This metadata is stored with the asset record and returned in list and detail endpoints.
Caching
Transformed images are cached for optimal performance:
- Cache headers:
Cache-Control: public, max-age=31536000, immutable(1 year) - ETag support: Returns
304 Not Modifiedwhen the asset hasn't changed - Transform cache: Transformed versions are cached in storage after first request
- Cache key: Based on asset ID + transform parameters
The immutable cache policy means browsers and CDNs will cache transformed images indefinitely. Since asset URLs include the asset ID, uploading a new version creates a new URL automatically.
Storage Configuration
CellCMS supports two storage backends:
Local Storage (Default)
Files are stored on the local filesystem:
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=./uploads
In Docker, uploads are persisted in a named volume (cellcms-uploads).
S3-Compatible Storage
Store files in Amazon S3, Cloudflare R2, MinIO, or any S3-compatible service:
STORAGE_TYPE=s3
S3_BUCKET=my-cellcms-assets
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
For Cloudflare R2 or MinIO, set the custom endpoint:
S3_ENDPOINT=https://your-account.r2.cloudflarestorage.com
Storage Key Format
Assets are stored with the key pattern:
{projectId}/{dataset}/{assetId}{extension}
Example: proj-uuid/production/asset-uuid.jpg
Listing Assets
List all assets in a dataset:
curl "https://api.cellcms.com/api/v1/assets/production/list?type=image&limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"
Response:
{
"items": [
{
"id": "asset-uuid",
"type": "image",
"filename": "hero.jpg",
"mime_type": "image/jpeg",
"size": 245760,
"url": "/api/v1/assets/asset-uuid",
"metadata": { "width": 1920, "height": 1080 },
"created_at": "2025-01-15T10:00:00Z"
}
],
"total": 42
}
Filter by type: ?type=image or ?type=file
Paginate with ?limit=20&offset=40
Deleting Assets
curl -X DELETE https://api.cellcms.com/api/v1/assets/production/asset-uuid \
-H "Authorization: Bearer YOUR_TOKEN"
This removes the file from storage and the record from the database.
Using Assets in Documents
Reference uploaded assets in your document content:
{
"_type": "post",
"title": "My Post",
"coverImage": {
"_type": "image",
"asset": {
"_ref": "asset-uuid",
"_type": "reference"
},
"hotspot": {
"x": 0.5,
"y": 0.3,
"width": 0.8,
"height": 0.6
}
}
}
The hotspot field defines the focal point and crop region for the image, ensuring important content stays visible at any aspect ratio.
Related Documentation
- API Reference — Asset endpoints
- Schema Definition — Image and file field types
- Deployment — Storage configuration