Video Enhancer API

Enhance kualitas video (2K/4K) lewat unblurimage.ai. Async job system: POST uploadpoll progressdownload 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
Dashboardhttps://api.chioriya.my.id
Upload (URL)GET /api/video-enhancer?url=...
Upload (Multipart)POST /api/video-enhancer
Poll ProgressGET /api/video-enhancer?action=poll
Download ResultGET /api/video-enhancer?action=download

Quick 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 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-enhancer
Poll ProgressCek status job + progress (0-100).GET /api/video-enhancer?action=poll
Download ResultAmbil video hasil enhance (video/mp4).GET /api/video-enhancer?action=download
Health CheckCek status service + engine.GET /api/video-enhancer?action=health

Parameter Upload Endpoint

ParamDefaultKeterangan
apikey / header x-api-key / BearerwajibAPI 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.
resolution2kTarget 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

EndpointParamKeterangan
?action=polljobTokenToken dari Step 1 (response jobToken). Stateless base64url, selalu works di serverless.
?action=downloadjobTokenToken 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)

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

FieldTipeKeterangan
status / okbooleantrue kalau request sukses.
sourcestringSelalu video-enhancer.
traceIdstringID trace untuk pelacakan error.
input / inputTypestringInput asli dan tipe (url atau multipart).
auth / coststring/numberSelalu apikey dan cost yang dipotong (100).
resolutionstringTarget resolusi (2k atau 4k).
jobTokenstringBase64url token stateless untuk poll & download. Encode jobId, input, resolution, apikey hash. Selalu works.
jobIdstringID job unik di engine unblurimage.ai.
pollUrlstringURL lengkap untuk polling. Tinggal GET URL ini berulang.
jobStatusstringprocessing, done, atau failed.
progressnumberPersentase 0-100.
downloadUrlstring|nullURL download video hasil. null sampai jobStatus = done.
errorstring|nullPesan error kalau jobStatus = failed.
remainingnumberSisa 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