Getting Started
Page Assets API
Upload and manage files (images, documents, etc.) that belong to a page. Assets are stored in cloud storage and served via CDN.
Assets vs Data: Use Page Assets for binary files (images, PDFs). Use CmsData, TeamData, etc. for structured content. You can reference asset URLs in your data records.
PageAssets is NOT for team file uploads! PageAssets is owner-only — only the page creator can upload and delete. If you are building a team_app where team members need to upload files, use TeamData.uploadFile(), TeamData.listFiles(), and TeamData.getDownloadUrl(fileId) instead. These use the /api/pages/:id/team-files endpoint which respects team roles (member+ can upload, creator or admin+ can delete). See the Client-Side APIs section for details.
Full Guide: See the CMS Data & Page Assets Guide for a complete walkthrough with Python examples.
Tutorial: See Create a Blog with a Coding Agent for a step-by-step guide to building a full publication using Claude Code or any CLI coding agent.
Endpoints
/api/pages/:id/assets/generate
Generate an AI image and save as asset (owner only)
/api/pages/:id/assets
List all assets (public)
/api/pages/:id/assets
Upload a new asset (owner only)
/api/pages/:id/assets/:assetId
Delete an asset (owner only)
POST /api/pages/:id/assets/generate
Generate an AI image from a text prompt and automatically save it as a page asset. Returns the public CDN URL that you can use directly in page content, CmsData records, or HTML. This is the recommended way for AI agents to create images for blogs and pages — no need to use external image services like Unsplash.
Requires authentication (Bearer token or session) with pages:write scope. Only the page owner can generate images. The :id parameter can be a numeric page ID or a page slug.
Request Body
{
"prompt": "A futuristic city skyline at sunset, digital art style", // required, max 4000 chars
"aspectRatio": "16:9", // optional: "1:1" | "16:9" | "9:16" | "4:3" | "3:4" (default "1:1")
"filename": "hero-city" // optional: custom filename (auto-generated from prompt if omitted)
}Example
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"prompt": "A futuristic city skyline at sunset", "aspectRatio": "16:9", "filename": "hero-city"}' \
https://visimade.com/api/pages/123/assets/generateResponse (201)
{
"id": 12,
"filename": "hero-city-a1b2c3d4.jpg",
"publicUrl": "https://visimade-r2.com/page-assets/123/hero-city-a1b2c3d4.jpg",
"contentType": "image/jpeg",
"sizeBytes": 184320,
"createdAt": "2026-02-09T12:00:00Z"
}Use the publicUrl directly as the src for images in your HTML content or as the featuredImage URL in CmsData blog posts. The URL is a permanent CDN link — no need to resolve filenames at runtime.
For AI agents building blogs: Generate a hero image for each article and use the returned publicUrl in your CmsData post records. See the CMS Blog Example for the full workflow.
GET /api/pages/:id/assets
List all assets for a page. This endpoint is public - no authentication required. Returns asset metadata including the public CDN URL.
Example
curl https://visimade.com/api/pages/123/assets
Response
{
"assets": [
{
"id": 1,
"filename": "hero-image.jpg",
"content_type": "image/jpeg",
"size": 245678,
"url": "https://cdn.visimade.com/pages/123/assets/hero-image.jpg",
"created_at": "2024-01-15T10:30:00Z"
},
{
"id": 2,
"filename": "logo.png",
"content_type": "image/png",
"size": 12345,
"url": "https://cdn.visimade.com/pages/123/assets/logo.png",
"created_at": "2024-01-15T09:00:00Z"
}
]
}POST /api/pages/:id/assets
Upload a new asset. Only the page owner can upload. Requires pages:write scope. Use multipart/form-data with a file field.
Example
curl -X POST \ -H "Authorization: Bearer vm_your_token_here" \ -F "file=@/path/to/image.jpg" \ https://visimade.com/api/pages/123/assets
Response
{
"id": 3,
"filename": "image.jpg",
"content_type": "image/jpeg",
"size": 54321,
"url": "https://cdn.visimade.com/pages/123/assets/image.jpg",
"created_at": "2024-01-16T14:20:00Z"
}DELETE /api/pages/:id/assets/:assetId
Delete an asset. Only the page owner can delete. Requires pages:write scope.
curl -X DELETE \ -H "Authorization: Bearer vm_your_token_here" \ https://visimade.com/api/pages/123/assets/3
Client-Side Access
Pages automatically have access to window.PageAssets for runtime asset access:
// List all assets
const { assets } = await PageAssets.list();
// Get asset by filename
const asset = await PageAssets.getByFilename('logo.png');
if (asset) {
document.getElementById('logo').src = asset.url;
}
// Get URL directly
const heroUrl = await PageAssets.getUrl('hero-image.jpg');
// Upload new asset (owner only)
const newAsset = await PageAssets.upload(fileInput.files[0]);
// Delete asset (owner only)
await PageAssets.delete(assetId);
// Check if current user is page owner
if (PageAssets.isOwner()) {
showUploadButton();
}On this page
- Overview
- Endpoints
- POST - Generate Image
- GET - List Assets
- POST - Upload Asset
- DELETE - Delete Asset
- Client-Side Access