Four requests change an asset already in the library, all with a key carrying
Edit the library through the API (assets.library.edit):
| Request | What it changes |
|---|---|
PATCH /v1/assets/{asset_id} |
its words — this page |
PUT /v1/assets/{asset_id}/tags |
its tags — this page |
PATCH /v1/assets/{asset_id}/custom-fields |
its custom fields |
PUT /v1/assets/{asset_id}/thumbnail |
its thumbnail |
Each answers the whole asset, as GET /v1/assets/{asset_id} reads it: one
shape to parse, whatever you wrote.
No permission implies another: a key that edits does not read the library for
that. A write answers what it wrote either way, but to find an asset before
editing it — by your external_ref, say —, the key also needs Read the library
through the API (assets.library.read).
Change its words
PATCH /v1/assets/{asset_id} writes the fields you send, and those alone:
curl -X PATCH https://api.videas.com/v1/assets/0192a6e4-3b5c-7d6e-8f90-a1b2c3d4e5f6 \
-H "Authorization: Bearer $VIDEAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"excerpt": "Three recycling processes, tried on the same offcuts.",
"seo_title": "Recycling carbon fibre: pyrolysis, solvolysis or grinding?",
"copyright": null
}'
| Field | What it holds | Bounds |
|---|---|---|
name |
Its title. | Never blank, never null: an asset always has one. 500 characters. |
description |
Its description. | 50,000 characters. |
excerpt |
A short summary, shown under the title where the description would not fit. | 1,000 characters. |
copyright |
The notice a reuser has to carry: who holds the rights, under what terms. | 1,000 characters. |
language |
The language of its content, as a BCP 47 tag (fr, en-GB, zh-Hans-CN). |
A well-formed tag. |
external_ref |
Your identifier for the asset. Not unique. | Never blank, 500 characters. |
seo_title |
The title a web page publishing it gives itself — in a browser’s tab and a search engine’s results. Without one, the page takes its name. |
Never blank, 255 characters. |
seo_description |
The description a page publishing it gives search engines and link previews. Without one, the page takes its excerpt, else its description. |
Never blank, 1,000 characters. |
Absent, null or a value
- A field left out stays as it is.
- A value replaces it.
nullempties it — but forname, refused with a400. Alanguageemptied becomes unknown.- An empty string empties
description,excerptandcopyrighttoo; onname,external_ref,seo_titleandseo_descriptionit is refused with a400— sendnullto empty them.
The answer is a 200 carrying the asset as it now is:
{
"id": "0192a6e4-3b5c-7d6e-8f90-a1b2c3d4e5f6",
"name": "Recycling carbon fibre: three processes compared",
"type": "third_party",
"status": "ready",
"workspace_id": "0192a6b1-7c3e-7d40-9a51-3f0e2b6c8d10",
"description": "Pyrolysis, solvolysis and mechanical grinding, put side by side on the same production offcuts.",
"external_ref": "webtv/2026/carbon-fibre-recycling",
"language": "en",
"duration_ms": null,
"created_at": "2026-10-15T08:30:12Z",
"updated_at": "2026-10-15T08:30:14Z",
"third_party": {
"provider": "youtube",
"video_id": "Xk3Ua9yQe7M",
"player_url": "https://www.youtube.com/embed/Xk3Ua9yQe7M"
},
"thumbnail_url": "https://app.videas.com/images/assets/0192a6e4-3b5c-7d6e-8f90-a1b2c3d4e5f6/thumbnail.jpg",
"excerpt": "Three recycling processes, tried on the same offcuts.",
"copyright": null,
"seo_title": "Recycling carbon fibre: pyrolysis, solvolysis or grinding?",
"seo_description": null,
"tags": [],
"custom_fields": []
}
What is not changed here: the asset’s type, its address, whether it is
listed, its expiry, its license and its thumbnail. A body naming any of these —
or any field the request does not list — is refused with a 422. The thumbnail
is changed with PUT …/thumbnail.
Its tags
PUT /v1/assets/{asset_id}/tags files the asset under the tags you name, by
their words — not by their ids:
curl -X PUT https://api.videas.com/v1/assets/0192a6e4-3b5c-7d6e-8f90-a1b2c3d4e5f6/tags \
-H "Authorization: Bearer $VIDEAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"tags": ["Carbon fibre", "Recycling"]}'
The answer is the whole asset, its tags ordered by name:
{
"id": "0192a6e4-3b5c-7d6e-8f90-a1b2c3d4e5f6",
"updated_at": "2026-10-15T08:30:14Z",
"tags": [
{ "id": "0192a690-3d4e-7f5a-8b6c-7d8e9f0a1b2c", "name": "Carbon fibre" },
{ "id": "0192a690-4e5f-7a6b-9c7d-8e9f0a1b2c3d", "name": "Recycling" }
]
}
(an excerpt: the answer carries every field of the asset.)
The list replaces the asset’s tags — except those Videas attaches itself
The tags you send replace the asset’s. A tag missing from the list is taken
off, and an empty list, {"tags": []}, takes off all of yours. The tags Videas
attaches itself stay, whatever you send: the answer carries them beside yours. So
send the complete list of what the asset should carry, never an addition.
Only Videas puts its own tags on. A word naming one of them changes nothing where
the asset already carries it, and is refused with a 400 where it does not.
One word, one tag
A word is matched to a tag by its letters and digits: case and accents do not
count, and any run of spaces or punctuation counts as one separator.
Carbon fibre, carbon-fibre and CARBON FIBRE are one tag; carbonfibre is
another. Two words of your list that name the same tag file it once.
Each word is looked for first among the tags of the asset’s workspace, then among the organization’s. A word that matches neither becomes a new tag of the organization, named as you wrote it; a tag that already exists keeps its own spelling.
A workspace may accept only the tags it already has. There, a word that
matches no tag is refused with a 400 — whose message quotes the first ten such
words and counts the rest — and nothing changes.
The bounds: at most 100 words, each at most 100 characters once the spaces around it are trimmed, never blank, and holding at least one Latin letter or digit. A refused word is named by its position in the list, from 0.
A tag a machine suggested and nobody confirmed is not among tags.
updated_at, and what changes nothing
updated_atmoves with the asset’s words and its thumbnail, never with its tags or its custom fields. To know whether an asset changed since your last sync, compare itstagsand itscustom_fieldsas well.- A request that changes nothing writes nothing: sending what the asset
already holds — its words, its tags — leaves it as it was,
updated_atincluded. - The last request to arrive wins: nothing checks what the asset held when you read it.
What the team sees
A change a key makes to an asset’s title, description, excerpt, copyright notice or language, to its tags or to its custom fields is recorded in the asset’s history, in Videas, under the key’s name. The people who look after the library see which integration did what: give each key a name that says it — “CMS sync”, “Catalog import”.
An asset validated in the shared pool is read-only
An asset your organization has validated in its shared pool cannot be changed
through the API: each of the four requests is refused with a 403, whatever the
key carries. Only that pool’s moderators can change it, from Videas.
This 403 has the same code, forbidden, as the one a key without
assets.library.edit gets. If your key edits other assets without trouble and one
alone refuses it, it is this lock: do not retry, and tell the team that moderates
the shared pool.
Retrying
PATCH and PUT say what the asset should hold: sent again as they are after a
timeout or a 5xx, they do nothing more, the second finding the asset in that
state already.
Errors
Every error has the same body — {"code": "…", "message": "…", "request_id": "…"}.
Branch on code; message is written for a human and may change.
| Status | code |
On PATCH /v1/assets/{asset_id} and PUT …/tags |
|---|---|---|
400 |
validation |
Words: a name blank or null; a blank external_ref, seo_title or seo_description; a field past its bound; a malformed language. Tags: more than 100 words; a word blank, too long or with no letter or digit; a word naming a tag Videas attaches itself, which the asset does not carry; a word no tag matches in a workspace that accepts only its own tags. And for both: an asset_id that is not a uuid, or a query parameter. The message names the field. |
401 |
unauthorized |
No key, or a key that is unknown, expired or revoked. |
403 |
forbidden |
The key does not carry assets.library.edit; or the asset is validated in the organization’s shared pool. |
404 |
not_found |
No asset GET /v1/assets lists has this id. |
409 |
conflict |
Tags only: a tag being created for one of your words was deleted at the same moment. Send the request again. |
415 |
unsupported_media_type |
The body is not sent as application/json. |
422 |
validation |
A field of the wrong type, or one the body does not list; for tags, tags missing or not a list of strings. |
429 |
rate_limited |
Too many requests: wait the number of seconds Retry-After gives. |
Next steps
- Custom fields — your organization’s own fields, and their values.
- An asset’s thumbnail — sending it, and showing it.
- Read the library — every field of an asset.
- The API reference, generated from its contract.