Errors
The error envelope, every error code the API returns, and which errors are safe to retry.
Every error has the same JSON shape and a stable machine code. Branch on code and the HTTP status, never on message: messages are written for people and can change.
The error envelope
{
"error": {
"code": "validation_failed",
"message": "validation failed",
"request_id": "9f2c4e7a1b3d5f6e8a0c2e4f6a8b0d1c",
"details": {
"fields": [
{ "field": "video_id", "message": "must be a UUID" },
{ "field": "ttl_seconds", "message": "must be at most 86400" }
]
}
}
}| Field | Meaning |
|---|---|
code | Stable machine code, listed below. |
message | A short description for logs and people. |
request_id | The ID of this request, also in the X-Request-ID response header. Quote it when you contact support. |
details.fields | Only on validation_failed: every invalid field with the reason. |
Server errors (500) always say internal server error: their details stay in OctaVideo's logs, found by the request_id.
Error codes
| Status | code | What happened | What to do |
|---|---|---|---|
| 400 | validation_failed | One or more fields are invalid. | Fix the fields listed in details.fields. |
| 400 | bad_request | The body could not be read: malformed JSON, an unknown field, more than one JSON value, an empty body, or a missing multipart body. | Fix the request. The API rejects unknown fields on purpose, so a typo never passes silently. |
| 401 | unauthorized | The AccessKey header is missing, or the key is wrong or was regenerated. | Check the key on your server. See Authentication. |
| 403 | forbidden | The key is valid but not allowed to do this. | Check that the resource belongs to this key's library. |
| 404 | not_found | The video, collection or route does not exist in this library. | Check the ID and the library of your key. |
| 405 | method_not_allowed | The route exists with another HTTP method. | Check the method in the API reference. |
| 409 | video_not_ready | You asked for a playback OTP before the video finished processing. | Wait until encoding_status is ready. See Processing status. |
| 409 | conflict | The request conflicts with the current state. | Read the message, then fetch the resource again. |
| 413 | payload_too_large | The body is over the limit. | See limits. |
| 429 | rate_limited | Too many requests. | Wait for the seconds in the Retry-After header, then retry. |
| 500 | internal_error | Something failed on OctaVideo's side. | Retry with backoff. If it persists, send the request_id to support. |
Playback errors
The player checks every OTP when it starts. Your viewers may see these refusals; they never reach your server.
code | Meaning |
|---|---|
domain_not_allowed | The page that embeds the player is not on the library's allowed domains. |
country_blocked | The viewer's country is blocked by the library's country rules. |
unauthorized | The OTP is unknown, already used or expired. Request a new one for each page view. |
Retrying
- Retry
429afterRetry-After, and500with exponential backoff (for example 1 s, 2 s, 4 s, up to 5 attempts). - Don't retry other
4xxerrors unchanged: they fail the same way until you fix the request. - Uploads: an upload that fails halfway must start again from the beginning.
Request IDs
Every response carries an X-Request-ID header. You can send your own (printable ASCII, up to 128 characters) to match OctaVideo's logs with yours; otherwise OctaVideo generates one. Log it next to every failed call.