library.
The library. endpoints under /api/v1/library manage media of any kind:
videos, programmes, clips, podcasts, music or not. There is no entity layer:
you work on the media and its files directly.
- Media is one piece of content. It carries a name, free-form
metadata, workflowstatusvalues and the DMRNs that identify it in your systems. - Assets are the files of a media: video, audio, image and WebVTT subtitle files. Each asset lists the storage locations holding its file.
- Storage lists where your files live: your organisation's deliver.media platform storage, and your own storage account when you connected one.
- Subtitle tracks are parsed from WebVTT files, one or more versions per language.
- Channels and timelines say which media plays when. They are the same timelines managedradio. plays out.
A media created through the API is the same media your team sees in the library. app, and the reverse.
Access
The library. endpoints need an API key with the deliverdotmedia:library:api
permission (see Authentication). API access is part of
the library. Enterprise plan and of the Public API option. A request from an
organisation whose plan does not include API access answers 402 with the
error code plan_required.
Identify media with your own IDs
Attach the identifier your system already uses, as a DMRN, and look the media up by it instead of storing our ids:
# Create the media with your reference
curl -X POST https://public-api.deliver.media/api/v1/library/media \
-H "Authorization: Bearer sk_..." -H "Content-Type: application/json" \
-d '{
"name": "Evening news 2026-09-28",
"metadata": { "programme": "Evening news", "season": 12 },
"reference": "dmrn:customer:mam:ch:acme:programme/EN-20260928"
}'
# Find it again later
curl "https://public-api.deliver.media/api/v1/library/media?reference=dmrn:customer:mam:ch:acme:programme/EN-20260928" \
-H "Authorization: Bearer sk_..."
A media may carry several DMRNs (add more with
POST /api/v1/library/media/{id}/references), but a DMRN identifies one
object only: attaching one that is already in use answers 409.
Metadata and statuses
PATCH /api/v1/library/media/{id}mergesmetadataone top-level key at a time: keys you send replace their value, keys you leave out are kept. Values may be strings, numbers, booleans,null, nested objects or arrays.PATCH /api/v1/library/media/{id}/statussets workflow states such as{ "status": { "subtitles": "DONE", "legal": "PENDING" } }. The library. app shows each status type as a column and filters by it. Set a type tonullto remove it.
Upload a file
Files never pass through the API itself: you upload them straight to storage with a signed URL.
-
Create the asset on the media. The MIME type decides the asset type (
video/*,audio/*,image/*,text/vtt):curl -X POST https://public-api.deliver.media/api/v1/library/media/{id}/assets \-H "Authorization: Bearer sk_..." -H "Content-Type: application/json" \-d '{ "name": "evening-news.mp4", "mimeType": "video/mp4", "sizeInBytes": 734003200 }'The response carries an
assetIdand anuploadtarget. -
PUTthe raw file bytes (not multipart form data) toupload.url, sending every header ofupload.headers, beforeupload.expiresOn. -
Confirm it with
POST /api/v1/library/assets/{assetId}/confirm. The asset becomesONLINE. A confirmed video is queued for video analysis, exactly as when it is uploaded in the library. app.
Read the file back with GET /api/v1/library/assets/{id}/download, which
signs a short-lived URL. Request a fresh one each time rather than storing it.
GET /api/v1/library/assets/{id} returns the asset's technical data (once the
file has been probed) and its storage locations; storageId points to an entry
of GET /api/v1/library/storage (it is null only for files stored before your
organisation had a storage of its own).
Add subtitles
-
Upload the
.vttfile as an asset of the media withmimeType: text/vtt,PUTit and confirm it, as above. Subtitle files are limited to 10 MiB. -
Create the track:
curl -X POST https://public-api.deliver.media/api/v1/library/media/{id}/subtitles \-H "Authorization: Bearer sk_..." -H "Content-Type: application/json" \-d '{ "assetId": "…", "language": "de-CH" }'
Each upload of a language becomes a new version and the active one of that
language: the version the player shows and AI AutoCut uses. Promote an older
version with POST /api/v1/library/subtitles/{trackId}/activate, read the cues
with GET /api/v1/library/subtitles/{trackId}/cues. A track used by an AI
AutoCut session cannot be deleted (409).
Import a schedule
PUT /api/v1/library/channels/{channelId}/timelines creates or updates
timelines, their events and the media the events play. Everything is keyed by
DMRNs from your system, so you can resend a day whenever it changes: the same
references update the same timelines, events and media. List channel ids with
GET /api/v1/library/channels.
{
"timelines": [
{
"reference": "dmrn:customer:playout:ch:acme:timeline/2026-09-28-morning",
"name": "Morning show",
"startTime": "2026-09-28T06:00:00+02:00",
"events": [
{
"reference": "dmrn:customer:playout:ch:acme:event/81723",
"startTime": "2026-09-28T06:00:00+02:00",
"endTime": "2026-09-28T06:03:30+02:00",
"media": {
"reference": "dmrn:customer:mam:ch:acme:programme/JINGLE-07",
"name": "Station jingle 07",
"metadata": { "category": "jingle" }
}
}
]
}
]
}
Rules worth knowing:
- Times must carry an offset (
Zor+02:00). - Send events in play order. Each timeline and event reference may appear once per import.
- The import is a sliding window: events of a timeline that start after the first event you send and are missing from your list are deleted. Events before it are kept, so resending the rest of the day never touches what already aired.
- An event's
media.metadatareplaces that media's metadata: send all of it.
Read timelines back with GET /api/v1/library/timelines (filter by
channelId, from and to) and GET /api/v1/library/timelines/{id}, which
returns every event in play order with the mediaId it plays.
Errors and limits
Errors use the same envelope as every endpoint of the API:
{ "error": { "code": "media_not_found", "message": "No media with id …" } }
The library. endpoints share the ordinary limit of 120 requests per minute per API key described in Getting started.