{"openapi":"3.1.0","info":{"title":"Universal Compression API","version":"1.0.0","description":"A single endpoint that compresses images and PDFs. No API key, no account, no signup.\n\n**Uniform contract.** Every supported file type goes through the same request shape and returns\nthe same response shape. Only the `kind` field and a handful of nullable metadata fields differ\nbetween an image and a PDF, so a client needs one code path rather than one per format.\n\n**Two ways to ask for compression.** Set `mode` for a fixed aggressiveness level, or set\n`target_size` to name a size budget such as `4mb` and let the server search for settings that fit.\nWhen both are supplied, `target_size` wins.\n\n**Never worse than the input.** Already-optimised files often grow when re-encoded. If that\nhappens the original bytes are returned unchanged with an explanation in `warnings`, so the\noutput is never larger than what you sent.\n\n**Three ways to get the file back.** `response=json` (the default) returns metadata and URLs.\n`response=binary` returns the compressed file as the response body, with every metadata field\nmoved into `X-Compress-*` headers. `response=base64` keeps the JSON and adds the bytes as\n`output.data_base64`. The last two save a round trip; `binary` also avoids base64's 33% overhead\nand has no size limit.\n\n**Engines.** Images are encoded by libvips via sharp, with ImageMagick used purely as a decoder\nfor formats libvips cannot open such as HEIC. PDFs get a lossless qpdf structural pass, and for\nanything beyond `lossless` a Ghostscript pass that resamples the images embedded in the document.\n\n**Retention.** Stored files expire after 3600 seconds. The deadline is\nreturned as `expires_at` on every response.","license":{"name":"AGPL-3.0-or-later","url":"https://www.gnu.org/licenses/agpl-3.0.html"}},"components":{"schemas":{}},"paths":{"/v1/compress":{"post":{"summary":"Compress an image or PDF","tags":["compress"],"description":"Accepts any supported image format or a PDF and returns before/after sizes and URLs.\n\nThe inbound contract is identical for every file type. Supply `mode` for a fixed\naggressiveness level, or `target_size` to have the server search for settings that fit a\nsize budget. `target_size` overrides `mode`.\n\nIf compression cannot beat the original, the original is returned unchanged with an\nexplanatory entry in `warnings`, so the output is never larger than the input.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The image or PDF to compress."},"mode":{"type":"string","enum":["lossless","light","balanced","aggressive","extreme"],"default":"balanced","description":"Compression aggressiveness. Ignored when `target_size` is supplied. `lossless` never re-encodes image data."},"target_size":{"type":"string","description":"Desired maximum output size. Accepts a raw byte count or a size string such as `4mb`, `500kb`, `1.5gb`. Overrides `mode` and switches the engine into search mode.","example":"4mb"},"output_format":{"type":"string","enum":["auto","jpeg","png","webp","avif","pdf"],"default":"auto","description":"`auto` preserves the input format. Anything else transcodes. `pdf` is only valid for PDF input."},"max_dimension":{"type":"integer","minimum":16,"maximum":30000,"description":"Cap the long edge of an image in pixels. Ignored for PDF input."},"strip_metadata":{"type":"boolean","default":true,"description":"Remove EXIF, XMP, ICC and document info."},"response":{"type":"string","enum":["json","binary","base64"],"default":"json","description":"How to deliver the compressed bytes.\n\n- `json` (default): metadata and URLs only.\n- `binary`: the compressed file as the raw response body. Every metadata field is returned\n  as an `X-Compress-*` header, so nothing is lost. Avoids base64 overhead and a second request.\n- `base64`: the usual JSON with the bytes added as `output.data_base64`. Subject to the\n  server's inline size limit; above it the field is null and a warning explains why.\n\nSending `Accept: application/octet-stream` selects `binary` when this field is omitted."}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Source file to fetch. Requires `ALLOW_URL_INPUT=true` on the server."},"mode":{"type":"string","enum":["lossless","light","balanced","aggressive","extreme"],"default":"balanced","description":"Compression aggressiveness. Ignored when `target_size` is supplied. `lossless` never re-encodes image data."},"target_size":{"type":"string","description":"Desired maximum output size. Accepts a raw byte count or a size string such as `4mb`, `500kb`, `1.5gb`. Overrides `mode` and switches the engine into search mode.","example":"4mb"},"output_format":{"type":"string","enum":["auto","jpeg","png","webp","avif","pdf"],"default":"auto","description":"`auto` preserves the input format. Anything else transcodes. `pdf` is only valid for PDF input."},"max_dimension":{"type":"integer","minimum":16,"maximum":30000,"description":"Cap the long edge of an image in pixels. Ignored for PDF input."},"strip_metadata":{"type":"boolean","default":true,"description":"Remove EXIF, XMP, ICC and document info."},"response":{"type":"string","enum":["json","binary","base64"],"default":"json","description":"How to deliver the compressed bytes.\n\n- `json` (default): metadata and URLs only.\n- `binary`: the compressed file as the raw response body. Every metadata field is returned\n  as an `X-Compress-*` header, so nothing is lost. Avoids base64 overhead and a second request.\n- `base64`: the usual JSON with the bytes added as `output.data_base64`. Subject to the\n  server's inline size limit; above it the field is null and a warning explains why.\n\nSending `Accept: application/octet-stream` selects `binary` when this field is omitted."}}}}}},"responses":{"200":{"description":"JSON by default. With `response=binary` the body is the compressed file itself and every metadata field is returned as an `X-Compress-*` header instead.","content":{"application/json":{"schema":{"type":"object","required":["id","status","input","output","savings","target","engine","warnings","duration_ms","expires_at"],"properties":{"id":{"type":"string","examples":["cmp_01K9X7Q2ZB8N4T6V0YJ3M5R7WD"]},"status":{"type":"string","enum":["ok"]},"input":{"type":"object","required":["filename","kind","mime","bytes","bytes_human","url","download_url","width","height","pages"],"properties":{"filename":{"type":"string"},"kind":{"type":"string","enum":["image","pdf"]},"mime":{"type":"string"},"bytes":{"type":"integer"},"bytes_human":{"type":"string","examples":["17.6 MB"]},"url":{"type":"string","format":"uri","description":"Inline URL for this variant."},"download_url":{"type":"string","format":"uri","description":"Same file with a forced download disposition."},"width":{"type":["null","integer"],"description":"Null for PDF input."},"height":{"type":["null","integer"],"description":"Null for PDF input."},"pages":{"type":["null","integer"],"description":"Null for image input."},"data_base64":{"type":["null","string"],"description":"The file itself, base64 encoded. Present on the output descriptor only when `response=base64`, and null if the result exceeded the inline size limit."}}},"output":{"type":"object","required":["filename","kind","mime","bytes","bytes_human","url","download_url","width","height","pages"],"properties":{"filename":{"type":"string"},"kind":{"type":"string","enum":["image","pdf"]},"mime":{"type":"string"},"bytes":{"type":"integer"},"bytes_human":{"type":"string","examples":["17.6 MB"]},"url":{"type":"string","format":"uri","description":"Inline URL for this variant."},"download_url":{"type":"string","format":"uri","description":"Same file with a forced download disposition."},"width":{"type":["null","integer"],"description":"Null for PDF input."},"height":{"type":["null","integer"],"description":"Null for PDF input."},"pages":{"type":["null","integer"],"description":"Null for image input."},"data_base64":{"type":["null","string"],"description":"The file itself, base64 encoded. Present on the output descriptor only when `response=base64`, and null if the result exceeded the inline size limit."}}},"savings":{"type":"object","required":["bytes","percent","ratio"],"properties":{"bytes":{"type":"integer","description":"Bytes saved. Zero when the original was kept."},"percent":{"type":"number","examples":[86.9]},"ratio":{"type":"number","description":"input bytes / output bytes.","examples":[7.65]}}},"target":{"type":"object","required":["requested_bytes","met"],"properties":{"requested_bytes":{"type":["null","integer"]},"met":{"type":["null","boolean"],"description":"Null when no target was requested. False when the target was unreachable."}}},"engine":{"type":"object","required":["name","version","strategy","attempts","settings"],"properties":{"name":{"type":"string","enum":["sharp","ghostscript","qpdf","passthrough"]},"version":{"type":"string"},"strategy":{"type":"string","enum":["mode-preset","quality-bisect","ladder-bisect","none"]},"attempts":{"type":"integer"},"settings":{"type":"object","additionalProperties":true}}},"warnings":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"}}}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}},"413":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}},"429":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}}}}},"/f/{id}/{variant}/{filename}":{"get":{"summary":"Fetch a stored original or compressed file","tags":["files"],"description":"Files are removed once the retention window elapses. The trailing filename segment is cosmetic; lookup uses the id and variant only.","parameters":[{"schema":{"type":"string"},"in":"query","name":"download","required":false,"description":"Any truthy value forces an attachment disposition."},{"schema":{"type":"string"},"example":"cmp_01K9X7Q2ZB8N4T6V0YJ3M5R7WD","in":"path","name":"id","required":true},{"schema":{"type":"string","enum":["original","compressed"]},"in":"path","name":"variant","required":true},{"schema":{"type":"string"},"in":"path","name":"filename","required":true}],"responses":{"200":{"description":"The file bytes.","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}}}}},"/v1/compress/{id}":{"delete":{"summary":"Delete a stored result before it expires","tags":["files"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","id"],"properties":{"status":{"type":"string","enum":["deleted"]},"id":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","error","message"],"properties":{"status":{"type":"string","enum":["error"]},"error":{"type":"string","description":"Stable machine-readable code.","example":"unsupported_media_type"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}}}}}}},"/healthz":{"get":{"summary":"Liveness and engine availability","tags":["meta"],"description":"Reports `degraded` when Ghostscript or qpdf is missing, since PDF compression is unavailable without them.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","uptime_seconds","engines"],"properties":{"status":{"type":"string","enum":["ok","degraded"]},"uptime_seconds":{"type":"number"},"queue_depth":{"type":"integer","description":"Compressions running or queued right now."},"engines":{"type":"object","additionalProperties":{"type":"object","properties":{"available":{"type":"boolean"},"version":{"type":["null","string"]}}}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["status","uptime_seconds","engines"],"properties":{"status":{"type":"string","enum":["ok","degraded"]},"uptime_seconds":{"type":"number"},"queue_depth":{"type":"integer","description":"Compressions running or queued right now."},"engines":{"type":"object","additionalProperties":{"type":"object","properties":{"available":{"type":"boolean"},"version":{"type":["null","string"]}}}}}}}}}}}},"/v1/formats":{"get":{"summary":"Formats this deployment can actually process","tags":["meta"],"description":"Probed against the binaries present in the running container, so it reflects reality rather than a static list.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["images","documents","engines","limits"],"properties":{"images":{"type":"object","required":["native","via_fallback"],"properties":{"native":{"type":"array","items":{"type":"string"},"description":"Decoded directly by libvips."},"via_fallback":{"type":"array","items":{"type":"string"},"description":"Decoded by ImageMagick first. Empty if ImageMagick is unavailable."}}},"documents":{"type":"array","items":{"type":"string"}},"engines":{"type":"object","additionalProperties":{"type":"object","properties":{"available":{"type":"boolean"},"version":{"type":["null","string"]}}}},"limits":{"type":"object","properties":{"max_upload_bytes":{"type":"integer"},"max_input_pixels":{"type":"integer"},"max_pdf_pages":{"type":"integer"},"retention_seconds":{"type":"integer"},"url_input_enabled":{"type":"boolean"}}}}}}}}}}},"/openapi.json":{"get":{"summary":"The OpenAPI 3.1 document for this API","tags":["meta"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}}},"servers":[{"url":"https://compress.agentic.ae","description":"This deployment"}],"tags":[{"name":"compress","description":"Compress a file."},{"name":"files","description":"Retrieve or delete stored results."},{"name":"meta","description":"Capabilities and health of this deployment."}]}