DOCUMENTATION

Video Convert API

Bucket-to-bucket video processing for S3-compatible storage.

Open test console

How it works

Submit a JSON job describing a source bucket/object and a destination bucket/object. The worker downloads the source object, converts it with FFmpeg, writes the completed video and optional thumbnail to the destination bucket, and pushes progress through WebSocket events. The browser never uploads the original video to the API.

Create a job

curl -X POST https://api.example.com/api/v1/jobs \
  -H 'content-type: application/json' \
  -d '{
    "sourceBucket": "original-media",
    "sourceKey": "uploads/movie.mp4",
    "sourceRegion": "us-east-1",
    "sourceAccessKeyId": "SOURCE_KEY",
    "sourceSecretAccessKey": "SOURCE_SECRET",
    "destinationBucket": "converted-media",
    "destinationKey": "converted/movie.mp4",
    "destinationRegion": "us-east-1",
    "destinationAccessKeyId": "DESTINATION_KEY",
    "destinationSecretAccessKey": "DESTINATION_SECRET",
    "outputFormat": "mp4",
    "resolution": "1080p",
    "normalizeHdr": true,
    "thumbnail": true,
    "destinationThumbnailKey": "previews/movie.jpg",
    "webhookUrl": "https://customer.example/webhooks/video",
    "webhookSecret": "replace-with-a-random-secret"
  }'

The API returns 202 Accepted with a job object and statusUrl. A job is created before source download begins, so source credentials, missing objects, and FFmpeg errors remain visible in the job history.

Endpoints

MethodPathPurpose
GET/healthService and queue health.
POST/api/v1/jobsCreate a bucket-to-bucket conversion job with JSON.
GET/api/v1/jobsList jobs for the operations dashboard.
GET/api/v1/jobs/:idRead one job and its progress percentage.
DELETE/api/v1/jobs/:idRemove a job record.
WebSocket/wsReceive snapshots, health, and job lifecycle/progress events.

Storage fields

Source fields are sourceBucket, sourceKey, sourceRegion, sourceEndpoint, sourceAccessKeyId, sourceSecretAccessKey, and sourceForcePathStyle. Destination fields use the corresponding destination prefix and add destinationThumbnailKey. Custom endpoints support R2, MinIO, Wasabi, and other S3-compatible providers.

Credentials are used in memory for the job and are not returned in the job response or written to the JSON job store. Use least-privilege credentials limited to the required source object and destination prefix.

Media processing

outputFormat accepts mp4 or webm. resolution accepts original, 360p, 480p, 720p, 1080p, 1440p, 2160p, or custom with width and height. fit selects contain, cover, or stretch. Set cropEnabled with cropWidth, cropHeight, cropX, and cropY to crop before resizing.

Set thumbnail=true and optionally thumbnailTime and destinationThumbnailKey to create a JPEG. MP4 uses fast-start metadata placement. HDR normalization is enabled by default and converts HDR/Apple HDR to 8-bit SDR BT.709 with yuv420p for Android-compatible playback.

WebSocket events

Connect to wss://api.example.com/ws in production. The server sends snapshot, health, job.created, job.updated, and job.deleted. Job updates include progress values for source download, FFmpeg conversion, and destination delivery.

Webhooks

Configured webhooks receive job.completed or job.failed as JSON. If a webhook secret is supplied, verify x-video-convert-signature as sha256=HMAC_SHA256(raw_request_body, webhookSecret) before parsing the body. Delivery is best-effort and logged on failure.

Coolify deployment

Use the included Dockerfile, expose port 3000, mount persistent storage at /app/data, and provide adequate temporary storage at /app/temp. Set WORKER_CONCURRENCY=1 and optionally FFMPEG_THREADS=2 on a small VPS. The source and destination buckets must be reachable from the VPS.