Compression API — Free Tier + Pay-As-You-Go
Compress video, image, PDF, and audio files programmatically. Quality presets, resolution scaling, and a real byte-ceiling mode for video and audio.
What it does
The Compression API is `POST /v1/convert` driven by a `toolOperation` that selects a compression pipeline instead of a format change: `video-compressor` (FFmpeg), `image-compressor` (Sharp), `compress-audio` (FFmpeg), and `compress-pdf` (Ghostscript), alongside the narrower `compress-png`, `compress-jpg`, `optimize-gif`, `compress-svg`, `compress-word` and `compress-powerpoint` operations. Compression is quality-based. For video, `quality=high|medium|low` maps to CRF 26, 32 or 38 with a matching x264 preset and a 128k / 96k / 64k audio ladder; `resolution=1280x720` rescales on the width while keeping the aspect ratio, `fps` lowers the frame rate, `removeAudio=true` drops the audio track, and `twoPass=true` runs a two-pass encode at a fixed bitrate derived from the quality tier and the output resolution.
Video and audio compression also accept `targetSize=25`, a hard ceiling in MB (1-500) that replaces the quality tier: the engine probes the duration, splits the byte budget into a video and an audio bitrate, encodes two-pass, measures the file it actually produced, and re-encodes at a corrected bitrate if it came out over — at most two retries, stepping the resolution and frame rate down when the corrected bitrate falls under the ~100 kbps floor. A target that cannot hold the duration fails with `TARGET_SIZE_INFEASIBLE` and the length that would fit; an over-cap file is never returned as a success. Images re-encode through Sharp with a 1-100 `quality` dial for JPEG, PNG, WebP and AVIF.
Audio takes either a CBR `bitrate` override or a `quality` tier that maps to VBR, keeping ID3 tags and (where the container allows it) cover art. PDFs run through Ghostscript with `pdfQuality=screen|ebook|printer|prepress` — default `ebook`, 150 DPI — which downsamples embedded raster images, subsets fonts and drops unused objects while leaving text selectable rather than rasterised; if the rewritten PDF ends up larger than the source, the original is returned instead. One file per request: poll `GET /v1/status/{jobId}`, then fetch the output from `GET /v1/download/{jobId}`.
Supported formats
Source formats (20)
- mp4
- mov
- mkv
- webm
- avi
- wmv
- flv
- jpg
- png
- webp
- tiff
- heic
- gif
- mp3
- wav
- flac
- m4a
- aac
- ogg
Target formats (11)
- mp4
- mov
- mkv
- webm
- jpg
- png
- webp
- mp3
- wav
- flac
Quick start
Every sample posts the job, then polls /v1/status/{jobId} until it finishes, with your API key in the X-Api-Key header. The parameter names below are the ones the endpoint actually accepts — anything else is dropped rather than rejected.
curl -X POST https://api.convertintomp4.com/v1/convert \
-H "X-Api-Key: ck_your_api_key" \
-F "file=@input.mp4" \
-F "targetFormat=mp4" \
-F "toolOperation=video-compressor" \
-F "targetSize=25" \
-F "resolution=1280x720"import { readFileSync } from "node:fs";
import { ConvertIntoMP4Client } from "convertintomp4";
const apiKey = process.env.CIM4_API_KEY;
const client = new ConvertIntoMP4Client({ apiKey });
// Two ways to drive it:
// quality: high | medium | low -> CRF 26 | 32 | 38, size is whatever it lands on
// targetSize: 1-500 (MB) -> hard ceiling, iterated until it fits or fails
const { jobId } = await client.uploadDirect(
readFileSync("input.mp4"),
"input.mp4",
"video/mp4",
{
targetFormat: "mp4",
toolOperation: "video-compressor",
targetSize: 25, // never returns a file above this — fails instead
resolution: "1280x720",
},
);
let job;
do {
await new Promise((r) => setTimeout(r, 2000));
job = await fetch(`https://api.convertintomp4.com/v1/status/${jobId}`, {
headers: { "X-Api-Key": apiKey },
}).then((r) => r.json());
} while (job.status !== "completed" && job.status !== "failed");
// outputSize is guaranteed <= targetSize * 1024 * 1024 when status is completed
console.log("Compressed:", job.result?.downloadUrl, job.result?.outputSize);import time, requests
from convertintomp4 import Client
api_key = "ck_your_api_key"
client = Client(api_key=api_key)
# pdfQuality: screen | ebook | printer | prepress (default ebook, 150 DPI)
with open("input.pdf", "rb") as f:
job = client.upload_direct(
f, "input.pdf", "application/pdf", "pdf",
tool_operation="compress-pdf",
pdfQuality="ebook",
)
while True:
status = requests.get(
f"https://api.convertintomp4.com/v1/status/{job['jobId']}",
headers={"X-Api-Key": api_key},
).json()
if status["status"] in ("completed", "failed"):
break
time.sleep(2)
result = status.get("result", {})
print("Compressed:", result.get("downloadUrl"), result.get("outputSize"))Features
- One endpoint for video, image, PDF and audio — pick the pipeline with `toolOperation`
- Video: FFmpeg CRF ladder (high/medium/low → CRF 26/32/38) plus `resolution` and `fps` scaling
- Byte-ceiling mode for video and audio: `targetSize=25` (MB, 1-500) — verified against the real output, up to 2 corrective retries
- A target that cannot fit fails with `TARGET_SIZE_INFEASIBLE` and the duration that would — never an over-cap file reported as success
- Optional two-pass video encode at a fixed bitrate (`twoPass=true`)
- Images: Sharp re-encode with a 1-100 `quality` dial (JPEG, PNG, WebP, AVIF)
- PDF: Ghostscript image downsampling, font subsetting and dead-object removal via `pdfQuality`
- Audio: CBR `bitrate` override or `quality`-driven VBR, ID3 tags and cover art kept
- PDF safety net: if the rewrite comes out larger than the source, the original is returned
Pricing
From $9.99/mo (Pro) or $24.99/mo (Business) — or pay-as-you-go on the API plan.
Free tier: 5 conversions/day, 100 MB file size, no API key required (IP-gated). Pro $9.99/mo: 100/day (2,000/month), 2 GB files. Business $24.99/mo: 1,000/day (20,000/month), 10 GB files, GPU encoding, dedicated support.
See full pricing breakdown →Built for production
99.9% uptime SLA
Multi-region failover, transparent status page, 60-second response-time guarantee on Business.
Encryption + auto-delete
TLS 1.2+ in transit, AES-256 at rest. Files deleted after 1h / 24h / 7d depending on plan, or instantly via DELETE endpoint. See the security page.
~7s median latency
Most sub-100 MB jobs complete in 6-9 seconds. Webhook-driven async for heavier workloads; waitForJob for synchronous flows.
Frequently Asked Questions
Can I ask the API for a specific output size?
Yes, for video and audio: send `targetSize=25` (MB, 1-500) with `toolOperation=video-compressor` or one of the audio compression operations. The engine probes the duration, takes `targetMB × 8192 ÷ duration_seconds` as the total kbps, trims 5% for container and rate-control overhead, subtracts the audio allowance to get the video bitrate, encodes two-pass, then stats the file it actually wrote. The audio allowance follows a quality ladder (128 kbps stereo down to 48 kbps mono) and steps down that ladder whenever a richer rung would leave the video under its ~100 kbps floor, so a size is only refused when even the cheapest audio rung cannot fit. If it came out over, it re-encodes at a bitrate scaled by the measured overshoot — at most two retries — and steps the resolution and frame rate down when the corrected bitrate falls under the ~100 kbps video floor. The job only completes when `result.outputSize` is at or under your ceiling. `targetSize` is rejected with a 400 on any other operation (including `compress-pdf` and `image-compressor`) rather than silently ignored, so you never get a false positive.
What happens if the target size is impossible?
The job fails with `TARGET_SIZE_INFEASIBLE` and tells you roughly how much video would fit — for example, a 10-minute clip into 8 MB works out below the usable bitrate floor, and the error says about 7 minutes is the most 8 MB can hold. If the encoder still overshoots after all the retries you get `TARGET_SIZE_NOT_REACHED` with the best size achieved. Both are terminal and not retried, because the same request would fail the same way. What you will never get is a completed job whose output is bigger than the ceiling you asked for.
How does the target-size mode pick the audio bitrate?
Audio is a fixed cost taken out of the video's share, so it scales with the total budget: 128 kbps stereo when the budget is roomy, then 96 and 64 kbps stereo, then 64 and 48 kbps mono at the bottom. A 25 MB ceiling on a 10-minute video leaves about 324 kbps total, so audio lands at 64 kbps stereo and video gets the remaining 260 kbps. Pass `audioBitrate` to override the ladder, or `removeAudio=true` to give the entire budget to video.
How much can the API compress a PDF without rasterising the text?
Scanned PDFs usually give the biggest win because the payload is embedded raster images and `pdfQuality=ebook` downsamples them to 150 DPI. Born-digital PDFs (LaTeX, InDesign exports) give much less — the savings come from font subsetting, duplicate-image detection and dropping unused objects. Text and vector art stay as text and vectors; Ghostscript rewrites the file, it does not rasterise the page.
Does video compression re-encode or just remux?
It always re-encodes — that's where the size reduction comes from. `twoPass=true` runs two passes at a fixed bitrate derived from the quality tier and the output resolution (roughly 2500k / 1500k / 900k at 640x360, scaled by pixel count), so it targets a bitrate, not a file size. Use `targetSize` when you need the file size itself pinned; it runs its own two-pass encode at a duration-derived bitrate and verifies the result. If you only want a container change with no re-encode, use the Video Conversion API instead.
Is image metadata preserved?
No. The image compression path re-encodes through Sharp without copying metadata, so EXIF, GPS coordinates and ICC profiles are dropped from the output. That is what you want for privacy-sensitive workflows and a problem if you need camera data downstream — keep the original file if you do.
What are the real limits on email attachments?
Gmail caps outgoing attachments at 25 MB (it switches to a Drive link above that). Other providers differ — Outlook.com and many corporate mail servers sit lower, and some gateways count the base64-encoded size, which is about a third larger than the file on disk. Compress with headroom under whatever your recipient's server allows rather than assuming a single universal number.
Related APIs
- Merge APIMerge PDFs, videos, images, and audio files programmatically. Upload-order concatenation with per-type engines.
- Split APIPull a page range out of a PDF or cut a time range out of a video or audio file via API. One output per request.
- OCR APIOptical character recognition for scanned PDFs and images via API. Tesseract, searchable-PDF or plain-text output, 17 language packs.
- Watermark APIAdd a text or image watermark to PDFs, videos, and images via API. Nine anchor positions, opacity, size, and colour.
- File Conversion APIOne unified file conversion API for video, audio, image, document, ebook, archive, and font formats — 255 formats, 2,290+ conversion pairs.
- Convert APIProduction-grade file conversion API with 9 language SDKs, async webhooks, and cloud-to-cloud workflows. Free tier available.
Or browse the full catalogue of 23 API products →
Get an API key
Start integrating the Compression API in five minutes. Read the docs, grab a key, and ship your first conversion before the trial coffee cools.