Everything on this page holds for every endpoint of /v1: one handler on your
side can read every refusal, and one retry policy covers every call.
One error shape
Whatever the status, an error answers the same body:
{
"code": "not_found",
"message": "no asset of this organization has this id",
"request_id": "0192a6d3-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}
codeis what your code branches on. A code keeps its meaning for good, and the list may grow: read a code you do not know by the HTTP status it came with.messageis English, written for a person — log it, show it to a developer, never branch on it: it may change at any time.request_ididentifies the request: quote it when you ask us about a failure. It is absent, nevernull, when the server has none to give.
Statuses and codes
| Status | code |
What happened | What to do |
|---|---|---|---|
400 |
validation |
A parameter, or a value in the body, that the endpoint’s rules refuse. The message says which. | Fix the request. |
401 |
unauthorized |
No Authorization: Bearer header, or a key that is unknown, expired or revoked. |
Send a valid key. |
403 |
forbidden |
The key does not carry the permission the endpoint requires; or the organization does not have what it serves — channels; or the asset is read-only (see below). | Use a key created with that permission. |
404 |
not_found |
Nothing your organization can reach has this identifier — in the path or in the body. | — |
409 |
conflict |
The request contradicts the resource’s state (see below). | Read the current state again rather than sending the same request. |
413 |
payload_too_large |
A file larger than 10 GiB, or a thumbnail larger than 10 MiB. | Send less. |
415 |
unsupported_media_type |
A body sent under a Content-Type the endpoint does not take. |
Send JSON, or the picture under its type. |
422 |
validation |
A JSON body that is not the request: a field missing, of the wrong type, or one the body does not list. | Fix the body. |
429 |
rate_limited |
More than the API accepts right now, from this key or its organization. | Wait the seconds Retry-After gives, then send it again. |
500 |
internal |
A failure on our side. | Retry after a growing delay; quote the request_id if it lasts. |
502 |
upstream_error |
A service called on your behalf failed — the provider of a video hosted elsewhere, for instance. Nothing was created. | Send the request again in a moment. |
503 |
service_unavailable |
The service cannot answer right now. | Retry after a growing delay. |
504 |
timed_out |
The server stopped waiting for this request. | A GET, a PATCH or a PUT is safe to send again; for a POST, see below. |
The API reference lists, for each endpoint, the refusals it may answer.
A body refused: 415, 422 or 400
Every body is JSON, but a thumbnail’s, which is the picture itself. A body is refused for one of three reasons, and each has its status:
415— it is not sent under the rightContent-Type: a JSON body outsideapplication/json, a thumbnail outsideimage/jpeg,image/pngorimage/webp;422— it is not the request: a required field is missing, a field has the wrong type, or the body names a field the request does not list;400— it is the request, but a value is refused by its rules: too long, malformed, contradicting another. The message names the field.
The API does not ignore what it does not understand: an unknown field in a
body is refused rather than ignored, and so is a query parameter — one the
endpoint does not list, or one given twice (400). ?typ=video is refused rather
than served unfiltered, and a write takes no query parameter at all. A typo is an
error you see at once, never a setting quietly ignored.
An identifier in a body: 404
An identifier sent in a body — a workspace, a channel, an asset, a custom field —
that names nothing your key can reach is a 404, whether it names nothing at
all or something of another organization’s. It is the same answer as for an
identifier in the path.
A publication’s categories are the exception: a category that is not one of the
publication’s channel is refused with a 400, which names it.
The 403s that are not a permission
A key carrying the right permission may still get a 403:
- the organization does not publish channels: every channel, category and
publication endpoint answers
403to all of its keys; - the asset is validated in the organization’s shared pool: it is read-only
to the API, and each of the requests that change it answers
403, whatever the key carries — only the pool’s moderators change it, from Videas. See Edit an asset.
Neither is retried.
The 409s
A 409 says the request contradicts the resource’s state. Reading that state again
says what to do:
| Request | The 409 |
What to do |
|---|---|---|
DELETE /v1/uploads/{upload_id} |
The upload has finished already: its file belongs to the asset. | Nothing: the upload can no longer be given up. |
PUT /v1/assets/{asset_id}/tags |
A tag being created for one of your words was deleted at the same moment. | Send the request again. |
POST /v1/publications |
The asset is already published on this channel. | GET /v1/publications?channel_id=…&asset_id=… answers its publication. |
POST /v1/publications |
The asset is not ready yet. |
Send it again once the asset is ready. |
POST and PATCH /v1/publications |
The slug is taken by another publication or a page of the channel. |
Choose another address — the message names the one taken. |
PATCH /v1/publications/{publication_id} |
access would move a publication that is restricted, paid or on_request. |
Nothing through the API: those are set from Videas. |
| Any write on the channels | The organization’s channels are still being moved to Videas, and are changed from the platform they are moving from until the move is complete. | Wait for the move to complete. Reads answer as usual. |
Retrying
429: wait the number of secondsRetry-Aftergives, then send the same request again.500,502,503,504: retry after a growing delay — an exponential back-off.- A
GETis always safe to send again, and so are aPATCHand aPUT: each says what the resource should hold, and sent twice, the second finds it holding that already and writes nothing. DELETE /v1/uploads/{upload_id}is safe to send again: an upload already given up on, expired or failed answers204and stays as it is.- A
POSTcreates something: after a timeout or a5xx, look for what the first one may have created before sending it again.POST /v1/uploadsandPOST /v1/assetsare not idempotent: sent twice, they create two assets. Setexternal_refevery time, and look it up withGET /v1/assets?external_ref=before sending again — for a file as for a video hosted elsewhere.POST /v1/publicationspublishes an asset once on a channel: sent again, it answers409, andGET /v1/publications?channel_id=…&asset_id=…finds the publication the first one made.
Limits
These are the limits the contract publishes:
| Limit | Value |
|---|---|
| A file, sent or fetched from a link | 10 GiB |
A PUT to upload_url, a tus chunk |
the upload’s max_put_bytes |
| A tus chunk, but the last | at least 5 MiB |
| Time to send a file | until the upload’s expires_at |
| Redirects followed to fetch a link | five, never from https to http |
| Links waiting or downloading at once, per organization | bounded — past it, a 429 with Retry-After |
| A thumbnail | 10 MiB, as a JPEG, a PNG or a WebP |
An asset’s name, external_ref |
500 characters |
An asset’s description |
50,000 characters |
An asset’s excerpt, copyright, seo_description |
1,000 characters |
An asset’s seo_title |
255 characters |
| An asset’s tags, in one request | 100 words, of 100 characters each |
| Custom field values, in one request | 200, of 256 KiB each |
| A publication’s categories | 100 |
A publication’s slug |
255 characters |
| Rows per page | limit, lowered to the endpoint’s cap past it |
Beyond these, any request may be refused with a 429 when a key, or its
organization, sends more than the API accepts: the answer always carries
Retry-After, and waiting that long is all it asks.
What may change under /v1
Without a new version, the API may gain:
- a new endpoint;
- a new optional query parameter;
- a new field in an answer;
- a new value in a list of values — an error’s or a failure’s
code, an upload’sstatus, and those of the table below.
Write your client to read a field or a value it does not know as something it does not know yet, not as an error. For some lists, the contract says how to read a value you do not know:
| List | A value you do not know reads as |
|---|---|
An asset’s type and status |
a value your client does not handle yet |
third_party.provider |
other |
A custom field’s type |
a field your client neither reads nor writes |
A publication’s status |
a publication the channel does not show |
A publication’s access |
restricted |
Never under /v1: removing or renaming anything, changing a type or a unit,
or refusing a request that used to be accepted. That would be a new version,
/v2.
Next steps
- Get started — a key, its permissions, and a first call.
- Read the library.
- Add a file with the API.
- Edit an asset and publish on a channel.