compress.target takes a media URL and a target, then searches candidate encodes for the smallest file that still clears the bar. Images are scored with SSIMULACRA2, video with VMAF, and every job returns a report: the achieved score, the compression ratio, and what the search did.
Live. Accepts video, image, and audio URLs.
Compress an image for the web
output.file and the report in output.data. Images finish in about 10 seconds, audio in about 1, video takes longer because every search probe is a real encode plus a VMAF pass.
The report
Every completed job carries the search’s account of itself:status is the honest part. ok means the target was met. infeasible_quality means even the best encode could not reach the score you asked for, and you got the best effort. infeasible_size means the byte cap and the quality floor could not both hold. skipped_no_improvement means no encode beat your original, so the original came back untouched with compressionRatio: 1 and verdict: "passthrough". Set forceReencode: true to get the re-encode anyway.
verdict maps the score to a label. For images: 90+ is visually_lossless, 70+ is high, 50+ is medium, below that low. For video on VMAF: 95+, 90+, and 80+ (acceptable).
Targets
target takes one of four shapes:
The tier thresholds per medium: images clear SSIMULACRA2 90 / 85 / 78, video clears VMAF 96 / 93 / 88. Audio has no metric loop; tiers map to a channel-aware Opus bitrate ladder, so a mono voice track gets half the budget of stereo music.
Codecs
Withcodec: "auto", the pick follows compatibility:
Or pin one:
av1, hevc, h264, vp9, avif, jxl, jpegli, webp, png, opus, aac, mp3, flac, alac. The lossless-only codecs (png, flac, alac) always encode losslessly; combined with a byte budget, the report tells you whether the lossless file fit.
for: "archive" skips the lossy ladder entirely and produces a lossless master: PNG for images, FFV1 in MKV for video, FLAC for audio.
Predict without encoding
dryRun: true runs the search and returns the report with a predicted outputBytes, but writes no file and uploads nothing. output.file is null, the same shape as a data job. Use it to quote a compression before committing to it.
Parameters
string
Delivery posture.
"web" resolves the defaults to sRGB + stripped metadata; "archive" resolves to lossless with everything preserved. Any explicit field you set wins over the profile.string | number | object
default:"balanced"
The compression target. One of the four shapes above.
string
default:"broad"
Decode reach
codec: "auto" must guarantee: "modern", "broad", or "legacy".string
default:"auto"
Output codec, or
"auto" to follow the compatibility ladder.string | number | null
default:"null"
Cap the longest edge: a pixel count or a rung like
"1080p" / "720p". Images downscale before encoding; video scales in-encode and the VMAF score is measured against the full-resolution source.string
default:"preserve"
Transparency:
"preserve", "flatten" (onto white), or a "#RRGGBB" fill color.string
default:"colorOnly"
"all" keeps everything, "colorOnly" strips EXIF and GPS (ICC preservation is best-effort), "none" strips all.string
default:"balanced"
"fast", "balanced", or "thorough" — trades encode time for extra compression on every codec that has a speed knob.boolean
default:"false"
Re-encode even when the result would not beat the original.
boolean
default:"false"
Return the predicted report without producing a file.
object
Video-only policies.
audioTracks: "all" (default), "primary", or "none". subtitles: "strip" (default) or "preserve" (best-effort copy; fails when the output container cannot hold the codec).object
Audio-only policies.
loudnessLufs: normalize to an integrated LUFS target such as -14, or null (default) for off. channels: "preserve" (default), "mono", or "stereo".object
Expert knobs.
metric: "auto" (default), "ssimulacra2", or "vmaf" to override the scoring oracle. floor: a hard minimum score the output must never drop below, in any mode.How the search behaves
The search is a binary search over the encoder’s quality scale, so a job costs about 7 probe encodes at most, each scored against the source. Videos longer than 12 seconds probe on three 2-second samples instead of the full file, and only the final encode runs over everything. A byte-budget search always encodes the full file, because the budget is exact. Compression ratios depend on the input. A camera original shrinks hard; a file that is already well-compressed often comes back asskipped_no_improvement, which is the job telling you the original was already the smallest honest answer.
Errors
A malformed request (an unknown codec name, a removed tuning knob, two target goals at once) returnsVALIDATION_ERROR on POST /jobs before anything is billed. A URL that resolves somewhere Rendobar won’t fetch from returns INPUT_URL_BLOCKED.
After the job starts, failures carry the standard error shape. INPUT_FETCH_FAILED follows the same retryable rules as ffprobe. An infeasible target is not an error: the job completes with status: "infeasible_quality" or "infeasible_size" in the report and the best file the search found.
See also
- Job output: the output shape every job returns
- ffprobe: inspect a file before deciding how to compress it
- FFmpeg: full manual control when you want to write the command yourself
- Webhooks: receive
job.completedinstead of polling