Skip to main content

Media API

Upload, manage, and retrieve media files (images, documents, videos) programmatically.

Try it — API Explorer

API Explorer
Parameters
Show cURL
curl \
  "https://your-site.clearcms.app/api/v1/public/media"

Authentication

Authenticated endpoints require your API key as a Bearer token:

Authorization: Bearer YOUR_API_KEY

Public endpoints work without authentication but return fewer fields.

Public endpoints

No authentication required. These endpoints support CORS.

List media

GET /api/v1/public/media

cURL:

curl https://your-site.clearcms.app/api/v1/public/media

Query parameters:

ParameterTypeDescription
folderstringFilter by folder path (e.g. /images)
typestringFilter by type: image, document, or video
limitintegerResults per page. Default: 24. Max: 100
offsetintegerPagination offset

With an API key, search, sort, and order parameters are also available.

Response:

{
"data": [
{
"id": "media_abc123",
"filename": "product.jpg",
"mimeType": "image/jpeg",
"width": 1920,
"height": 1080,
"alt": "Product showcase",
"url": "/uploads/2026/03/abc123.jpg",
"focalX": 50,
"focalY": 50
}
],
"total": 45,
"limit": 24,
"offset": 0
}

Get a media item

GET /api/v1/public/media/{id}

Returns a single media item by ID. Cached for 1 hour.


Authenticated endpoints

Require an API key. Return full metadata including size, title, description, folder, and createdAt.

List media (full)

GET /api/v1/media

Query parameters:

ParameterTypeDescription
folderstringFilter by folder path
typestringFilter by type: image, document, video
searchstringSearch filename and alt text
limitintegerResults per page. Default: 24
offsetintegerPagination offset
sortstringSort by createdAt, filename, or size. Default: createdAt
orderstringasc or desc. Default: desc

Response:

{
"data": [
{
"id": "media_abc123",
"filename": "product.jpg",
"mimeType": "image/jpeg",
"size": 245000,
"width": 1920,
"height": 1080,
"alt": "Product showcase",
"title": "Product Image",
"description": "High-quality product photo",
"url": "/uploads/2026/03/abc123.jpg",
"folder": "/images/products",
"focalX": 50,
"focalY": 50,
"createdAt": "2026-03-26T10:30:00Z"
}
],
"total": 45,
"limit": 24,
"offset": 0,
"folders": ["/", "/images", "/documents", "/logos"]
}

Get a media item (full)

GET /api/v1/media/{id}

Returns the full media item including all metadata fields.


Upload media

POST /api/v1/media
Content-Type: multipart/form-data

cURL:

curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@photo.jpg" \
-F "folder=/images" \
https://your-site.clearcms.app/api/v1/media

Form fields:

FieldTypeRequiredDescription
filesFile[]YesOne or more files to upload
folderstringNoTarget folder path (default: /)
altstringNoAlt text for images

Response (201):

{
"data": [
{
"id": "media_def456",
"filename": "banner.png",
"mimeType": "image/png",
"size": 512000,
"width": 1200,
"height": 400,
"url": "/uploads/2026/03/def456.png",
"folder": "/",
"focalX": 50,
"focalY": 50,
"createdAt": "2026-03-26T11:00:00Z"
}
],
"errors": []
}

Supported file types: JPEG, PNG, GIF, WebP, SVG, PDF, MP4, WebM

Size limits: 50 MB (local storage), 500 MB (cloud storage)

Images are automatically optimized into multiple sizes (150px, 400px, 800px, 1200px) and converted to WebP.


Update media metadata

PATCH /api/v1/media/{id}

Request body:

{
"alt": "Updated alt text",
"title": "New title",
"description": "New description",
"folder": "/images/updated",
"focalX": 35,
"focalY": 65
}

All fields are optional. focalX and focalY are percentages (0–100) that set the focal point for smart cropping.


Delete media

DELETE /api/v1/media/{id}

Returns { "success": true } on success.


Presigned uploads

For large files, use presigned URLs to upload directly to cloud storage (R2/S3), bypassing your server.

1. Request a presigned URL

POST /api/v1/media/presign

cURL:

curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename":"video.mp4","mimeType":"video/mp4","size":500000000}' \
https://your-site.clearcms.app/api/v1/media/presign

Request body:

{
"filename": "large-video.mp4",
"mimeType": "video/mp4",
"size": 500000000
}

Response:

{
"uploadUrl": "https://storage.example.com/signed-url...",
"publicUrl": "https://cdn.example.com/2026/03/abc123.mp4",
"storageKey": "site_id/2026/03/abc123.mp4",
"expiresAt": "2026-03-26T12:30:00Z",
"method": "PUT",
"headers": {
"Content-Type": "video/mp4"
}
}

2. Upload the file

Send the file to the uploadUrl with the headers from the response:

await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "video/mp4" },
body: fileBlob,
});

3. Confirm the upload

POST /api/v1/media/confirm

Request body:

{
"storageKey": "site_id/2026/03/abc123.mp4",
"filename": "large-video.mp4",
"mimeType": "video/mp4",
"size": 500000000,
"folder": "/videos"
}

Response (201):

{
"success": true,
"data": {
"id": "media_xyz789",
"filename": "large-video.mp4",
"url": "https://cdn.example.com/2026/03/abc123.mp4",
"folder": "/videos",
"createdAt": "2026-03-26T11:45:00Z"
}
}

Presigned uploads require a cloud storage adapter (R2, S3). Sites using local storage should use the regular upload endpoint.


Folders

List folders

GET /api/v1/media/folders

Returns all folder paths as a flat array:

{
"folders": ["/", "/images", "/images/products", "/documents", "/logos"]
}

Create a folder

POST /api/v1/media/folders
{
"path": "/images/new-category"
}

Delete a folder

DELETE /api/v1/media/folders
{
"path": "/images/old-category"
}

Folders must be empty before deletion. The root folder / cannot be deleted.


Error responses

Errors follow the same format as the Headless API.

StatusMeaning
400Invalid request (bad file type, focal point out of range, invalid folder path)
401Missing or invalid API key
403Insufficient permissions
404Media item or folder not found
500Server error
Was this page helpful?