API

Authentication

Base URL:

https://api.bgless.video/v1

Unscreen-compatible migration endpoints are available at:

https://api.bgless.video/v1.0/videos

Use an API key from /settings/apikeys.

Authorization: Bearer sk_...

X-Api-Key is also accepted.

API keys can optionally have a monthly credit quota. When a key would exceed its quota, job creation returns 429 rate_limited before submitting provider work.

Upload

Request a presigned upload URL:

curl -X POST https://api.bgless.video/v1/uploads \
  -H "Authorization: Bearer $BGLESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "input.mp4",
    "contentType": "video/mp4",
    "sizeBytes": 123456
  }'

Response:

{
  "data": {
    "uploadUrl": "https://storage.example.com/presigned-put-url",
    "fileUrl": "https://cdn.example.com/uploads/source/file.mp4",
    "method": "PUT",
    "headers": {
      "Content-Type": "video/mp4"
    },
    "fileUrlExpiresAt": "2026-05-08T12:00:00.000Z",
    "sizeBytes": 123456,
    "uploaded": false,
    "directUpload": true
  }
}

Then upload the file with PUT to data.uploadUrl using the returned headers. Use data.fileUrl when creating a job. Same-origin R2 file URLs are signed and expire after 24 hours.

For already-hosted files, send { "url": "https://example.com/input.mp4" } and use the returned fileUrl.

Estimate Job

Estimate credits, ETA, and current balance before submitting provider work. This endpoint does not create a job and does not spend KIE credits.

curl -X POST https://api.bgless.video/v1/jobs/estimate \
  -H "Authorization: Bearer $BGLESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "mode": "text",
      "prompt": "a floating product bottle rotating slowly",
      "durationSec": 3,
      "resolution": "720p"
    },
    "options": {
      "outputs": ["webm-vp9-alpha"],
      "preset": "web-app"
    }
  }'

Response:

{
  "data": {
    "provider": "kie",
    "model": "kie.kling-3-video",
    "credits": 48,
    "etaSec": 120,
    "remainingCredits": 100,
    "quota": null,
    "canAfford": true
  }
}

For browser-selected files that are not uploaded yet, the web app can estimate from mode, duration, resolution, outputs, and model before direct upload.

Models

List available public RGBA models:

curl https://api.bgless.video/v1/models

The response includes each model id, provider, display name, supported modes, capabilities, and output kind. Use the returned model id as model when creating or estimating a job.

Create Job

curl -X POST https://api.bgless.video/v1/jobs \
  -H "Authorization: Bearer $BGLESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "mode": "video",
      "videoUrl": "https://cdn.example.com/input.mp4",
      "resolution": "1080p",
      "refineEdges": true
    },
    "options": {
      "outputs": ["webm-vp9-alpha", "mov-prores4444"],
      "preset": "web-app",
      "callbackUrl": "https://example.com/webhooks/bgless",
      "callbackSecret": "replace-with-your-secret"
    }
  }'

Response is 202 Accepted with a queued job and pollUrl.

/api/v1/alpha-videos is an alias for /api/v1/jobs for clients that prefer the alpha-video resource name.

Supported output values are webm-vp9-alpha, mov-prores4444, animated-webp, gif, apng, png-sequence, and matte-grayscale-mp4.

Unscreen Compatibility

For migrations from the older Unscreen API shape, use X-Api-Key and POST /v1.0/videos with video_url or video_file.

curl -X POST https://api.bgless.video/v1.0/videos \
  -H "X-Api-Key: $BGLESS_API_KEY" \
  -F "video_url=https://cdn.example.com/input.mp4" \
  -F "format=pro_bundle" \
  -F "webhook_url=https://example.com/webhooks/unscreen"

The compatibility layer maps pro_bundle to bgless WebM alpha plus an alpha matte MP4, returns Unscreen-style data.type = "video" responses, and supports GET /v1.0/videos/:id and DELETE /v1.0/videos/:id.

For short jobs you can request bounded synchronous waiting:

curl -X POST "https://api.bgless.video/v1/jobs?wait=true&timeout=30" \
  -H "Authorization: Bearer $BGLESS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

The API returns 200 when the job reaches a terminal status inside the timeout. It still returns 202 with pollUrl when the job is still queued, processing, or transcoding.

For existing alpha videos that only need format conversion, set input.alphaStrategy to preserve-source-alpha. The job is routed to the local transcoder (local.ffmpeg-encoder) and does not submit a KIE generation task.

Query Job

curl https://api.bgless.video/v1/jobs/job_id \
  -H "Authorization: Bearer $BGLESS_API_KEY"

Successful transcoded jobs include outputAssets, previewAssets for checkerboard/dark/light previews, and qaReport. QA JSON artifacts are also listed in previewAssets with kind: "qa".

Statuses:

  • queued
  • submitted
  • processing
  • transcoding
  • success
  • failed
  • canceled

Download

curl -L "https://api.bgless.video/v1/jobs/job_id/download?format=webm-vp9-alpha" \
  -H "Authorization: Bearer $BGLESS_API_KEY"

Delete

curl -X DELETE https://api.bgless.video/v1/jobs/job_id \
  -H "Authorization: Bearer $BGLESS_API_KEY"

Deleting a running job cancels it first, then hides it from job history. For R2-backed assets, deletion also makes a best-effort attempt to remove stored source, output, preview, and QA objects.

Webhooks

When options.callbackUrl is set, terminal jobs are sent to the user webhook. If options.callbackSecret is set, delivery includes:

X-Bgless-Signature: t=unix_timestamp,v1=hmac_sha256(secret, t + "." + body)

Events are job.completed, job.failed, and job.canceled.

Provider webhooks from KIE must target:

https://bgless.video/api/v1/webhooks/kie

Set KIE_WEBHOOK_HMAC_KEY in production.