Workspace API

Media library

Media library endpoints of the Zanfia Workspace API, with schemas and code samples.

7 min readLast updated Sep 10, 2026

Upload files and videos for use in lessons and pages. Videos transcode after upload — poll the media item until uploadStatus is ready. You can also generate images with AI (synchronous; spends the workspace's AI credits) and start video transcription (spends transcription minutes; returns 202 — poll GET /media/{mediaId}/transcript for the result). All routes require a Authorization: Bearer header — see Authentication.

List media

GET/media

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Query Parameters

folder?string

Response Body

application/json

application/json

curl -X GET "https://example.com/media"
{  "count": 0,  "media": [    {      "id": "string",      "name": "string",      "type": "string",      "mimeType": "string",      "size": 0,      "url": "string",      "folder": "string",      "uploadStatus": "string",      "createdAt": "string"    }  ]}
{  "error": "string",  "message": "string"}

Upload a file

POST/media

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "https://example.com/media" \  -H "Content-Type: application/json" \  -d '{    "name": "string",    "mimeType": "string",    "data": "string"  }'
{  "mediaId": "string",  "url": "string",  "storagePath": "string"}
{  "error": "string",  "message": "string"}

Start a video upload

POST/media/videos/initiate-upload

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Begin a Bunny video upload: provisions a Bunny video object + a Pending MediaDocument, and returns a signed TUS credential. The caller then uploads the bytes DIRECTLY to Bunny (the file never passes through the API), and polls GET /media/:mediaId until uploadStatus is ready (Bunny finalizes via webhook).

Response Body

application/json

application/json

curl -X POST "https://example.com/media/videos/initiate-upload" \  -H "Content-Type: application/json" \  -d '{    "title": "string",    "sourceSizeBytes": 0  }'
{  "mediaId": "string",  "bunnyVideoId": "string",  "bunnyLibraryId": "string",  "signature": "string",  "expire": 0}
{  "error": "string",  "message": "string"}

Generate an AI image

POST/media/ai-images

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Generate ONE AI image into the Media Library. Synchronous (up to ~1 min); spends the workspace's AI credits. 402 no-credits, 413 storage-quota-exceeded, 502 image-generation-failed.

Response Body

application/json

application/json

curl -X POST "https://example.com/media/ai-images" \  -H "Content-Type: application/json" \  -d '{    "prompt": "string",    "aspectRatio": "1:1",    "quality": "1K"  }'
{  "mediaId": "string",  "url": "string",  "name": "string"}
{  "error": "string",  "message": "string"}

Move media into a folder

POST/media/move

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Files the items into folder (by NAME); folder: null unfiles them.

Response Body

application/json

application/json

curl -X POST "https://example.com/media/move" \  -H "Content-Type: application/json" \  -d '{    "mediaIds": [      "string"    ],    "folder": "string"  }'
{  "updatedCount": 0}
{  "error": "string",  "message": "string"}

Media detail

GET/media/{mediaId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

mediaId*string

Media id

Response Body

application/json

application/json

curl -X GET "https://example.com/media/string"
{  "media": {    "id": "string",    "name": "string",    "type": "string",    "mimeType": "string",    "size": 0,    "url": "string",    "folder": "string",    "uploadStatus": "string",    "createdAt": "string"  }}
{  "error": "string",  "message": "string"}

Update media details

PATCH/media/{mediaId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

mediaId*string

Media id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/media/string" \  -H "Content-Type: application/json" \  -d '{}'
{  "mediaId": "string",  "updated": true}
{  "error": "string",  "message": "string"}

Delete a media item

DELETE/media/{mediaId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

mediaId*string

Media id

Response Body

application/json

application/json

curl -X DELETE "https://example.com/media/string"
{  "status": "ok"}
{  "error": "string",  "message": "string"}

Video transcript

GET/media/{mediaId}/transcript

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

mediaId*string

Media id

Query Parameters

includeWords?boolean

true includes word-level timings (large payload).

Response Body

application/json

application/json

curl -X GET "https://example.com/media/string/transcript"
{  "transcription": {    "text": "string",    "language": "string",    "createdAt": "string",    "updatedAt": "string",    "words": [      {        "word": "string",        "start": 0,        "end": 0      }    ]  }}
{  "error": "string",  "message": "string"}

Start video transcription

POST/media/{mediaId}/transcribe

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

mediaId*string

Media id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Start background transcription for a video. Spends transcription minutes (duration-aware). 202 on accept; poll GET /media/:mediaId/transcript.

Response Body

application/json

application/json

curl -X POST "https://example.com/media/string/transcribe" \  -H "Content-Type: application/json" \  -d '{}'
{  "status": "queued",  "queuedAt": "string"}
{  "error": "string",  "message": "string"}

List folders

GET/media-folders

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Response Body

application/json

application/json

curl -X GET "https://example.com/media-folders"
{  "count": 0,  "folders": [    {      "id": "string",      "name": "string"    }  ]}
{  "error": "string",  "message": "string"}

Create a folder

POST/media-folders

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "https://example.com/media-folders" \  -H "Content-Type: application/json" \  -d '{    "name": "string"  }'
{  "folder": {    "id": "string",    "name": "string"  }}
{  "error": "string",  "message": "string"}

Rename a media folder

PATCH/media-folders/{name}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

name*string

Folder name

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Renaming onto an existing folder MERGES into it (the old folder is removed).

Response Body

application/json

application/json

curl -X PATCH "https://example.com/media-folders/string" \  -H "Content-Type: application/json" \  -d '{    "newName": "string"  }'
{  "folder": {    "id": "string",    "name": "string"  },  "updatedItemCount": 0}
{  "error": "string",  "message": "string"}

Delete a folder

DELETE/media-folders/{name}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

name*string

Folder name

Response Body

application/json

application/json

curl -X DELETE "https://example.com/media-folders/string"
{  "docDeleted": true,  "unfiledItemCount": 0}
{  "error": "string",  "message": "string"}

Was this article helpful?

Related articles

Spotted something off? Tell us at support@zanfia.com.