koala

API REFERENCE

Koala API

Base URL: https://koala.brighter.la/api

No API key is required during early access. All endpoints are CORS-enabled and stateless: images are processed in memory and never stored. Responses are deterministic — the same input and parameters always produce the same output, so results are safe to cache. An optional Authorization: Bearer header and Idempotency-Key are accepted for forward-compatibility with paid tiers.

Quick start

curl -X POST "https://koala.brighter.la/api/compress?preset=web" \
  -H "Content-Type: image/png" \
  --data-binary @screenshot.png \
  -o screenshot-optimized.png -D -
POST/api/compress

Compress a single image. Send the raw bytes as the request body (any image/* content type), or multipart/form-data with the image in a file field. The optimized image is returned as the response body; metrics are in the headers. Optionally pass the original file name via an X-File-Name header (URL-encoded) so the Content-Disposition filename matches.

ParameterValuesDescription
presetweb | max | quality | avifCompression profile. Default "web" (smart lossy). "avif" also converts to AVIF.
formatauto | jpeg | png | webp | avifOutput format. Default "auto" keeps the input format (TIFF→JPEG, GIF→PNG).
quality1–100Explicit encoder quality. Omit to let the smart-lossy engine pick per image.
losslesstrue | falseTrue lossless for PNG/WebP/AVIF (JPEG falls back to near-lossless q95, 4:4:4).
striptrue | falseStrip EXIF/XMP/ICC metadata. Default true. EXIF rotation is applied before stripping.
# convert a PNG to AVIF at maximum squeeze
curl -X POST "https://koala.brighter.la/api/compress?format=avif&preset=max" \
  -H "Content-Type: image/png" \
  --data-binary @hero.png -o hero.avif
POST/api/compress-url

Fetch a remote image and compress it — built for AI-generation pipelines that hand you temporary URLs. Send JSON with a url plus any of the shared parameters, or use query parameters. A GET variant (/api/compress-url?url=…) exists for quick tests.

curl -X POST "https://koala.brighter.la/api/compress-url" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/render.png", "format": "webp"}' \
  -o render.webp
POST/api/batch

Compress up to 20 images in one request and receive a ZIP. Send multipart/form-data with multiple files, or JSON with a urls array. Shared parameters apply to every image (query params for multipart, JSON fields for URLs). The response includes an X-Job-Id header for /api/status/:id.

curl -X POST "https://koala.brighter.la/api/batch?format=webp" \
  -F "file=@one.jpg" -F "file=@two.png" -F "file=@three.jpg" \
  -o koala-optimized.zip
GET/api/status/:id

Per-file progress and results for a batch job. Jobs are kept in memory for 10 minutes. Batches are processed synchronously within the request, so on the hosted platform this is most useful for post-hoc inspection; self-hosted deployments can poll it live.

{
  "id": "5f2b…", "status": "completed", "total": 3, "completed": 3,
  "files": [
    { "name": "one.jpg", "status": "completed",
      "originalSize": 612352, "compressedSize": 231188,
      "savings": 0.6224, "format": "webp" }
  ]
}
GET/api/health

Service liveness, supported formats and presets.

Response headers

ParameterValuesDescription
X-Original-SizebytesSize of the uploaded image.
X-Compressed-SizebytesSize of the optimized image.
X-Savings0–1Fraction of bytes saved, e.g. "0.6224" = 62% smaller.
X-Width / X-HeightpxOutput dimensions.
X-Qualitynumber | lossless | original"original" means the file was already optimal and returned untouched.
X-EnginestringEncoder used: mozjpeg, libimagequant+zlib, libwebp, libaom-av1, or original.

Errors & limits

Errors return JSON: { "error": { "code", "message" } } with status 400 (bad parameters), 413 (too large), 415 (undecodable image), 422 (remote fetch failed) or 500. Limits: 25 MB per image, 14,000px per side, 20 images per batch request. Hosted note: the hosted platform caps request bodies at ~4.5 MB — send larger files from a self-hosted deployment, where the full 25 MB applies.