API Reference
The Unblur Video API lets you enhance videos programmatically: upload a file (or point us at a URL), create an upscale job, poll until it completes, and download the result.
Base URL: https://unblurvideo.ai/api/v1
All requests and responses are JSON. Responses share one envelope:
{ "success": true, "data": { } }
Failed requests return success: false with an error message and a machine-readable code:
{ "success": false, "error": "Insufficient credits.", "code": "INSUFFICIENT_CREDITS" }
API access is included in the Pro plan. Requests from accounts without an active Pro subscription are rejected with
403 API_ACCESS_REQUIRED. See pricing.
Authentication
Create an API key in your dashboard, then pass it as a Bearer token on every request:
curl -H "Authorization: Bearer ubv_your_key_here" https://unblurvideo.ai/api/v1/credits
Keys start with ubv_ and are shown only once at creation time. Treat them like passwords: store them in your server's environment, never in client-side code or a repository. You can revoke a key at any time from the dashboard.
Quick start
The fastest integration passes a public video URL — we download it, analyze it, and it's ready for a job in one call:
curl -X POST -H "Authorization: Bearer ubv_..." -H "Content-Type: application/json" -d '{"mode": "source_url", "source_url": "https://example.com/video.mp4"}' https://unblurvideo.ai/api/v1/uploads
Then create a job with the returned uploadId, and poll it until status is completed:
curl -X POST -H "Authorization: Bearer ubv_..." -H "Content-Type: application/json" -d '{"upload_id": "UPLOAD_ID", "target_resolution": "1080p"}' https://unblurvideo.ai/api/v1/jobs
curl -H "Authorization: Bearer ubv_..." https://unblurvideo.ai/api/v1/jobs/JOB_ID
When the job completes, the response includes a temporary outputUrl you can download the enhanced video from.
Endpoints
POST /uploads
Register a video to process. Two modes:
Mode 1 — source_url. We fetch a public https URL server-side (max 500 MB; mp4, mov or webm). Metadata is extracted before the call returns, so you can create a job immediately.
curl -X POST -H "Authorization: Bearer ubv_..." -H "Content-Type: application/json" -d '{"mode": "source_url", "source_url": "https://example.com/video.mp4"}' https://unblurvideo.ai/api/v1/uploads
{
"success": true,
"data": {
"uploadId": "0c9d…",
"status": "uploaded",
"sizeBytes": 10485760,
"contentType": "video/mp4",
"metadata": { "resolution": "720p", "width": 1280, "height": 720, "duration": 12.4, "fps": 30 },
"metadataStatus": "ready"
}
}
Mode 2 — presigned upload. For local files: request an upload URL, PUT the file to it, then confirm.
curl -X POST -H "Authorization: Bearer ubv_..." -H "Content-Type: application/json" -d '{"filename": "clip.mp4", "content_type": "video/mp4", "size_bytes": 10485760}' https://unblurvideo.ai/api/v1/uploads
The response contains uploadId and a temporary uploadUrl (valid 10 minutes). Upload the raw file bytes to it:
curl -X PUT -H "Content-Type: video/mp4" --data-binary @clip.mp4 "UPLOAD_URL"
POST /uploads/{id}/confirm
Confirm a presigned upload after the PUT succeeds. Verifies the stored file and extracts video metadata synchronously (this call can take a few seconds).
curl -X POST -H "Authorization: Bearer ubv_..." https://unblurvideo.ai/api/v1/uploads/UPLOAD_ID/confirm
The response mirrors the source_url mode above. If metadataStatus is "failed" the video could not be analyzed — try a different file.
POST /jobs
Create an enhancement job for an uploaded video.
| Field | Type | Description |
|---|---|---|
upload_id | string | Required. The uploadId from an upload call. |
target_resolution | string | Required. 1080p, 2k or 4k. |
preview | boolean | Optional. true renders a free ~3-second watermarked preview. |
curl -X POST -H "Authorization: Bearer ubv_..." -H "Content-Type: application/json" -d '{"upload_id": "UPLOAD_ID", "target_resolution": "1080p"}' https://unblurvideo.ai/api/v1/jobs
Returns 201 with the job, including its creditCost. Credits are deducted when the job is created and automatically refunded if processing fails. If an identical job is already active, the existing job is returned with 200 and "duplicate": true — no double charge.
If metadata extraction is still in progress you get 409 METADATA_PENDING with a Retry-After header; retry after that many seconds.
GET /jobs/{id}
Poll a job. Polling this endpoint also drives processing bookkeeping, so poll it (every 5–10 seconds is plenty) rather than scraping other state.
curl -H "Authorization: Bearer ubv_..." https://unblurvideo.ai/api/v1/jobs/JOB_ID
Key response fields:
| Field | Description |
|---|---|
status | pending, in_queue, processing, completed, failed or cancelled. |
outputUrl | Present when completed: a temporary download URL (valid 4 hours). Re-poll for a fresh one. |
creditCost | Credits charged for this job. |
errorMessage | Present when failed. Failed jobs are refunded automatically. |
GET /jobs
List your jobs, newest first. Query parameters: limit (default 20, max 100), offset, and optional status filter.
curl -H "Authorization: Bearer ubv_..." "https://unblurvideo.ai/api/v1/jobs?status=completed&limit=10"
GET /credits
Check your credit balance and plan.
curl -H "Authorization: Bearer ubv_..." https://unblurvideo.ai/api/v1/credits
{
"success": true,
"data": {
"totalCredits": 3600,
"subscriptionCredits": 3400,
"oneTimeCredits": 200,
"planName": "Pro",
"subscriptionStatus": "active",
"currentPeriodEnd": "2026-08-01T00:00:00.000Z"
}
}
Credits and pricing
Jobs are billed in credits based on video duration and target resolution:
| Target resolution | Credits per second of video |
|---|---|
| 1080p | 1.0 |
| 2k | 1.6 |
| 4k | 4.5 |
The cost is rounded up to a whole credit. Previews are free. Source videos may be at most 1080p and 500 MB. Credits come with your subscription and can be topped up with one-time packs from the pricing page.
Rate limits
Limits apply per account (all keys share them). When exceeded, requests return 429 with a Retry-After header.
| Scope | Limit |
|---|---|
| Uploads (presigned or confirm) | 30 / hour each |
| Uploads via source_url | 10 / hour |
| Job creation | 45 / hour |
| Polling (job status, job list, credits) | 120 / minute |
Errors
| HTTP | Code | Meaning |
|---|---|---|
| 401 | MISSING_API_KEY, INVALID_API_KEY, KEY_EXPIRED | Missing, wrong or revoked key. |
| 402 | INSUFFICIENT_CREDITS | Not enough credits for this job. |
| 403 | API_ACCESS_REQUIRED | Your plan does not include API access. |
| 404 | UPLOAD_NOT_FOUND, JOB_NOT_FOUND | Resource does not exist or is not yours. |
| 409 | METADATA_PENDING | Video still being analyzed; retry after Retry-After seconds. |
| 409 | UPLOAD_STATUS_CONFLICT, JOB_ALREADY_CREATING | State conflict; retry shortly. |
| 413 | FILE_TOO_LARGE | Video exceeds 500 MB. |
| 422 | METADATA_UNAVAILABLE, RESOLUTION_TOO_HIGH, SOURCE_URL_FORBIDDEN | Video can't be processed or URL not allowed. |
| 429 | RATE_LIMIT_EXCEEDED | Slow down; respect Retry-After. |
| 500 | RUNPOD_FAILED | Processing backend error; charged credits are refunded. |
| 502 / 504 | SOURCE_FETCH_FAILED, SOURCE_FETCH_TIMEOUT | We couldn't download your source_url. |