> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ltx.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ltx.io/_mcp/server.

# Upscale a video

POST https://api.ltx.io/v2/video-upscale
Content-Type: application/json

Upscale a video to 1080p, 4K or 8K. On completion, the result contains `video_url`, an H.264 MP4.

The output keeps the input's aspect ratio and is as large as fits 1920×1080 (`1080p`), 3840×2160 (`4k`) or 7680×4320 (`8k`). For a portrait input the box is turned to portrait (1080×1920, 2160×3840 or 4320×7680). Width and height are rounded to even numbers. For example, at `1080p` a 1280×720 input becomes 1920×1080; at `4k` a 1920×1080 input becomes 3840×2160 and a 1440×1080 input becomes 2880×2160; at `8k` a 1080×1920 input becomes 4320×7680. The output keeps the input's audio (as stereo) and uses the input's frame rate, rounded to a whole number.

Responds immediately with the job `id` and `created_at` timestamp. Poll `GET /v2/video-upscale/{id}` until the status is `completed`.

Requests that violate the content policy fail the job with `content_filtered_error`. An account without enough credit fails the same way, with `insufficient_funds_error`.

Billed per second of input video. See [Pricing](/pricing).

Reference: https://docs.ltx.io/api-documentation/api-reference/async-video-generation/submit-video-upscale

## Authentication

- `Authorization` header (bearer token, required) — API key authentication

## Request

### Body (application/json)

This endpoint expects a VideoUpscaleRequest.

- `video_uri` (string, required) — Input video in HTTPS URL or base64 data URI format. See [Input Formats](/input-formats#videos) for supported formats. The video must be H.264 or HEVC (H.265). Max 200 MB ([data URIs](/input-formats#data-uri-base64) have a lower limit). The short side must be at least 480 pixels. The long side can be up to 7680 pixels and the short side up to 4320 pixels, so 8K video is accepted in landscape (7680×4320) or portrait (4320×7680). At least 2 frames and at most 2401 frames for `1080p` (e.g. about 100 seconds at 24fps, or about 80 seconds at 30fps), 601 frames for `4k` (e.g. about 25 seconds at 24fps, or about 20 seconds at 30fps) or 241 frames for `8k` (e.g. about 10 seconds at 24fps, or about 8 seconds at 30fps). The frame rate must be at least 1 fps.
- `resolution` (enum, required) — Output size. The output keeps the input's aspect ratio and is as large as fits 1920×1080 (`1080p`), 3840×2160 (`4k`) or 7680×4320 (`8k`), turned to portrait for a portrait input.
  - Allowed values: `1080p`, `4k`, `8k`

## Response

### 202

Job submitted successfully

- `id` (string, required) — Unique job identifier. Use this to poll for status.
- `created_at` (datetime, required) — ISO 8601 timestamp of when the job was created.

## Errors

### 400 Bad Request Error

The request is invalid or malformed

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

### 401 Unauthorized Error

Authentication failed

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

### 413 Content Too Large Error

The request body exceeds 32 MB

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

### 429 Too Many Requests Error

Queue limit exceeded

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

### 500 Internal Server Error

An unexpected error occurred

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

### 503 Service Unavailable Error

Service temporarily unavailable

- `type` (enum, required) — Response type indicator
  - Allowed values: `error`
- `error` (ErrorError, required)

## Types

### ErrorError

- `type` (string, required) — Error type for programmatic handling
- `message` (string, required) — Human-readable error description

## Examples

**Request**

```json
{
  "video_uri": "YOUR_VIDEO_URI",
  "resolution": "4k"
}
```

**Response**

```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "created_at": "2026-01-15T10:00:00.000Z"
}
```

**SDK Code**

```python
import requests

url = "https://api.ltx.io/v2/video-upscale"

payload = {
    "video_uri": "YOUR_VIDEO_URI",
    "resolution": "4k"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.ltx.io/v2/video-upscale"

	payload := strings.NewReader("{\n  \"video_uri\": \"YOUR_VIDEO_URI\",\n  \"resolution\": \"4k\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.ltx.io/v2/video-upscale")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"video_uri\": \"YOUR_VIDEO_URI\",\n  \"resolution\": \"4k\"\n}")
  .asString();
```