{"openapi":"3.1.0","info":{"title":"Image Tools API - Remove Background, Resize, Convert, Compress","version":"1.0.0","description":"Remove the background of product photos, portraits, animals and logos with an AI segmentation model (BiRefNet), hair and fur edges included, and get a transparent PNG or WebP or a solid color background, optionally cropped to the subject. Plus fast utilities: resize (contain, cover with smart crop, pad, squeeze), convert (JPEG, PNG, WebP, AVIF) and compress (never returns a larger file). Send a URL, a base64 image or a file upload (JPEG, PNG, WebP, GIF up to 10 MB); get the image bytes back, or JSON with base64.\n\nAll endpoints accept GET (query string) or POST (JSON body). Errors use one shape: `{\"success\": false, \"error\": {\"code\", \"message\", \"retryable\"}}`. When a numeric `Retry-After` header is present, `error.retryAfterSeconds` is included.","contact":{"name":"TidyTools","url":"https://apify.com/tidytools"}},"servers":[{"url":"https://webcapture-api.yukailin.workers.dev","description":"Origin (reachable only through the marketplace gateway)"}],"tags":[{"name":"Image"}],"paths":{"/api/v1/image/remove-background":{"get":{"operationId":"removeBackgroundGet","summary":"Remove the background of an image (GET)","description":"Cuts out the main subject (people, products, animals, logos; hair and fur edges kept) with an AI segmentation model (BiRefNet on Cloudflare Images). The result is a transparent PNG (default) or WebP, or, with `bg`, the subject on a solid color (any format, including JPEG). `crop=true` trims the empty margin around the subject (keep some with `cropMargin`). Not made for screenshots and text documents: their white background is removed and text becomes semi-transparent. Typical time 2-8 seconds (10 seconds for a 20+ megapixel photo). Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.","tags":["Image"],"parameters":[{"name":"url","schema":{"type":"string"},"description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead.","required":false,"example":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","in":"query"},{"name":"format","schema":{"type":"string","default":"png","enum":["png","webp","jpeg"]},"description":"Result format. `png` and `webp` keep transparency; `jpeg` needs `bg`.","required":false,"in":"query"},{"name":"bg","schema":{"type":"string"},"description":"Color for the removed background, e.g. `ffffff`, `#f5f5f5`, `rgb(0,0,0)` or `white`. Without it the background is transparent. Alias: `background`.","required":false,"example":"ffffff","in":"query"},{"name":"crop","schema":{"type":"boolean","default":false},"description":"Crop the result to the subject (trims the transparent margin).","required":false,"in":"query"},{"name":"cropMargin","schema":{"type":"integer","default":0,"minimum":0,"maximum":1000},"description":"With crop=true: pixels of margin kept around the subject.","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"quality","schema":{"type":"integer","default":90,"minimum":1,"maximum":100},"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 90.","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}],"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/png":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"remove-background","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg/960px-Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg/960px-Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg","input":{"format":"jpeg","width":960,"height":836,"bytes":127578,"hasAlpha":false,"sha256":"c38bfce39fed7437e535e9cf4a29dd44b3388bdba6b9f137b377beebd30ee6c7"},"output":{"format":"png","contentType":"image/png","width":849,"height":724,"bytes":607008,"transparent":true,"savedBytes":-479430,"savedPercent":-375.8},"options":{"format":"png","bg":null,"crop":true,"cropMargin":0,"maxSize":null,"quality":null},"image":"iVBORw0KGgoAAAANSUhEUgAAA1EAAALUCAYAAADqj7h1AAlC50lEQVR4nOy9...(base64 truncated)","warnings":[],"durationMs":5371}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"removeBackground","summary":"Remove the background of an image","description":"Cuts out the main subject (people, products, animals, logos; hair and fur edges kept) with an AI segmentation model (BiRefNet on Cloudflare Images). The result is a transparent PNG (default) or WebP, or, with `bg`, the subject on a solid color (any format, including JPEG). `crop=true` trims the empty margin around the subject (keep some with `cropMargin`). Not made for screenshots and text documents: their white background is removed and text becomes semi-transparent. Typical time 2-8 seconds (10 seconds for a 20+ megapixel photo). Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.\n\nPOST accepts a JSON body (`url` or base64 `image`), a multipart/form-data upload (field `image`) or raw image bytes.","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead."},"image":{"type":"string","description":"The image itself as base64 or a data URL (`data:image/png;base64,...`), up to 10 MB decoded. POST only. Aliases: `imageBase64`, `base64`."},"format":{"type":"string","default":"png","enum":["png","webp","jpeg"],"description":"Result format. `png` and `webp` keep transparency; `jpeg` needs `bg`."},"bg":{"type":"string","description":"Color for the removed background, e.g. `ffffff`, `#f5f5f5`, `rgb(0,0,0)` or `white`. Without it the background is transparent. Alias: `background`."},"crop":{"type":"boolean","default":false,"description":"Crop the result to the subject (trims the transparent margin)."},"cropMargin":{"type":"integer","default":0,"minimum":0,"maximum":1000,"description":"With crop=true: pixels of margin kept around the subject."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"quality":{"type":"integer","default":90,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 90."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}},"example":{"url":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg/960px-Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg","crop":true,"response":"json"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"The image file (JPEG, PNG, WebP or GIF, up to 10 MB). Alias: `file`."},"format":{"type":"string","default":"png","enum":["png","webp","jpeg"],"description":"Result format. `png` and `webp` keep transparency; `jpeg` needs `bg`."},"bg":{"type":"string","description":"Color for the removed background, e.g. `ffffff`, `#f5f5f5`, `rgb(0,0,0)` or `white`. Without it the background is transparent. Alias: `background`."},"crop":{"type":"boolean","default":false,"description":"Crop the result to the subject (trims the transparent margin)."},"cropMargin":{"type":"integer","default":0,"minimum":0,"maximum":1000,"description":"With crop=true: pixels of margin kept around the subject."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"quality":{"type":"integer","default":90,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 90."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}}},"image/*":{"schema":{"type":"string","format":"binary","description":"Raw image bytes (up to 10 MB); put the options in the query string."}}}},"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/png":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"remove-background","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg/960px-Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg/960px-Canon_EOS_5D_Mark_II_with_50mm_1.4_edit1.jpg","input":{"format":"jpeg","width":960,"height":836,"bytes":127578,"hasAlpha":false,"sha256":"c38bfce39fed7437e535e9cf4a29dd44b3388bdba6b9f137b377beebd30ee6c7"},"output":{"format":"png","contentType":"image/png","width":849,"height":724,"bytes":607008,"transparent":true,"savedBytes":-479430,"savedPercent":-375.8},"options":{"format":"png","bg":null,"crop":true,"cropMargin":0,"maxSize":null,"quality":null},"image":"iVBORw0KGgoAAAANSUhEUgAAA1EAAALUCAYAAADqj7h1AAlC50lEQVR4nOy9...(base64 truncated)","warnings":[],"durationMs":5371}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"format","schema":{"type":"string","default":"png","enum":["png","webp","jpeg"]},"description":"For raw image bodies: Result format. `png` and `webp` keep transparency; `jpeg` needs `bg`.","required":false,"in":"query"},{"name":"bg","schema":{"type":"string"},"description":"For raw image bodies: Color for the removed background, e.g. `ffffff`, `#f5f5f5`, `rgb(0,0,0)` or `white`. Without it the background is transparent. Alias: `background`.","required":false,"example":"ffffff","in":"query"},{"name":"crop","schema":{"type":"boolean","default":false},"description":"For raw image bodies: Crop the result to the subject (trims the transparent margin).","required":false,"in":"query"},{"name":"cropMargin","schema":{"type":"integer","default":0,"minimum":0,"maximum":1000},"description":"For raw image bodies: With crop=true: pixels of margin kept around the subject.","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"For raw image bodies: Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"quality","schema":{"type":"integer","default":90,"minimum":1,"maximum":100},"description":"For raw image bodies: Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 90.","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"For raw image bodies: `image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}]}},"/api/v1/image/resize":{"get":{"operationId":"resizeImageGet","summary":"Resize an image (GET)","description":"Resizes to `width` and/or `height`. `fit`: `contain` (default; fits inside the box, keeps the aspect ratio, may enlarge), `scale-down` (like contain, never enlarges), `cover` (fills the box and crops; `gravity=auto` keeps the most interesting part), `crop` (like cover, never enlarges), `pad` (fits inside and fills the rest with `background`, transparent by default; white for JPEG), `squeeze` (stretches to the exact size). The format stays the same unless `format` is set (GIF becomes PNG). Typical time under 1 second. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.","tags":["Image"],"parameters":[{"name":"url","schema":{"type":"string"},"description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead.","required":false,"example":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","in":"query"},{"name":"width","schema":{"type":"integer","minimum":1,"maximum":8000},"description":"Target width in pixels. At least one of width/height.","required":false,"example":400,"in":"query"},{"name":"height","schema":{"type":"integer","minimum":1,"maximum":8000},"description":"Target height in pixels.","required":false,"example":400,"in":"query"},{"name":"fit","schema":{"type":"string","default":"contain","enum":["contain","scale-down","cover","crop","pad","squeeze"]},"description":"How the image fits the box (see the description).","required":false,"in":"query"},{"name":"gravity","schema":{"type":"string","default":"center","enum":["center","auto","top","bottom","left","right"]},"description":"With fit=cover/crop: which part to keep. `auto` picks the most interesting area.","required":false,"in":"query"},{"name":"format","schema":{"type":"string","default":"auto","enum":["auto","jpeg","png","webp","avif"]},"description":"`auto` keeps the input format (GIF becomes PNG).","required":false,"in":"query"},{"name":"quality","schema":{"type":"integer","default":85,"minimum":1,"maximum":100},"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"With fit=pad, or for transparent areas in a JPEG: fill color (`ffffff`, `white`, `rgb(...)`).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}],"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"resize","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","input":{"format":"jpeg","width":960,"height":959,"bytes":150302,"hasAlpha":false,"sha256":"0dca7c808c38df01e4ad136e461f465000f88601281c7d3069242b2c9c295008"},"output":{"format":"jpeg","contentType":"image/jpeg","width":400,"height":400,"bytes":23651,"transparent":false,"savedBytes":126651,"savedPercent":84.3},"options":{"width":400,"height":400,"fit":"cover","gravity":"auto","format":"auto","quality":null,"background":null},"image":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUFBQUFBQUGBgUICAcICAsKCQkK...(base64 truncated)","warnings":[],"durationMs":181}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"resizeImage","summary":"Resize an image","description":"Resizes to `width` and/or `height`. `fit`: `contain` (default; fits inside the box, keeps the aspect ratio, may enlarge), `scale-down` (like contain, never enlarges), `cover` (fills the box and crops; `gravity=auto` keeps the most interesting part), `crop` (like cover, never enlarges), `pad` (fits inside and fills the rest with `background`, transparent by default; white for JPEG), `squeeze` (stretches to the exact size). The format stays the same unless `format` is set (GIF becomes PNG). Typical time under 1 second. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.\n\nPOST accepts a JSON body (`url` or base64 `image`), a multipart/form-data upload (field `image`) or raw image bytes.","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead."},"image":{"type":"string","description":"The image itself as base64 or a data URL (`data:image/png;base64,...`), up to 10 MB decoded. POST only. Aliases: `imageBase64`, `base64`."},"width":{"type":"integer","minimum":1,"maximum":8000,"description":"Target width in pixels. At least one of width/height."},"height":{"type":"integer","minimum":1,"maximum":8000,"description":"Target height in pixels."},"fit":{"type":"string","default":"contain","enum":["contain","scale-down","cover","crop","pad","squeeze"],"description":"How the image fits the box (see the description)."},"gravity":{"type":"string","default":"center","enum":["center","auto","top","bottom","left","right"],"description":"With fit=cover/crop: which part to keep. `auto` picks the most interesting area."},"format":{"type":"string","default":"auto","enum":["auto","jpeg","png","webp","avif"],"description":"`auto` keeps the input format (GIF becomes PNG)."},"quality":{"type":"integer","default":85,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85."},"background":{"type":"string","description":"With fit=pad, or for transparent areas in a JPEG: fill color (`ffffff`, `white`, `rgb(...)`)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}},"example":{"url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","width":400,"height":400,"fit":"cover","gravity":"auto","response":"json"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"The image file (JPEG, PNG, WebP or GIF, up to 10 MB). Alias: `file`."},"width":{"type":"integer","minimum":1,"maximum":8000,"description":"Target width in pixels. At least one of width/height."},"height":{"type":"integer","minimum":1,"maximum":8000,"description":"Target height in pixels."},"fit":{"type":"string","default":"contain","enum":["contain","scale-down","cover","crop","pad","squeeze"],"description":"How the image fits the box (see the description)."},"gravity":{"type":"string","default":"center","enum":["center","auto","top","bottom","left","right"],"description":"With fit=cover/crop: which part to keep. `auto` picks the most interesting area."},"format":{"type":"string","default":"auto","enum":["auto","jpeg","png","webp","avif"],"description":"`auto` keeps the input format (GIF becomes PNG)."},"quality":{"type":"integer","default":85,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85."},"background":{"type":"string","description":"With fit=pad, or for transparent areas in a JPEG: fill color (`ffffff`, `white`, `rgb(...)`)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}}},"image/*":{"schema":{"type":"string","format":"binary","description":"Raw image bytes (up to 10 MB); put the options in the query string."}}}},"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"resize","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","input":{"format":"jpeg","width":960,"height":959,"bytes":150302,"hasAlpha":false,"sha256":"0dca7c808c38df01e4ad136e461f465000f88601281c7d3069242b2c9c295008"},"output":{"format":"jpeg","contentType":"image/jpeg","width":400,"height":400,"bytes":23651,"transparent":false,"savedBytes":126651,"savedPercent":84.3},"options":{"width":400,"height":400,"fit":"cover","gravity":"auto","format":"auto","quality":null,"background":null},"image":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUFBQUFBQUGBgUICAcICAsKCQkK...(base64 truncated)","warnings":[],"durationMs":181}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"width","schema":{"type":"integer","minimum":1,"maximum":8000},"description":"For raw image bodies: Target width in pixels. At least one of width/height.","required":false,"example":400,"in":"query"},{"name":"height","schema":{"type":"integer","minimum":1,"maximum":8000},"description":"For raw image bodies: Target height in pixels.","required":false,"example":400,"in":"query"},{"name":"fit","schema":{"type":"string","default":"contain","enum":["contain","scale-down","cover","crop","pad","squeeze"]},"description":"For raw image bodies: How the image fits the box (see the description).","required":false,"in":"query"},{"name":"gravity","schema":{"type":"string","default":"center","enum":["center","auto","top","bottom","left","right"]},"description":"For raw image bodies: With fit=cover/crop: which part to keep. `auto` picks the most interesting area.","required":false,"in":"query"},{"name":"format","schema":{"type":"string","default":"auto","enum":["auto","jpeg","png","webp","avif"]},"description":"For raw image bodies: `auto` keeps the input format (GIF becomes PNG).","required":false,"in":"query"},{"name":"quality","schema":{"type":"integer","default":85,"minimum":1,"maximum":100},"description":"For raw image bodies: Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"For raw image bodies: With fit=pad, or for transparent areas in a JPEG: fill color (`ffffff`, `white`, `rgb(...)`).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"For raw image bodies: `image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}]}},"/api/v1/image/convert":{"get":{"operationId":"convertImageGet","summary":"Convert an image to JPEG, PNG, WebP or AVIF (GET)","description":"Converts to `format`. Transparent areas become white in JPEG (or `background`). AVIF is limited to 1,200 px per side: larger results are written as WebP with the warning `avif_too_large_used_webp` (or send `maxSize` 1200). PNG results are limited to 16 megapixels (send `maxSize`). Metadata (EXIF, GPS) is removed. Typical time under 1 second; 20+ megapixel photos 3-9 seconds. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.","tags":["Image"],"parameters":[{"name":"url","schema":{"type":"string"},"description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead.","required":false,"example":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","in":"query"},{"name":"format","schema":{"type":"string","enum":["jpeg","png","webp","avif"]},"description":"Target format (required).","required":true,"example":"webp","in":"query"},{"name":"quality","schema":{"type":"integer","default":85,"minimum":1,"maximum":100},"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85.","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"Fill color for transparent areas when converting to JPEG (default white).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}],"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/webp":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"convert","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/960px-Tux.svg.png","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/960px-Tux.svg.png","input":{"format":"png","width":960,"height":1138,"bytes":223939,"hasAlpha":true,"sha256":"a4bd591c958d147cfab5babbaae9d1eb91dc8ce0f38b5402f42cb0ad67c0f598"},"output":{"format":"webp","contentType":"image/webp","width":960,"height":1138,"bytes":31462,"transparent":true,"savedBytes":192477,"savedPercent":86},"options":{"format":"webp","quality":null,"maxSize":null,"background":null},"image":"UklGRt56AABXRUJQVlA4WAoAAAAQAAAAvwMAcQQAQUxQSL4hAAABsEZb2zKn...(base64 truncated)","warnings":[],"durationMs":223}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"convertImage","summary":"Convert an image to JPEG, PNG, WebP or AVIF","description":"Converts to `format`. Transparent areas become white in JPEG (or `background`). AVIF is limited to 1,200 px per side: larger results are written as WebP with the warning `avif_too_large_used_webp` (or send `maxSize` 1200). PNG results are limited to 16 megapixels (send `maxSize`). Metadata (EXIF, GPS) is removed. Typical time under 1 second; 20+ megapixel photos 3-9 seconds. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.\n\nPOST accepts a JSON body (`url` or base64 `image`), a multipart/form-data upload (field `image`) or raw image bytes.","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead."},"image":{"type":"string","description":"The image itself as base64 or a data URL (`data:image/png;base64,...`), up to 10 MB decoded. POST only. Aliases: `imageBase64`, `base64`."},"format":{"type":"string","enum":["jpeg","png","webp","avif"],"description":"Target format (required)."},"quality":{"type":"integer","default":85,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"background":{"type":"string","description":"Fill color for transparent areas when converting to JPEG (default white)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}},"example":{"url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/960px-Tux.svg.png","format":"webp","response":"json"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"The image file (JPEG, PNG, WebP or GIF, up to 10 MB). Alias: `file`."},"format":{"type":"string","enum":["jpeg","png","webp","avif"],"description":"Target format (required)."},"quality":{"type":"integer","default":85,"minimum":1,"maximum":100,"description":"Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"background":{"type":"string","description":"Fill color for transparent areas when converting to JPEG (default white)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}}},"image/*":{"schema":{"type":"string","format":"binary","description":"Raw image bytes (up to 10 MB); put the options in the query string."}}}},"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/webp":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"convert","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/960px-Tux.svg.png","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/960px-Tux.svg.png","input":{"format":"png","width":960,"height":1138,"bytes":223939,"hasAlpha":true,"sha256":"a4bd591c958d147cfab5babbaae9d1eb91dc8ce0f38b5402f42cb0ad67c0f598"},"output":{"format":"webp","contentType":"image/webp","width":960,"height":1138,"bytes":31462,"transparent":true,"savedBytes":192477,"savedPercent":86},"options":{"format":"webp","quality":null,"maxSize":null,"background":null},"image":"UklGRt56AABXRUJQVlA4WAoAAAAQAAAAvwMAcQQAQUxQSL4hAAABsEZb2zKn...(base64 truncated)","warnings":[],"durationMs":223}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"format","schema":{"type":"string","enum":["jpeg","png","webp","avif"]},"description":"For raw image bodies: Target format (required).","required":false,"example":"webp","in":"query"},{"name":"quality","schema":{"type":"integer","default":85,"minimum":1,"maximum":100},"description":"For raw image bodies: Quality for JPEG, WebP and AVIF (ignored for PNG, which is lossless). Default 85.","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"For raw image bodies: Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"For raw image bodies: Fill color for transparent areas when converting to JPEG (default white).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"For raw image bodies: `image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}]}},"/api/v1/image/compress":{"get":{"operationId":"compressImageGet","summary":"Compress an image (GET)","description":"Re-encodes with a lower `quality` (default 75) in the same format (`format=auto`) or in WebP, AVIF or JPEG, optionally scaled down with `maxSize`. Metadata (EXIF, GPS) is removed. If the result would not be smaller in the same format, the original bytes come back (`unchanged: true`, warning `already_optimized`). PNG input stays lossless PNG with `format=auto`: use `format=webp` for large savings. Typical time under 1 second. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.","tags":["Image"],"parameters":[{"name":"url","schema":{"type":"string"},"description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead.","required":false,"example":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/960px-Cat03.jpg","in":"query"},{"name":"quality","schema":{"type":"integer","default":75,"minimum":1,"maximum":100},"description":"Quality 1-100 (lower = smaller).","required":false,"in":"query"},{"name":"format","schema":{"type":"string","default":"auto","enum":["auto","jpeg","webp","avif"]},"description":"`auto` keeps the input format (GIF becomes PNG).","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"Fill color for transparent areas when the result is JPEG (default white).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}],"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"compress","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Smiling_senior_woman_with_curly_hair_portrait.jpg/960px-Smiling_senior_woman_with_curly_hair_portrait.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Smiling_senior_woman_with_curly_hair_portrait.jpg/960px-Smiling_senior_woman_with_curly_hair_portrait.jpg","input":{"format":"jpeg","width":960,"height":1438,"bytes":235096,"hasAlpha":false,"sha256":"276dee0a095dccf2cf5843f5fdcdd90dbb2b39c55fb9ab71162292cd351f0d2c"},"output":{"format":"jpeg","contentType":"image/jpeg","width":960,"height":1438,"bytes":131418,"transparent":false,"savedBytes":103678,"savedPercent":44.1,"unchanged":false},"options":{"format":"auto","quality":70,"maxSize":null,"background":null},"image":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0N...(base64 truncated)","warnings":[],"durationMs":71}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"compressImage","summary":"Compress an image","description":"Re-encodes with a lower `quality` (default 75) in the same format (`format=auto`) or in WebP, AVIF or JPEG, optionally scaled down with `maxSize`. Metadata (EXIF, GPS) is removed. If the result would not be smaller in the same format, the original bytes come back (`unchanged: true`, warning `already_optimized`). PNG input stays lossless PNG with `format=auto`: use `format=webp` for large savings. Typical time under 1 second. Send an image URL (GET or POST), a base64 image (POST JSON), a file upload (POST multipart/form-data, field `image`) or the raw image bytes (POST with `Content-Type: image/*`, options in the query string). The answer is the image itself by default (`response=json` for metadata + base64). One call = one image. The same image with the same options is answered from a 24-hour cache.\n\nPOST accepts a JSON body (`url` or base64 `image`), a multipart/form-data upload (field `image`) or raw image bytes.","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public image URL (JPEG, PNG, WebP or GIF, up to 10 MB, 50 megapixels and 12,000 px per side). Private, local and cloud-metadata addresses are refused on every redirect. Alias: `imageUrl`. For POST you can send `image` (base64) or upload the file instead."},"image":{"type":"string","description":"The image itself as base64 or a data URL (`data:image/png;base64,...`), up to 10 MB decoded. POST only. Aliases: `imageBase64`, `base64`."},"quality":{"type":"integer","default":75,"minimum":1,"maximum":100,"description":"Quality 1-100 (lower = smaller)."},"format":{"type":"string","default":"auto","enum":["auto","jpeg","webp","avif"],"description":"`auto` keeps the input format (GIF becomes PNG)."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"background":{"type":"string","description":"Fill color for transparent areas when the result is JPEG (default white)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}},"example":{"url":"https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Smiling_senior_woman_with_curly_hair_portrait.jpg/960px-Smiling_senior_woman_with_curly_hair_portrait.jpg","quality":70,"response":"json"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"The image file (JPEG, PNG, WebP or GIF, up to 10 MB). Alias: `file`."},"quality":{"type":"integer","default":75,"minimum":1,"maximum":100,"description":"Quality 1-100 (lower = smaller)."},"format":{"type":"string","default":"auto","enum":["auto","jpeg","webp","avif"],"description":"`auto` keeps the input format (GIF becomes PNG)."},"maxSize":{"type":"integer","minimum":16,"maximum":8000,"description":"Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio."},"background":{"type":"string","description":"Fill color for transparent areas when the result is JPEG (default white)."},"response":{"type":"string","default":"image","enum":["image","json"],"description":"`image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB)."}}}},"image/*":{"schema":{"type":"string","format":"binary","description":"Raw image bytes (up to 10 MB); put the options in the query string."}}}},"responses":{"200":{"description":"The resulting image (default, `response=image`; metadata in the `x-*` headers), or JSON with the image as base64 when `response=json`.","content":{"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"operation":{"type":"string","enum":["remove-background","resize","convert","compress"]},"source":{"type":"string","enum":["url","upload"]},"url":{"type":"string","nullable":true,"description":"The image URL you sent (null for uploads)."},"finalUrl":{"type":"string","nullable":true,"description":"The URL after redirects (null for uploads)."},"input":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","gif"]},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"hasAlpha":{"type":"boolean","nullable":true,"description":"The input already has a transparency channel (from the file header; null when unknown)."},"sha256":{"type":"string","description":"SHA-256 of the input bytes (results are cached by it and the options for 24 hours)."}}},"output":{"type":"object","properties":{"format":{"type":"string","enum":["jpeg","png","webp","avif"]},"contentType":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"bytes":{"type":"integer"},"transparent":{"type":"boolean","description":"The result has a transparent background or areas."},"savedBytes":{"type":"integer","description":"Input bytes minus output bytes (negative when the result is larger, e.g. a transparent PNG made from a JPEG)."},"savedPercent":{"type":"number"},"unchanged":{"type":"boolean","description":"compress only: true when re-encoding did not make the file smaller, so the original bytes are returned."}}},"options":{"type":"object","additionalProperties":true,"description":"The options applied, after defaults (only the ones that apply to the endpoint)."},"image":{"type":"string","contentEncoding":"base64","description":"The resulting image, base64-encoded (only with response=json)."},"warnings":{"type":"array","items":{"type":"string","enum":["low_resolution","input_has_transparency","gif_first_frame_only","avif_too_large_used_webp","already_optimized"]},"description":"`low_resolution`: under about 300x300 pixels, fine edges are lost. `input_has_transparency`: the input was already transparent. `gif_first_frame_only`: GIF animations are reduced to their first frame. `avif_too_large_used_webp`: AVIF is limited to 1,200 px per side, so WebP was written. `already_optimized`: compress returned the original."},"durationMs":{"type":"integer"},"fileName":{"type":"string","nullable":true,"description":"File name of a multipart upload."}}},"example":{"success":true,"operation":"compress","source":"url","url":"https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Smiling_senior_woman_with_curly_hair_portrait.jpg/960px-Smiling_senior_woman_with_curly_hair_portrait.jpg","finalUrl":"https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Smiling_senior_woman_with_curly_hair_portrait.jpg/960px-Smiling_senior_woman_with_curly_hair_portrait.jpg","input":{"format":"jpeg","width":960,"height":1438,"bytes":235096,"hasAlpha":false,"sha256":"276dee0a095dccf2cf5843f5fdcdd90dbb2b39c55fb9ab71162292cd351f0d2c"},"output":{"format":"jpeg","contentType":"image/jpeg","width":960,"height":1438,"bytes":131418,"transparent":false,"savedBytes":103678,"savedPercent":44.1,"unchanged":false},"options":{"format":"auto","quality":70,"maxSize":null,"background":null},"image":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0N...(base64 truncated)","warnings":[],"durationMs":71}}},"headers":{"x-input-width":{"schema":{"type":"string"},"description":"Input width (px)."},"x-input-height":{"schema":{"type":"string"},"description":"Input height (px)."},"x-input-bytes":{"schema":{"type":"string"},"description":"Input size in bytes."},"x-output-width":{"schema":{"type":"string"},"description":"Result width (px)."},"x-output-height":{"schema":{"type":"string"},"description":"Result height (px)."},"x-output-bytes":{"schema":{"type":"string"},"description":"Result size in bytes."},"x-saved-percent":{"schema":{"type":"string"},"description":"Size saved versus the input, in percent (negative when larger)."},"x-warnings":{"schema":{"type":"string"},"description":"Comma-separated warnings (see the JSON `warnings`)."},"x-cache":{"schema":{"type":"string"},"description":"`HIT` when the result came from the 24-hour cache."},"x-duration-ms":{"schema":{"type":"string"},"description":"Processing time on our side."}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"The image is larger than 10 MB, 50 megapixels or 12,000 px per side, a PNG result would exceed 16 megapixels, or the result is too large for `response=json` (`too_large`). The message says which and what to send instead (`maxSize`, WebP).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"too_large","message":"the image must be at most 12000 px per side (this one is 12001x1000)"}}}}},"422":{"description":"Not a supported image (`unsupported_content`: a web page, PDF, SVG, BMP, TIFF, HEIC/AVIF or a damaged file), the image server refused (`target_blocked`), could not be reached (`target_unreachable`) or the image does not exist (`target_error`, HTTP 404/410).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"unsupported_content","message":"the URL returned a web page, not an image: link to the image file itself"}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"quality","schema":{"type":"integer","default":75,"minimum":1,"maximum":100},"description":"For raw image bodies: Quality 1-100 (lower = smaller).","required":false,"in":"query"},{"name":"format","schema":{"type":"string","default":"auto","enum":["auto","jpeg","webp","avif"]},"description":"For raw image bodies: `auto` keeps the input format (GIF becomes PNG).","required":false,"in":"query"},{"name":"maxSize","schema":{"type":"integer","minimum":16,"maximum":8000},"description":"For raw image bodies: Longest side of the result in pixels; larger images are scaled down (never up), keeping the aspect ratio.","required":false,"in":"query"},{"name":"background","schema":{"type":"string"},"description":"For raw image bodies: Fill color for transparent areas when the result is JPEG (default white).","required":false,"in":"query"},{"name":"response","schema":{"type":"string","default":"image","enum":["image","json"]},"description":"For raw image bodies: `image` (default): the response body is the image itself (`Content-Type: image/...`, metadata in `x-*` headers). `json`: JSON with the metadata and the image as base64 in `image` (results up to 15 MB).","required":false,"in":"query"}]}}},"components":{"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["not_configured","unauthorized","not_found","method_not_allowed","invalid_request","rate_limited","url_not_allowed","target_blocked","target_unreachable","target_error","unsupported_content","too_large","timeout","upstream_error","board_not_found","app_not_found"]},"message":{"type":"string"},"retryable":{"type":"boolean","description":"true for rate_limited, timeout, upstream_error and browser_busy; false for other errors."},"retryAfterSeconds":{"type":"integer","description":"Seconds to wait before retrying, when a numeric Retry-After header is present."},"details":{"type":"object","additionalProperties":true}}}}}}}}