POST /v1/shrink

Optimize an image. Body is the raw image bytes.

Request

POST /v1/shrink HTTP/1.1
Authorization: Bearer img_live_...
Content-Type: image/jpeg
X-Options: {"output":"webp","quality":80,"qualityTier":"balanced"}
Idempotency-Key: 6df7a9...        (optional)
 
<binary image bytes>

Query

ParamTypeDefaultNotes
asyncboolfalseIf true, returns 202 immediately with jobId.

X-Options (JSON, all optional)

FieldTypeDefaultNotes
output"auto"|"jpeg"|"png"|"webp"|"avif""auto"auto keeps input format.
qualityint 1–10080Ignored for lossless PNG.
qualityTier"fast"|"balanced"|"max""balanced"See overview.
resize{width?,height?,fit,withoutEnlargement}fit: cover/contain/fill/inside/outside.
losslessboolfalseFor PNG/WebP/AVIF.
effortint 0–96Encoder effort.
keepMetadataboolfalseStrip EXIF/XMP/ICC by default.
metricsboolfalseCompute PSNR and include in response.

Content-Type

One of: application/octet-stream, image/jpeg, image/png, image/webp, image/avif, image/gif, image/tiff.

Idempotency

Pass Idempotency-Key to make retries safe — the gateway returns the same jobId for the same key on your account.

Response (sync)

{
  "jobId": "f5012a57-9bd7-47b9-9eaf-6f9c00356872",
  "status": "completed",
  "cached": false,
  "outputBytes": 8465,
  "ratio": 0.74,
  "width": 600,
  "height": 360,
  "outputFormat": "webp",
  "downloadUrl": "https://storage.pixozip.pretzl.dev/.../?X-Amz-..."
}

cached: true means the result came from the 7-day per-account cache — no token was charged.

Response (?async=true)

{ "jobId": "ae96eb91-e353-45e0-a6b2-fbb3a9bd6a52", "status": "queued" }

Then poll GET /v1/jobs/:id.

Errors

400 unsupported_or_corrupt_image, 402 quota_exhausted, 413 file_too_large, 429. See Errors.