Skip to content
Image KB Reducer
Esc
↑↓navigate↵open⌘Jpreview
On this page

Overview

A hosted endpoint for the same compress job the CLI and library run — for anything that isn't already a Node process.

50 KB or less, at the highest quality possible — never exactly 50.000 KB.

The HTTP API is the fourth surface for that promise, alongside the website, the CLI, and the library — and it shares the CLI’s own backend: POST /v1/compress runs the exact same compressJob/runJob recipe over the exact same wasm codecs, deployed as a Cloudflare Worker at api.imagekbreducer.com. Script it, the CLI, or the library against the same input and get back the same bytes — for every input this endpoint accepts. It accepts fewer than the other two: no HEIC, and lower byte and pixel ceilings. Limits has each refusal and its reason; the parity note on the homepage covers the separate question of why the browser is not byte-identical to any of them.

Use this when the compression has to happen from somewhere that isn’t already running Node — a Rails, Django, or PHP backend; a mobile app’s server side; a CI system that can’t shell out to npx. If your own code already runs on Node, the library is a function call away and has no network hop at all.

One call

curl https://api.imagekbreducer.com/v1/compress \
  -H "Authorization: Bearer $IKB_API_KEY" \
  -F file=@photo.jpg \
  -F target=50kb \
  -o photo-compressed.jpg

file and target are the only required fields. file must be JPEG, PNG, or WebP — HEIC and AVIF are refused with 415 unsupported-format, which is worth knowing before your first call, because a photo straight off an iPhone is HEIC by default. Convert it first, or use the CLI or the web app, which decode HEIC natively; see Limits for why this endpoint can’t.

The response, on success, is the compressed image’s raw bytes with a Content-Type matching the format it was encoded to, plus a handful of X-* headers describing what happened:

Header Meaning
X-Original-Bytes size of the uploaded file
X-Result-Bytes size of the compressed result — always at or under target
X-Attempts how many encode attempts the search made
X-Result-Width / X-Result-Height pixel dimensions of the result
X-Warnings comma-separated warning codes, e.g. metadata-stripped,downscale-applied

The whole surface

Route Auth Purpose
POST /v1/compress required compress file to target, optionally pinning format and allow_downscale
GET /v1/health none liveness check — { ok: true, version: "…" }
OPTIONS /v1/compress none 204 with Allow: POST — not a CORS preflight response, see Authentication

Full field-by-field detail lives in the reference below, generated from openapi.yaml.

Where to go next

This surface is new (v0.1.0) and single-endpoint by design — it exists to serve one job well, not to expose the library’s full resize/crop/rotate/strip recipe set over HTTP. If you need those, run the library or the CLI directly.

Was this page helpful?