UVR Online API / 开发者接口

Use permanent purchased credits for asynchronous audio separation. Create and revoke API keys in Account. Keep keys on your server. Verified registered accounts can use a rate-limited free API sharing their daily website allowance. Available permanent credits are used first. Legacy subscription allowances do not fund API requests.

验证邮箱后,注册用户可以使用限速免费 API,与网页共用每日免费名额。有可用积分时优先扣积分;积分 API 不设套餐级提交频率上限。历史订阅额度不适用于 API。

Pricing and limits / 计费与限制

1 standard minute = 1 credit. Charge the whole task using max(1, floor(duration × multiplier / 60 + 0.5)). Standard 1×, fine and dual-model 2×, triple-model 3×. Quote before upload; explicit approval reserves the credits. The worker measures the actual audio before inference. A lower price returns the difference; a higher price requires another explicit approval. Both stems are included; repeat downloads are free.

整单四舍五入,最低 1 积分:4:20 标准为 4 积分,4:30 标准为 5 积分,4:30 双倍模式为 9 积分。只有成功预扣后才签发上传地址。最终失败、上传过期、文件不合法或取消等待任务自动退回积分;任务重试不重复扣费。

  • Input: MP3, WAV, FLAC or M4A, ≤60 minutes, ≤1 GiB. Choose one output: MP3, WAV, FLAC or M4A. Specialist models may return additional stems and support standard mode only.
  • No fixed account batch count or unfinished-task cap for prepaid uploads. Each file needs its own funded reservation. The GPU still processes tasks sequentially. Service availability, request rate and storage validation apply.
  • Registered free API request and hourly submission limits are configurable in Admin → Free policy; defaults are 60 requests/minute and 3 new tasks/hour. The signed-in daily free limit defaults to 10 tracks. No plan-level request/submission rate cap applies to credit-funded use. Poll no faster than once every 5 seconds. Back off with jitter on 429/503 and respect Retry-After.
  • Credit-funded files remain private and expire 7 days after completion. Free API retention follows the current free policy; always use the returned expires_at. Signed URLs expire sooner; request another URL when needed.

Endpoints / 接口

Base: https://uvr.online/api/v1. Send Authorization: Bearer uvr_live_….

MethodPathPurpose
GET/balanceavailable, held, ledger (integer credits)
POST/quotefilename, size, duration, mode, model_id, output_format
POST/uploadsQuote fields + request_id, confirm:true, points
POST/tasks/{id}/confirmConfirm direct upload; body {}
GET/tasks/{id}Status, real duration, points, expiry
POST/tasks/{id}/approve-priceExplicitly approve revised total: {points: integer}
GET/tasks/{id}/files/{kind}?download=1Private short-lived download URL
DELETE/tasks/{id}Cancel waiting task / delete files; active processing returns 409

Registered free API / 注册免费 API

With no available credits, POST /uploads accepts a stable request_id, filename, size, duration, mode:standard, model_id of any available published model and output_format:mp3 or wav. Actual MP3 or WAV input is accepted. No browser CAPTCHA is required for a verified API key. Each new file consumes the same registered daily track allowance as the website; hourly submission limits, shared-network protections, file size/duration limits and normal queue apply. /quote reports funding:registered_free and points:0 for eligible inputs. Upload, confirm and poll as shown below; a free task proceeds without the legacy /process call. Download before expires_at; free files use the retention configured by the operator.

免费 API 需要已验证邮箱的 API 密钥,与网页共用注册免费名额;只有使用积分的任务才不受免费档调用频率限制。免费模式支持 MP3、WAV 上传,可输出 MP3 或 16 位 WAV;积分任务可输出 MP3、WAV、FLAC、M4A。不要因超时更换 request_id 重复提交;同一 request_id 的重试不再占用名额,即使中途充值,也会返回原免费任务。注册用户免费额度及限速以后台当前配置为准。

Retries / 重试

Use a UUID request_id and persist the exact upload body. Repeating it returns the same task; changed parameters return 409. For an explicit retry of a failed/expired upload, keep request_id and parameters, add a fresh retry_id UUID, and keep that retry_id stable while retrying an uncertain request. The previous charge is refunded and the new attempt reserves once. Never overwrite a confirmed object. Do not use the legacy /process endpoint for points tasks.

401: invalid key; 402: insufficient credits; 404: inaccessible task; 409: state/quote conflict; 429: rate limit; 503: node/storage unavailable. No remote input URLs. Only upload audio you may legally process.

Python example / Python 示例

Install requests and FFmpeg/ffprobe; set UVR_API_KEY. This example uses real credits when your balance is positive; otherwise eligible input uses the registered free allowance. Check funding and the quoted price before continuing.

import os, time, uuid, subprocess, requests
base = "https://uvr.online/api/v1"
auth = {"Authorization": "Bearer " + os.environ["UVR_API_KEY"]}
path = "song.mp3"
def call(method, endpoint, **kwargs):
    r = requests.request(method, base + endpoint, headers=auth, timeout=60, **kwargs)
    r.raise_for_status()
    return r.json()
# ffprobe must be installed. Arguments are passed without a shell.
duration = float(subprocess.check_output(["ffprobe", "-v", "error", "-show_entries",
    "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", path]))
body = {"filename": os.path.basename(path), "size": os.path.getsize(path),
        "duration": duration, "mode": "standard", "model_id": "kim-melbandroformer",
        "output_format": "mp3"}
quote = call("POST", "/quote", json=body)
print("Credits to reserve:", quote["points"])
# Obtain explicit approval from the payer BEFORE creating an upload.
if input("Reserve these credits and upload? [yes/no] ") != "yes":
    raise SystemExit()
body.update(request_id=str(uuid.uuid4()), confirm=True, points=quote["points"])
# Persist the complete body; replay it unchanged after an uncertain response.
upload = call("POST", "/uploads", json=body)
task_id = upload["id"]
if "upload_url" in upload:
    with open(path, "rb") as f:
        r = requests.put(upload["upload_url"], data=f, headers=upload["headers"], timeout=600)
        r.raise_for_status()
    call("POST", f"/tasks/{task_id}/confirm", json={})
while True:
    task = call("GET", f"/tasks/{task_id}")
    if task["status"] == "awaiting_confirmation":
        multiplier = {"standard":1,"fine":2,"dual":2,"triple":3}[task["mode"]]
        import math
        total = max(1, math.floor(task["duration"] * multiplier / 60 + 0.5))
        if input(f"Measured price is {total} credits. Approve? [yes/no] ") != "yes":
            call("DELETE", f"/tasks/{task_id}")
            raise SystemExit()
        call("POST", f"/tasks/{task_id}/approve-price", json={"points":total})
    elif task["status"] == "completed":
        break
    elif task["status"] in ("failed", "expired"):
        raise RuntimeError(task.get("error") or task["status"])
    time.sleep(5)
for stem in ("vocals", "instrumental"):
    signed = call("GET", f"/tasks/{task_id}/files/{stem}_preview?download=1")
    # Never forward the API bearer token to object storage.
    with requests.get(signed["url"], stream=True, timeout=600) as r:
        r.raise_for_status()
        with open(stem + ".mp3", "wb") as f:
            for chunk in r.iter_content(1024*1024): f.write(chunk)

Recharge · Terms · Privacy · Support

Polski
Zaloguj się
Analiza użycia·
Polski
UVR Online

Witamy ponownie

Zaloguj się, aby kontynuować z Twoimi utworami i kredytami.