Media operations

11 operations named media.*. Every one runs in a batch through apply_ops, dry_run_ops, the CLI or the admin.

Updated
OperationWhat it doesPermissionConfirmation
media.listList the media library with its folders, filtered by folder, kind and filename.site.readnone
media.usageList where a media row is used: the draft and published page trees and the published articles that reference it, the pages and articles whose featured or social image it is, the design-system asset tokens and the site settings that name it.site.readnone
media.recordUploadRecord a staged upload after re-inspecting its bytes: kind, dimensions, page count and variants.content.editnone
media.uploadUpload a file from its base64 bytes: staged, checked (type, size, magic, SVG sanitiser, quota), its variants rendered, then recorded like media.recordUpload, in its folder when one is named.content.editnone
media.replaceReplace the bytes of a media row with a staged upload, re-inspected like media.recordUpload (type, size, SVG sanitiser, variants, quota); the row keeps its id, alt text, caption, credit and folder, so every reference shows the new file.content.editnone
media.deleteRemove a media row from the library; its bytes stay for undo.site.editdestructive
media.updateEdit the alt text, caption, credit or folder of a media row.content.editnone
media.moveMove media rows into a folder, or to the top level with a null folder.site.editnone
media.createFolderCreate a media folder, at the top level or inside another folder.site.editnone
media.renameFolderRename a media folder.site.editnone
media.deleteFolderDelete an empty media folder; a folder holding media or folders is refused.site.editdestructive

media.list

List the media library with its folders, filtered by folder, kind and filename. Site ownership is checked; undo restores the media ledger.

permission: site.readreads onlyclass: read

Example input

{
  "kinds": [
    "image"
  ],
  "perPage": 50
}

Input

FieldTypeRequiredNotes
searchstringnoAt most 200 characters.
pageintegernoMore than 0.
perPageintegernoAt least 1. At most 100.
kindsarray of stringnoAt least 1 item. At most 4 items.
folderIdstring (uuid) | nullno

Output

FieldTypeRequiredNotes
itemsarray of objectyes
items[].idstring (uuid)yes
items[].kindstringyesOne of "image", "svg", "video", "document".
items[].filenamestringyesAt least 1 character. At most 255 characters.
items[].mimestringyesAt least 1 character. At most 127 characters.
items[].sizeintegeryesAt least 0.
items[].urlstringyesAt least 1 character. At most 2048 characters.
items[].widthintegernoAt least 1. At most 100000.
items[].heightintegernoAt least 1. At most 100000.
items[].variantsarray of objectyes
items[].altstring | record of stringyes
items[].captionstring | record of stringno
items[].creditstringnoAt most 200 characters.
items[].folderIdstring (uuid) | nullno
items[].pageCountintegernoAt least 1.
items[].createdAtstringyes
totalnumberyes
pagenumberyes
perPagenumberyes
usedBytesnumberyes
quotaBytesnumberyes
foldersarray of objectyes
folders[].idstring (uuid)yes
folders[].parentIdstring (uuid) | nullyes
folders[].namestringyesAt least 1 character. At most 120 characters.

Fields nested deeper are in the output schema that discover_operations answers with outputSchemas: true.

Try it

yarn splash media.list '{"kinds":["image"],"perPage":50}' --dry-run

media.usage

List where a media row is used: the draft and published page trees and the published articles that reference it, the pages and articles whose featured or social image it is, the design-system asset tokens and the site settings that name it. Site ownership is checked; undo restores the media ledger.

permission: site.readreads onlyclass: read

Example input

{
  "mediaId": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f"
}

Input

FieldTypeRequiredNotes
mediaIdstring (uuid)yes

Output

FieldTypeRequiredNotes
mediaIdstring (uuid)yes
usagesarray of object | object | objectyes

Try it

yarn splash media.usage '{"mediaId":"2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f"}' --dry-run

media.recordUpload

Record a staged upload after re-inspecting its bytes: kind, dimensions, page count and variants. Site ownership is checked; undo restores the media ledger.

permission: content.editwrites: mediaclass: transactionundo: yes

Example input

{
  "filename": "studio.jpg",
  "contentType": "image/jpeg",
  "size": 482113,
  "key": "staged/studio.jpg"
}

Input

FieldTypeRequiredNotes
filenamestringyesAt least 1 character. At most 255 characters.
contentTypestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
keystringyesAt least 1 character. At most 1024 characters.
folderIdstring (uuid) | nullno

Output

FieldTypeRequiredNotes
idstring (uuid)yes
kindstringyesOne of "image", "svg", "video", "document".
filenamestringyesAt least 1 character. At most 255 characters.
mimestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
urlstringyesAt least 1 character. At most 2048 characters.
widthintegernoAt least 1. At most 100000.
heightintegernoAt least 1. At most 100000.
variantsarray of objectyes
variants[].widthintegeryesAt least 1. At most 100000.
variants[].heightintegernoAt least 1. At most 100000.
variants[].mimestringyesOne of "image/avif", "image/webp", "image/jpeg", "image/png".
variants[].urlstringyesAt least 1 character. At most 2048 characters.
variants[].bytesintegernoAt least 0.
altstring | record of stringyes
captionstring | record of stringno
creditstringnoAt most 200 characters.
folderIdstring (uuid) | nullno
pageCountintegernoAt least 1.

Try it

yarn splash media.recordUpload '{"filename":"studio.jpg","contentType":"image/jpeg","size":482113,"key":"staged/studio.jpg"}' --dry-run

media.upload

Upload a file from its base64 bytes: staged, checked (type, size, magic, SVG sanitiser, quota), its variants rendered, then recorded like media.recordUpload, in its folder when one is named. The same limits as the admin upload (images 5 MB). Site ownership is checked; undo restores the media ledger.

permission: content.editwrites: mediaclass: transactionundo: yes

Example input

{
  "filename": "studio.jpg",
  "contentType": "image/jpeg",
  "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
}

Input

FieldTypeRequiredNotes
filenamestringyesAt least 1 character. At most 255 characters.
contentTypestringyesAt least 1 character. At most 127 characters.
datastringyesAt least 1 character. At most 146800640 characters.
folderIdstring (uuid) | nullno

Output

FieldTypeRequiredNotes
idstring (uuid)yes
kindstringyesOne of "image", "svg", "video", "document".
filenamestringyesAt least 1 character. At most 255 characters.
mimestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
urlstringyesAt least 1 character. At most 2048 characters.
widthintegernoAt least 1. At most 100000.
heightintegernoAt least 1. At most 100000.
variantsarray of objectyes
variants[].widthintegeryesAt least 1. At most 100000.
variants[].heightintegernoAt least 1. At most 100000.
variants[].mimestringyesOne of "image/avif", "image/webp", "image/jpeg", "image/png".
variants[].urlstringyesAt least 1 character. At most 2048 characters.
variants[].bytesintegernoAt least 0.
altstring | record of stringyes
captionstring | record of stringno
creditstringnoAt most 200 characters.
folderIdstring (uuid) | nullno
pageCountintegernoAt least 1.

Try it

yarn splash media.upload '{"filename":"studio.jpg","contentType":"image/jpeg","data":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="}' --dry-run

media.replace

Replace the bytes of a media row with a staged upload, re-inspected like media.recordUpload (type, size, SVG sanitiser, variants, quota); the row keeps its id, alt text, caption, credit and folder, so every reference shows the new file. The change is live: media is not versioned and published pages reference the row by id, so the published site shows the new file at once, without a publish. An image is replaced by an image or an SVG, a video by a video, a PDF by a PDF. Site ownership is checked; undo restores the media ledger.

permission: content.editwrites: mediaclass: transactionundo: yes

Example input

{
  "mediaId": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "filename": "studio-2.jpg",
  "contentType": "image/jpeg",
  "size": 501220,
  "key": "staged/studio-2.jpg"
}

Input

FieldTypeRequiredNotes
filenamestringyesAt least 1 character. At most 255 characters.
contentTypestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
keystringyesAt least 1 character. At most 1024 characters.
mediaIdstring (uuid)yes

Output

FieldTypeRequiredNotes
idstring (uuid)yes
kindstringyesOne of "image", "svg", "video", "document".
filenamestringyesAt least 1 character. At most 255 characters.
mimestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
urlstringyesAt least 1 character. At most 2048 characters.
widthintegernoAt least 1. At most 100000.
heightintegernoAt least 1. At most 100000.
variantsarray of objectyes
variants[].widthintegeryesAt least 1. At most 100000.
variants[].heightintegernoAt least 1. At most 100000.
variants[].mimestringyesOne of "image/avif", "image/webp", "image/jpeg", "image/png".
variants[].urlstringyesAt least 1 character. At most 2048 characters.
variants[].bytesintegernoAt least 0.
altstring | record of stringyes
captionstring | record of stringno
creditstringnoAt most 200 characters.
folderIdstring (uuid) | nullno
pageCountintegernoAt least 1.

Try it

yarn splash media.replace '{"mediaId":"2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f","filename":"studio-2.jpg","contentType":"image/jpeg","size":501220,"key":"staged/studio-2.jpg"}' --dry-run

media.delete

Remove a media row from the library; its bytes stay for undo. Site ownership is checked; undo restores the media ledger.

permission: site.editwrites: mediaclass: transactionconfirm: destructiveundo: yes

Example input

{
  "mediaId": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f"
}

Input

FieldTypeRequiredNotes
mediaIdstring (uuid)yes

Output

FieldTypeRequiredNotes
successtrueyes

Needs confirmed: ["destructive"] on the batch, which the single-operation CLI form does not set: put it in a batch file and run yarn splash apply <file> --dry-run.

media.update

Edit the alt text, caption, credit or folder of a media row. Site ownership is checked; undo restores the media ledger.

permission: content.editwrites: mediaclass: transactionundo: yes

Example input

{
  "mediaId": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "alt": {
    "en-US": "The studio courtyard at dusk"
  },
  "credit": "Studio archive"
}

Input

FieldTypeRequiredNotes
mediaIdstring (uuid)yes
altstring | record of stringno
captionstring | record of string | nullno
creditstring | nullno
folderIdstring (uuid) | nullno

Output

FieldTypeRequiredNotes
idstring (uuid)yes
kindstringyesOne of "image", "svg", "video", "document".
filenamestringyesAt least 1 character. At most 255 characters.
mimestringyesAt least 1 character. At most 127 characters.
sizeintegeryesAt least 0.
urlstringyesAt least 1 character. At most 2048 characters.
widthintegernoAt least 1. At most 100000.
heightintegernoAt least 1. At most 100000.
variantsarray of objectyes
variants[].widthintegeryesAt least 1. At most 100000.
variants[].heightintegernoAt least 1. At most 100000.
variants[].mimestringyesOne of "image/avif", "image/webp", "image/jpeg", "image/png".
variants[].urlstringyesAt least 1 character. At most 2048 characters.
variants[].bytesintegernoAt least 0.
altstring | record of stringyes
captionstring | record of stringno
creditstringnoAt most 200 characters.
folderIdstring (uuid) | nullno
pageCountintegernoAt least 1.

Try it

yarn splash media.update '{"mediaId":"2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f","alt":{"en-US":"The studio courtyard at dusk"},"credit":"Studio archive"}' --dry-run

media.move

Move media rows into a folder, or to the top level with a null folder. Site ownership is checked; undo restores the media ledger.

permission: site.editwrites: mediaclass: transactionundo: yes

Example input

{
  "mediaIds": [
    "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f"
  ],
  "folderId": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a"
}

Input

FieldTypeRequiredNotes
mediaIdsarray of string (uuid)yesAt least 1 item. At most 200 items.
folderIdstring (uuid) | nullyes

Output

FieldTypeRequiredNotes
movedintegeryesAt least 0.

Try it

yarn splash media.move '{"mediaIds":["2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f"],"folderId":"3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a"}' --dry-run

media.createFolder

Create a media folder, at the top level or inside another folder. Site ownership is checked; undo restores the media ledger.

permission: site.editwrites: mediaclass: transactionundo: yes

Example input

{
  "name": "Projects",
  "parentId": null
}

Input

FieldTypeRequiredNotes
namestringyesAt least 1 character. At most 120 characters.
parentIdstring (uuid) | nullno

Output

FieldTypeRequiredNotes
idstring (uuid)yes
parentIdstring (uuid) | nullyes
namestringyesAt least 1 character. At most 120 characters.

Try it

yarn splash media.createFolder '{"name":"Projects","parentId":null}' --dry-run

media.renameFolder

Rename a media folder. Site ownership is checked; undo restores the media ledger.

permission: site.editwrites: mediaclass: transactionundo: yes

Example input

{
  "folderId": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
  "name": "Built projects"
}

Input

FieldTypeRequiredNotes
folderIdstring (uuid)yes
namestringyesAt least 1 character. At most 120 characters.

Output

FieldTypeRequiredNotes
idstring (uuid)yes
parentIdstring (uuid) | nullyes
namestringyesAt least 1 character. At most 120 characters.

Try it

yarn splash media.renameFolder '{"folderId":"3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a","name":"Built projects"}' --dry-run

media.deleteFolder

Delete an empty media folder; a folder holding media or folders is refused. Site ownership is checked; undo restores the media ledger.

permission: site.editwrites: mediaclass: transactionconfirm: destructiveundo: yes

Example input

{
  "folderId": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a"
}

Input

FieldTypeRequiredNotes
folderIdstring (uuid)yes

Output

FieldTypeRequiredNotes
successtrueyes

Needs confirmed: ["destructive"] on the batch, which the single-operation CLI form does not set: put it in a batch file and run yarn splash apply <file> --dry-run.

Generated from the operation registry and the MCP tool catalogue (source 0eff2e5995d25e02).

Something wrong on this page? Write to docs@librettocms.com.

Libretto docs

Colophon. These docs are a Libretto site: 68 pages in two languages, 20 guide pages imported from Markdown and 41 reference pages generated from the operation registry. Set in Softcore, with code in IBM Plex Mono. Its outline:

/ Libretto docs /start Get started /start/request-access Request access /start/workspace Your workspace /start/first-site Your first site /start/invite-a-client Invite a client /start/connect-claude Connect Claude to Libretto /build Build /build/first-page Build a page /build/layers-and-canvas Layers and canvas /build/site-components Site components /design-system Design system /design-system/tokens Colours, space and themes /design-system/components Components and variants /design-system/fonts Typography and fonts /motion Motion /motion/scenes Scenes and recipes /motion/image-sequences Image sequences /motion/reduced-motion Reduced motion /publish Publish /publish/languages Site languages /publish/versions Publish and versions /publish/members-and-forms Members and forms /publish/domains Domains /handover Hand a site to a client /glossary Glossary /agents Agents and API /agents/mcp MCP server /agents/cli CLI /agents/batches Batches /agents/errors Errors and findings /agents/operations Operations /search Search