Video Enhancer API
Enhance kualitas video (2K/4K) lewat unblurimage.ai. Async job system: POST upload → poll progress → download result. Support URL-based input (recommended) dan multipart upload. Support proxy (http/https/socks4/socks5).
Wajib API Key
Cost 100 per sukses
Refund otomatis
Proxy support
Max 5MB
Async job system
2K/4K resolution
Domain aktif
Dashboard
https://api.chioriya.my.idUpload (URL)
GET /api/video-enhancer?url=...Upload (Multipart)
POST /api/video-enhancerPoll Progress
GET /api/video-enhancer?action=pollDownload Result
GET /api/video-enhancer?action=downloadQuick Start
GET https://api.chioriya.my.id/api/video-enhancer?url=https://domain.com/video.mp4&apikey=YOUR_APIKEY&resolution=2k
Endpoint /api/video-enhancer memakai 3-step async flow:
Step 1 — Upload: POST atau GET dengan
Step 2 — Poll: GET
Step 3 — Download: GET
Step 1 — Upload: POST atau GET dengan
url (recommended) atau multipart file. Return jobToken, jobId, dan pollUrl.Step 2 — Poll: GET
pollUrl (atau ?action=poll&jobToken=...) sampai jobStatus = done. Field progress (0-100) nunjukin persentase.Step 3 — Download: GET
downloadUrl (atau ?action=download&jobToken=...) untuk ambil video buffer video/mp4.
Cost 100 limit per request berhasil. Refund otomatis kalau job gagal (
jobStatus = failed). Vercel 60s limit per request — makanya pake async polling, bukan blocking.Endpoint Video Enhancer
Upload (URL)URL video → jobToken + pollUrl. Recommended.
GET /api/video-enhancer?url=...Upload (Multipart)File upload → jobToken + pollUrl. Max 4.5MB.
POST /api/video-enhancerPoll ProgressCek status job + progress (0-100).
GET /api/video-enhancer?action=pollDownload ResultAmbil video hasil enhance (video/mp4).
GET /api/video-enhancer?action=downloadHealth CheckCek status service + engine.
GET /api/video-enhancer?action=healthParameter Upload Endpoint
| Param | Default | Keterangan |
|---|---|---|
apikey / header x-api-key / Bearer | wajib | API key panel bot. Cost 100 limit per request berhasil. Refund otomatis kalau job gagal. |
url | โ | Recommended. URL video publik yang mau di-enhance. Contoh: https://domain.com/video.mp4. Bypass Vercel 4.5MB body limit. Format: mp4, mov, avi, mkv, webm. |
resolution | 2k | Target resolusi output: 2k atau 4k. Default 2k kalau kosong. |
proxy | โ | Proxy URL untuk fetch video input. Support: http://, https://, socks4://, socks5://. Contoh: socks5://user:pass@host:port. |
file (multipart only) | โ | File video untuk POST multipart upload. Max 4.5MB (Vercel body limit). Bisa kena 413 kalau lebih — pake url mode aja. |
URL mode recommended karena bypass Vercel 4.5MB body limit. Multipart upload max 4.5MB dan bisa kena
413 Payload Too Large kalau lebih.Parameter Poll & Download Endpoint
| Endpoint | Param | Keterangan |
|---|---|---|
?action=poll | jobToken | Token dari Step 1 (response jobToken). Stateless base64url, selalu works di serverless. |
?action=download | jobToken | Token dari Step 1. Hanya bisa di-download kalau jobStatus = done. |
?action=health | โ | Cek status service + engine. Gak butuh apikey, gak ngurangin limit. |
Cara kirim API key (upload endpoint)
- Query string:
?apikey=YOUR_APIKEY - Header:
x-api-key: YOUR_APIKEY - Authorization Bearer:
Authorization: Bearer YOUR_APIKEY - POST body JSON (multipart mode):
{ "apikey": "YOUR_APIKEY" }
Poll & download endpoint gak butuh apikey (jobToken udah cukup). Tapi cost 100 udah dipotong di Step 1 (upload).
Struktur Response
Step 1 — Upload (job created)
{
"status": true,
"ok": true,
"source": "video-enhancer",
"traceId": "ve_upload_abc123",
"input": "https://domain.com/video.mp4",
"inputType": "url",
"auth": "apikey",
"cost": 100,
"resolution": "2k",
"jobToken": "eyJpbnB1dCI6Imh0dHBzOi8vZG9tYWluLmNvbS92aWRlby5tcDQ...",
"jobId": "ve_job_abc123",
"pollUrl": "/api/video-enhancer?action=poll&jobToken=eyJpbnB1dC...",
"estimatedSeconds": 45,
"remaining": 9900
}
Step 2 — Polling (progress)
{
"status": true,
"ok": true,
"source": "video-enhancer",
"jobId": "ve_job_abc123",
"jobStatus": "processing",
"progress": 45,
"downloadUrl": null,
"error": null,
"elapsedSeconds": 18,
"estimatedRemaining": 27
}
jobStatus bisa: processing (masih jalan), done (selesai, downloadUrl keisi), atau failed (gagal, error keisi, limit di-refund).Step 2 — Polling (done)
{
"status": true,
"ok": true,
"source": "video-enhancer",
"jobId": "ve_job_abc123",
"jobStatus": "done",
"progress": 100,
"downloadUrl": "/api/video-enhancer?action=download&jobToken=eyJpbnB1dC...",
"error": null,
"elapsedSeconds": 42,
"estimatedRemaining": 0
}
Step 3 — Download result
Response: video buffer (binary) Content-Type: video/mp4 Content-Disposition: attachment; filename="enhanced.mp4" Content-Length: 5242880
Download URL return raw video buffer dengan
Content-Type: video/mp4. Langsung save ke file atau stream ke client. Gak butuh apikey (jobToken udah cukup).Field reference
| Field | Tipe | Keterangan |
|---|---|---|
status / ok | boolean | true kalau request sukses. |
source | string | Selalu video-enhancer. |
traceId | string | ID trace untuk pelacakan error. |
input / inputType | string | Input asli dan tipe (url atau multipart). |
auth / cost | string/number | Selalu apikey dan cost yang dipotong (100). |
resolution | string | Target resolusi (2k atau 4k). |
jobToken | string | Base64url token stateless untuk poll & download. Encode jobId, input, resolution, apikey hash. Selalu works. |
jobId | string | ID job unik di engine unblurimage.ai. |
pollUrl | string | URL lengkap untuk polling. Tinggal GET URL ini berulang. |
jobStatus | string | processing, done, atau failed. |
progress | number | Persentase 0-100. |
downloadUrl | string|null | URL download video hasil. null sampai jobStatus = done. |
error | string|null | Pesan error kalau jobStatus = failed. |
remaining | number | Sisa limit panel setelah request. |
Examples
1. Upload via URL (recommended)
fetch("/api/video-enhancer?url=https%3A%2F%2Fdomain.com%2Fvideo.mp4&apikey=YOUR_APIKEY&resolution=2k")
.then(res => res.json())
.then(data => {
console.log("Job created:", data.jobId);
console.log("Poll URL:", data.pollUrl);
console.log("Estimated:", data.estimatedSeconds, "s");
});
2. Upload via multipart (fallback)
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const form = new FormData();
form.append("file", file);
form.append("resolution", "4k");
const res = await fetch("/api/video-enhancer", {
method: "POST",
headers: { "x-api-key": "YOUR_APIKEY" },
body: form
});
const data = await res.json();
console.log("Job created:", data.jobId);
console.log("Poll URL:", data.pollUrl);
3. Poll progress
async function pollJob(pollUrl) {
while (true) {
const res = await fetch(pollUrl);
const data = await res.json();
console.log(`[${data.progress}%] ${data.jobStatus}`);
if (data.jobStatus === "done") return data.downloadUrl;
if (data.jobStatus === "failed") throw new Error(data.error || "Job gagal");
await new Promise(r => setTimeout(r, 2000));
}
}
const downloadUrl = await pollJob(data.pollUrl);
console.log("Download ready:", downloadUrl);
4. Download result
const res = await fetch(downloadUrl);
const blob = await res.blob();
console.log("Size:", blob.size, "bytes");
console.log("Type:", blob.type);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "enhanced.mp4";
a.click();
URL.revokeObjectURL(url);
5. Node.js (axios) — full 3-step flow with URL
const axios = require("axios");
const fs = require("fs");
async function enhanceVideo(videoUrl, apiKey, resolution, outputFile) {
// Step 1: Upload via URL
const uploadRes = await axios.get("https://api.chioriya.my.id/api/video-enhancer", {
params: { url: videoUrl, apikey: apiKey, resolution: resolution || "2k" },
timeout: 30000
});
if (!uploadRes.data.status) throw new Error("Upload gagal");
const { jobToken, pollUrl } = uploadRes.data;
console.log("Job created:", uploadRes.data.jobId);
// Step 2: Poll sampai done
let downloadUrl = null;
while (!downloadUrl) {
const pollRes = await axios.get("https://api.chioriya.my.id" + pollUrl, { timeout: 15000 });
const poll = pollRes.data;
console.log(`[${poll.progress}%] ${poll.jobStatus}`);
if (poll.jobStatus === "done") { downloadUrl = poll.downloadUrl; break; }
if (poll.jobStatus === "failed") throw new Error(poll.error || "Job gagal");
await new Promise(r => setTimeout(r, 2000));
}
// Step 3: Download video buffer ke file
const videoRes = await axios.get("https://api.chioriya.my.id" + downloadUrl, {
responseType: "stream",
timeout: 120000
});
videoRes.data.pipe(fs.createWriteStream(outputFile));
return outputFile;
}
enhanceVideo("https://domain.com/video.mp4", "YOUR_APIKEY", "2k", "enhanced.mp4")
.then(file => console.log("Saved:", file))
.catch(console.error);
6. Baileys / Keila — full 3-step flow
case "enhance": {
if (!text) return m.keila("Contoh: .enhance https://domain.com/video.mp4");
await m.react("๐ฌ");
const axios = require("axios");
const apiKey = global.apikey || "YOUR_APIKEY";
try {
// Step 1: Upload via URL
const uploadRes = await axios.get("https://api.chioriya.my.id/api/video-enhancer", {
params: { url: text, apikey: apiKey, resolution: "2k" },
timeout: 30000
});
if (!uploadRes.data.status) return m.keila("Upload gagal.");
const { pollUrl, jobId } = uploadRes.data;
await m.keila(`Job dibuat: ${jobId}\nPolling progress...`);
// Step 2: Poll sampai done
let downloadUrl = null;
let attempts = 0;
while (!downloadUrl && attempts < 30) {
attempts++;
const pollRes = await axios.get("https://api.chioriya.my.id" + pollUrl, { timeout: 15000 });
const poll = pollRes.data;
if (poll.jobStatus === "done") { downloadUrl = poll.downloadUrl; break; }
if (poll.jobStatus === "failed") return m.keila("Job gagal: " + (poll.error || "unknown"));
await new Promise(r => setTimeout(r, 2000));
}
if (!downloadUrl) return m.keila("Timeout nunggu job.");
// Step 3: Download buffer & kirim
const videoRes = await axios.get("https://api.chioriya.my.id" + downloadUrl, {
responseType: "arraybuffer",
timeout: 120000
});
const buffer = Buffer.from(videoRes.data);
await keila.sendMessage(m.chat, {
video: buffer,
mimetype: "video/mp4",
fileName: "enhanced.mp4",
caption: `*Video Enhancer*\nResolution: 2K\nSource: ${text}`
}, { quoted: m });
} catch (e) {
await m.keila("Error: " + e.message);
}
}
break;
7. With proxy
const axios = require("axios");
// Upload dengan proxy (untuk bypass region block atau rate limit)
const res = await axios.get("https://api.chioriya.my.id/api/video-enhancer", {
params: {
url: "https://domain.com/video.mp4",
apikey: "YOUR_APIKEY",
resolution: "4k",
proxy: "socks5://user:pass@host:port"
},
timeout: 30000
});
console.log("Job created:", res.data.jobId);
console.log("Poll URL:", res.data.pollUrl);
Proxy support:
http://, https://, socks4://, socks5://. Dipake untuk fetch video input (bukan untuk koneksi ke API).8. curl 3-step commands
# Step 1: Upload via URL curl -s "https://api.chioriya.my.id/api/video-enhancer?url=https://domain.com/video.mp4&apikey=YOUR_APIKEY&resolution=2k" | jq # Step 2: Poll progress (pakai pollUrl dari Step 1) curl -s "https://api.chioriya.my.id/api/video-enhancer?action=poll&jobToken=YOUR_JOBTOKEN" | jq # Step 3: Download result (pakai downloadUrl dari Step 2 saat jobStatus=done) curl -o enhanced.mp4 "https://api.chioriya.my.id/api/video-enhancer?action=download&jobToken=YOUR_JOBTOKEN" # Bonus: Upload via multipart (max 4.5MB) curl -X POST "https://api.chioriya.my.id/api/video-enhancer" \ -H "x-api-key: YOUR_APIKEY" \ -F "file=@video.mp4" \ -F "resolution=2k" | jq
Catatan Penting
- URL mode recommended untuk bypass Vercel 4.5MB body limit. Tinggal kasih
urlparameter, server yang fetch video inputnya. - Multipart upload max 4.5MB. Bisa kena
413 Payload Too Largekalau lebih. Untuk video besar, pakeurlmode aja. - Async job system: POST upload return langsung
jobToken+pollUrl, gak nunggu proses selesai. Poll terpisah di Step 2. - Job token = base64url stateless. Encoded jobId, input, resolution, apikey hash. Gak butuh server-side state, selalu works di serverless (Vercel).
- Cost 100 limit per request berhasil. Refund otomatis kalau
jobStatus=faileddi polling. - Vercel 60s limit per request — makanya pake async polling, bukan blocking. Job bisa makan 30-60s+, polling tiap 2 detik aman.
- Supported formats:
mp4,mov,avi,mkv,webm. Output selaluvideo/mp4. - Proxy support:
http://,https://,socks4://,socks5://. Dipake untuk fetch video input, bukan untuk koneksi ke API. - Poll & download endpoint gak butuh apikey (jobToken udah cukup). Tapi cost 100 udah dipotong di Step 1 (upload).
- Polling interval recommended 2 detik. Jangan terlalu cepat (rate limit), jangan terlalu lama (delay download).
- Job token gak punya expiry eksplisit, tapi hasil download dipurge setelah 1 jam. Kalau perlu, segera download setelah
jobStatus=done.