BetterVideo API

Privacy-first video enhancement as an API. Send a video by URL, we upscale / sharpen / restore it on GPU, and return a time-limited download link — never trained on, never sold, auto-deleted.

Get an API key →  ·  Interactive API reference (try it live) →

Introduction

The BetterVideo API is a REST API. All requests go to:

https://api.bettervideo.io/v1

The job model is asynchronous: you submit a video, we process it on GPU, and you either poll for status or receive a signed webhook when it's done. All responses are JSON. Every request must be authenticated.

Authentication

Authenticate with a bearer token in the Authorization header:

Authorization: Bearer bv_live_xxxxxxxxxxxxxxxx

There are two kinds of key, created in your developer console:

Key prefixWhat it does
bv_test_Sandbox — free mock processing. No GPU, no credits charged, no approval required. Use it to build and test your integration.
bv_live_Live — real GPU enhancement, billed against your credit balance. Requires account approval (early access).

Keys are shown once at creation and stored hashed — keep them secret and never embed them in client-side code.

Quickstart

Submit a video, wait for it to finish, and download the result — three calls:

Each command is a single line — copy with the button and paste as-is.

# 1) Submit a job
curl -X POST https://api.bettervideo.io/v1/jobs -H "Authorization: Bearer bv_test_your_key" -H "Content-Type: application/json" -d '{"video_url":"https://example.com/clip.mp4","resolution":"1080p"}'
# -> 201 { "id": "JOB_ID", "status": "queued", "sandbox": true, ... }

# 2) Poll until status is "done" (or use a webhook, below)
curl https://api.bettervideo.io/v1/jobs/JOB_ID -H "Authorization: Bearer bv_test_your_key"
# -> { "status": "done", ... }

# 3) Get a time-limited download link
curl https://api.bettervideo.io/v1/jobs/JOB_ID/result -H "Authorization: Bearer bv_test_your_key"
# -> { "download_url": "https://...", "expires_in": 3600, "retention": { ... } }

Sandbox & testing

Any request made with a bv_test_ key runs in a mock lane: it returns a realistic response with "sandbox": true and "credits_charged": 0, completes after a short delay, uses no GPU, and charges nothing. Sandbox keys work immediately — no approval needed — so you can build your full integration before going live. Switch to a bv_live_ key when you're ready for real enhancement.

Job lifecycle

A job moves through these states:

queued  ->  running  ->  done
                       \->  error   (you are auto-refunded)

Find out when a job finishes in one of two ways:

  • Poll GET /v1/jobs/{id} until status is done or error.
  • Webhook — pass a webhook_url when you create the job and we'll POST a signed event when it finishes (see Webhooks).

Input requirements

RequirementDetail
SourceA publicly reachable http(s) URL pointing directly at a video file. Internal/private addresses are blocked.
FormatsCommon video containers and codecs — MP4 (H.264), MOV, MKV, WebM, AVI, and similar. If we can't decode the file you get a clear unreadable_video error.
OutputEnhanced MP4 (H.264).
Target resolution1080p or 4k.
Max length10 minutes (600 s). Longer is rejected with video_too_long — before any charge.
Max file size2 GB. Larger is rejected with video_too_large.

We measure the real duration of your video server-side and bill on that — never on a value you send.

Webhooks

If you pass a webhook_url, we POST a JSON event when the job finishes:

{ "event": "job.completed", "job_id": "JOB_ID", "status": "done" }

Every webhook is signed. Verify the X-BetterVideo-Signature header — an HMAC-SHA256 of the raw request body using your signing secret — before trusting it.

Idempotency

Send an Idempotency-Key header on POST /v1/jobs to make retries safe. A repeated key returns the original job instead of creating — and charging for — a duplicate. Recommended whenever a gateway or queue might retry.

Errors

Errors use a consistent envelope and standard HTTP status codes:

{ "error": { "code": "insufficient_credits", "message": "...", "type": "billing_error" } }
StatusMeaning
400Validation error — bad/missing field, unsupported resolution, video_too_long, or video_too_large
401Missing or invalid API key
402Insufficient credits (top up or enable auto-recharge)
403Account pending approval, or a Secure-tier feature on a Standard key
404Job not found
409Result requested before the job is done
429Rate limit exceeded

Rate limits

Limits are applied per API key. Polling status is the most permissive; job creation is more restricted. If you exceed a limit you get 429 — back off and retry. Submitting ~60 jobs/min and polling ~300/min are comfortably within limits.

Endpoints

Account

GET /v1/me

Validate a key and return account info: plan, credit balance, sandbox flag, approval status, and per-minute pricing. Handy as an auth test.

Create a job

POST /v1/jobs
FieldTypeRequiredNotes
video_urlstringyesPublic http(s) link to the source video
resolutionstringyes"1080p" or "4k"
duration_secondsintegernoOptional hint; we auto-detect and bill on the real length
webhook_urlstringnoWe POST a signed completion event here
{
  "id": "1b9d...e4",
  "status": "queued",
  "resolution": "1080p",
  "duration_seconds": 15,
  "credits_charged": 45,
  "sandbox": false,
  "created_at": "2026-06-23T20:00:00Z",
  "expires_at": "2026-07-23T20:00:00Z"
}

Get a job

GET /v1/jobs/{id}

Returns the current status and metadata. Poll this until status is done or error.

Get the result

GET /v1/jobs/{id}/result

When the job is done, returns a signed download URL valid for one hour (re-request any time for a fresh link), plus a retention reminder:

{
  "download_url": "https://...",
  "expires_in": 3600,
  "retention": {
    "auto_delete_at": "2026-07-23T20:00:00Z",
    "delete_now": "DELETE /v1/jobs/{id}",
    "reminder": "For maximum privacy, delete this job as soon as you've downloaded it."
  }
}

Delete a job

DELETE /v1/jobs/{id}

Permanently deletes the original and enhanced files from our storage. On the Secure tier the response includes a signed deletion certificate. See Privacy & retention.

Deletion certificate Secure

GET /v1/jobs/{id}/deletion-certificate

Re-fetch the cryptographically signed proof that a job's files were destroyed. Works whether the job was deleted on demand or auto-deleted at retention.

Audit log Secure

GET /v1/audit-log

A chain-of-custody log of recent events on your account (job created, completed, result accessed, deleted, …).

Pricing & limits

Pay-as-you-go, billed per second of processed video (to the cent). You're charged when a job is accepted and automatically refunded if it fails.

StandardSecure
1080p$1.80 / min ($0.03/sec)$3.60 / min ($0.06/sec)
4K$3.60 / min ($0.06/sec)$7.20 / min ($0.12/sec)

Privacy is identical on both tiers. Secure adds the proof & control layer: signed deletion certificates, an audit log, and configurable retention. Limits: 10-minute max length, 2 GB max file size. New accounts start with free sandbox credits.

Privacy & data retention

Your data is removed two ways:

  • On demand — call DELETE /v1/jobs/{id} anytime (recommended right after you download). We suggest deleting promptly, and the download response reminds you with the scheduled auto-delete date.
  • Automatically at 30 days — if you never delete, we permanently remove all files once the job passes its retention window. You don't have to do anything.

On the Secure tier, every deletion (on-demand or automatic) can be proven with a signed deletion certificate. We never train on, and never sell, your data.

Next steps

Create an API key →  ·  Try the interactive reference →  ·  OpenAPI spec →