Video Restorer API Documentation
Playground
Try it on WaveSpeedAI!Video Restorer cleans up damaged footage: strip compression artifacts from low-bitrate video or bring out-of-focus footage back into sharp focus, keeping the subject, framing and motion exactly as they are. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.
Features
Fix damaged footage without touching the content. Video Restorer has two modes: decompress strips the macroblocking, ringing, banding and chroma bleed left by low-bitrate encodes, and deblur brings soft, out-of-focus footage back into sharp focus. Subject, framing and motion stay exactly as they are; only the image quality changes.
Two Modes
-
decompress (default) For clips that were re-encoded at a low bitrate: social-media downloads, old phone footage, screen recordings. Restores clean edges and fine detail and removes block artifacts.
-
deblur For footage that is soft or out of focus. Recovers sharp focus and crisp detail. It targets defocus blur, not motion blur, and heavily destroyed detail is reconstructed rather than recovered.
Parameters
| Parameter | Required | Description |
|---|---|---|
| video | Yes | Input video (URL or upload). Up to 2 minutes is processed. |
| mode | No | decompress (default) or deblur |
| prompt | No | Short description of the scene; leave empty for a generic restore |
| target_resolution | No | Output resolution: 480p, 720p, 1080p (default: 720p). Aspect ratio is preserved. |
| seed | No | Seed for reproducible results |
Pro Tips
- Pick the mode that matches the damage: blocky, smeared colors and edge ringing means
decompress; uniformly soft focus meansdeblur. - Neither mode is an upscaler or a denoiser. For resolution, run the result through a video upscaler afterwards.
- Keep the same seed to reproduce a result.
Limits and Performance
- Max clip length per job: 2 minutes (longer input is truncated)
- Processing speed: roughly 8 seconds of wall time per second of video at 720p, about 20 seconds per second at 1080p
Pricing
> Billing duration: Input media duration is rounded up to whole seconds. The minimum billed duration is 3 seconds; shorter inputs are billed as 3 seconds. Input beyond 2 minutes is not processed and not billed.
Per-second billing with a 3-second minimum. The table below lists prices per 5 seconds for easy comparison.
| Output Resolution | Cost per 5 seconds |
|---|---|
| 480p | $0.10 |
| 720p | $0.20 |
| 1080p | $0.50 |
Billing Rules
- Minimum charge: 3 seconds
- Per-second rate = (price per 5 seconds) ÷ 5
- Billed duration = video length in seconds (rounded up), with a 3-second minimum, capped at 120 seconds
- Total cost = billed duration × per-second rate (by output resolution)
Notes
- Video is the only required field.
- Maximum processed video length per job: 2 minutes.
- Ensure video URLs are publicly accessible.
Authentication
For authentication details, please refer to the Authentication Guide.
API Endpoints
Submit Task & Query Result
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
REQUEST_BODY=$(cat <<'JSON'
{
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"mode": "decompress",
"target_resolution": "720p"
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/wavespeed-ai/video-restorer" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}")
TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body \
"${RESULT_URL}" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}")
RESULT=$(printf '%s' "${RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout|deleted) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
*) sleep 2 ;;
esac
doneParameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| video | string | Yes | - | The video to restore; up to 2 minutes is processed (longer input is truncated). | |
| mode | string | No | decompress | decompress, deblur | decompress: remove compression artifacts (macroblocking, ringing, banding, chroma bleed) from low-bitrate footage. deblur: bring soft, out-of-focus footage back into sharp focus (defocus blur only, not motion blur). |
| prompt | string | No | - | Optional. A short description of what the video shows (for example "a woman walking a dog in a park at sunset"). Helps the model keep the right details; leave empty for a generic restore. | |
| target_resolution | string | No | 720p | 480p, 720p, 1080p | Output resolution. The input aspect ratio is preserved; output is never larger than the input. |
| seed | integer | No | - | - | The seed for random number generation. Omit for a random seed. |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data.id | string | Unique identifier for the prediction, Task Id |
| data.model | string | Model ID used for the prediction |
| data.outputs | array | Output values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed) |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Task status. completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses. |
| data.created_at | string | ISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”) |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |
Result Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Task ID |
Result Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data | object | The prediction data object containing all details |
| data.id | string | Unique identifier for the prediction |
| data.model | string | Model ID used for the prediction |
| data.outputs | array<string | object> | Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model. |
| data.urls | object | Object containing related API endpoints |
| data.status | string | Status: completed is successful; failed, cancelled, timeout, and deleted are failure terminal statuses |
| data.created_at | string | ISO timestamp of when the request was created |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |