File upload, storage, and management. Media files are stored on Cloudflare R2 and served via CDN with automatic image transformation (thumbnails, resizing, format conversion).
Uploaded images automatically get multiple CDN variants:
thumbnail(150px)card(400px)content(800px)medium(1200px)
Deleted files go to trash first (soft delete). Use force delete for permanent removal.
12 endpoints
GET /media
List media files
Returns a paginated list of media files. Supports filtering by folder, file type, and search. Excludes trashed files.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| query | number | No | Number |
| query | number | No | Number <= 100 |
| query | string | No | Full-text search query |
| query | "created_at" | "updated_at" | "filename" | "size" | No | One of: created_at, updated_at, filename, size |
| query | "asc" | "desc" | No | One of: asc, desc |
| query | string | No | Filter from date (ISO 8601) |
| query | string | No | Filter until date (ISO 8601) |
| query | string | No | MIME type (e.g. image/jpeg) |
| query | number | No | Number |
| query | number | No | Number |
| query | string[] | No | Array of strings |
| query | string[] | No | Array of strings |
| query | string | No | Media folder UUID |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
Examples
# List images in a specific folder
curl "https://api.lynkow.com/v1/media?folderId=uuid-of-folder&type=image" \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filename": "hero-banner.jpg",
"originalName": "hero-banner.jpg",
"mimeType": "image/jpeg",
"size": 245760,
"width": 1920,
"height": 1080,
"alt": "Homepage hero banner",
"url": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=1200"
},
"folderId": "folder-uuid",
"createdAt": "2025-02-10T12:00:00.000Z"
}
],
"meta": {
"total": 156,
"perPage": 15,
"currentPage": 1,
"lastPage": 11
}
}GET /media/trash
List trashed files
Returns files that have been soft-deleted. These can be restored or permanently removed.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| query | number | No | Number |
| query | number | No | Number <= 100 |
| query | string | No | Full-text search query |
| query | "deleted_at" | "created_at" | "filename" | "size" | No | One of: deleted_at, created_at, filename, size |
| query | "asc" | "desc" | No | One of: asc, desc |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
Examples
curl https://api.lynkow.com/v1/media/trash \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"data": [
{
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"filename": "old-banner.jpg",
"originalName": "old-banner.jpg",
"mimeType": "image/jpeg",
"size": 198400,
"alt": "Old banner",
"url": "https://cdn.lynkow.com/sites/abc123/old-banner.jpg",
"deletedAt": "2025-04-02T10:00:00.000Z",
"createdAt": "2025-01-20T09:00:00.000Z"
}
],
"meta": {
"total": 5,
"perPage": 15,
"currentPage": 1,
"lastPage": 1
}
}DELETE /media/trash
Empty trash
Permanently deletes ALL trashed files. This action is irreversible and frees the associated storage.
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
Notes: - This operation can take time if many files are trashed.
Storage quota is updated after completion.
Examples
curl -X DELETE https://api.lynkow.com/v1/media/trash \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"deleted": 5
}POST /media/upload
Upload a file
Uploads a file via multipart/form-data. Supported file types include
images (jpg, png, gif, webp, svg, avif), documents (pdf), and more.
Request Body
Content-Type: multipart/form-data
Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Required |
| string | No | |
| boolean | No | Boolean |
| number | No | Between 100 and 4000 |
| number | No | Between 50 and 100 |
| string | No | Media folder UUID |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Validation error |
Notes: - Maximum file size: 50 MB.
Images are automatically processed to generate CDN variants.
Set
folderIdto organize the file into a folder.
Examples
curl -X POST https://api.lynkow.com/v1/media/upload \
-H "Authorization: Bearer $API_TOKEN" \
-F "[email protected]" \
-F "alt=A beautiful sunset" \
-F "folderId=uuid-of-folder"Response Example
{
"data": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"filename": "photo.jpg",
"originalName": "photo.jpg",
"mimeType": "image/jpeg",
"size": 185320,
"width": 1600,
"height": 900,
"alt": "A beautiful sunset",
"url": "https://cdn.lynkow.com/sites/abc123/photo.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/photo.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/photo.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/photo.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/photo.jpg?w=1200"
},
"folderId": "uuid-of-folder",
"createdAt": "2025-04-06T11:30:00.000Z"
}
}POST /media/upload-from-url
Import file from URL
Downloads a file from an external URL and stores it in your media library. Useful for migrating content from other platforms.
Request Body
Content-Type: multipart/form-data
Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Required |
| string | No | Display name |
| string | No | |
| string | No | Media folder UUID |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Validation error |
Notes: - The URL must be publicly accessible.
Maximum download size: 50 MB.
The file is downloaded server-side — no client upload needed.
Examples
curl -X POST https://api.lynkow.com/v1/media/upload-from-url \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://images.unsplash.com/photo-example.jpg",
"alt": "Mountain landscape",
"folderId": "uuid-of-folder"
}'Response Example
{
"data": {
"id": "c3d4e5f6-a7b8-9012-cdef-234567890123",
"filename": "photo-example.jpg",
"originalName": "photo-example.jpg",
"mimeType": "image/jpeg",
"size": 312400,
"width": 2400,
"height": 1600,
"alt": "Mountain landscape",
"url": "https://cdn.lynkow.com/sites/abc123/photo-example.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/photo-example.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/photo-example.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/photo-example.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/photo-example.jpg?w=1200"
},
"folderId": "uuid-of-folder",
"createdAt": "2025-04-06T11:45:00.000Z"
}
}GET /media/:id
Get media details
Returns full metadata for a media file including dimensions, file size, MIME type, CDN URL, and all image variants.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
Examples
curl https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filename": "hero-banner.jpg",
"originalName": "hero-banner.jpg",
"mimeType": "image/jpeg",
"size": 245760,
"width": 1920,
"height": 1080,
"alt": "Homepage hero banner",
"title": "Hero Banner",
"url": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=1200"
},
"folderId": "folder-uuid",
"folder": {
"id": "folder-uuid",
"name": "Banners"
},
"references": {
"contents": 3,
"siteBlocks": 1
},
"createdAt": "2025-02-10T12:00:00.000Z",
"updatedAt": "2025-03-15T09:30:00.000Z"
}
}PUT /media/:id
Update media metadata
Updates a file's metadata: alt text, description, title. Does not
modify the file itself — use POST /media/{id}/replace for that.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
| Validation error |
Examples
curl -X PUT https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"alt": "Updated alt text", "title": "New title"}'Response Example
{
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filename": "hero-banner.jpg",
"originalName": "hero-banner.jpg",
"mimeType": "image/jpeg",
"size": 245760,
"width": 1920,
"height": 1080,
"alt": "Updated alt text",
"title": "New title",
"url": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=1200"
},
"folderId": "folder-uuid",
"createdAt": "2025-02-10T12:00:00.000Z",
"updatedAt": "2025-04-06T12:00:00.000Z"
}
}DELETE /media/:id
Soft delete a file
Moves a file to trash. The file remains accessible via its CDN URL
for 30 days. Use POST /media/{id}/restore to recover it.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
Examples
curl -X DELETE https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"message": "File moved to trash"
}GET /media/:id/references
Find content using this file
Returns a list of contents and site blocks that reference this media file. Useful before deleting to check for broken references.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
Examples
curl https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890/references \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"data": [
{
"type": "content",
"id": 42,
"title": "Getting Started with Lynkow"
},
{
"type": "content",
"id": 55,
"title": "Advanced Configuration"
},
{
"type": "siteBlock",
"id": 1,
"title": "Header"
}
]
}POST /media/:id/replace
Replace a file
Replaces the file data while keeping the same ID and URL. Useful for updating an image without changing all references.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Request Body
Content-Type: multipart/form-data
Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Required |
| boolean | No | Boolean |
| number | No | Between 100 and 4000 |
| number | No | Between 50 and 100 |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
| Validation error |
Notes: - The CDN URL remains the same — existing references continue to work.
Old CDN cache may take a few minutes to refresh.
Examples
curl -X POST https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890/replace \
-H "Authorization: Bearer $API_TOKEN" \
-F "[email protected]"Response Example
{
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"filename": "new-hero-banner.jpg",
"originalName": "new-hero-banner.jpg",
"mimeType": "image/jpeg",
"size": 310200,
"width": 1920,
"height": 1080,
"alt": "Homepage hero banner",
"url": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg",
"variants": {
"thumbnail": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=150",
"card": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=400",
"content": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=800",
"medium": "https://cdn.lynkow.com/sites/abc123/hero-banner.jpg?w=1200"
},
"createdAt": "2025-02-10T12:00:00.000Z",
"updatedAt": "2025-04-06T12:00:00.000Z"
}
}POST /media/:id/restore
Restore from trash
Restores a soft-deleted file back to the media library.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
| Validation error |
Examples
curl -X POST https://api.lynkow.com/v1/media/d4e5f6a7-b8c9-0123-defa-456789012345/restore \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"data": {
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"filename": "old-banner.jpg",
"originalName": "old-banner.jpg",
"mimeType": "image/jpeg",
"size": 198400,
"alt": "Old banner",
"url": "https://cdn.lynkow.com/sites/abc123/old-banner.jpg",
"folderId": null,
"createdAt": "2025-01-20T09:00:00.000Z",
"updatedAt": "2025-04-06T12:00:00.000Z"
}
}DELETE /media/:id/force
Permanently delete a file
Immediately and permanently deletes a file, bypassing the trash. The CDN URL becomes invalid. This action is irreversible.
Parameters
Name | In | Type | Required | Description |
|---|---|---|---|---|
| path | string | Yes | Unique identifier |
Responses
Status | Description |
|---|---|
| Successful response |
| Unauthorized — invalid or missing API token |
| Forbidden — insufficient permissions |
| Not found |
Examples
curl -X DELETE https://api.lynkow.com/v1/media/a1b2c3d4-e5f6-7890-abcd-ef1234567890/force \
-H "Authorization: Bearer $API_TOKEN"Response Example
{
"message": "Permanently deleted"
}