{"openapi":"3.1.0","info":{"title":"ImageCompressor API","version":"1.0.0","description":"Compress, convert, resize, crop, edit and inspect images; remove backgrounds, upscale and read text; run pipelines and background jobs; optimize a website's images. Authenticate with an API key: Authorization: Bearer ic_live_…. Every response carries X-Request-Id; errors are JSON with a code and a message."},"servers":[{"url":"https://imagecompressor.si"}],"security":[{"apiKey":[]}],"tags":[{"name":"Images","description":"One image in, one image or one answer out."},{"name":"AI","description":"Model-based tools. Need a key with the ai scope."},{"name":"Pipelines and jobs","description":"Several steps, several images, in the background. Running and saving them needs a Pro plan; a free account gets upgrade_required."},{"name":"Website","description":"Optimize every image of a website."},{"name":"Account","description":"Usage and discovery."}],"paths":{"/api/v1/compress":{"post":{"tags":["Images"],"operationId":"compress","summary":"Compress, convert, resize, crop, rotate, edit or watermark an image","description":"Options combine freely. Order: orient, crop, flip, rotate, resize, colour adjustments, pad, circle mask, border, watermark, encode.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"format","in":"query","description":"Output format. auto keeps the input format. ico holds the image at 16 to 256 pixels, on a square.","schema":{"type":"string","enum":["auto","jpeg","png","webp","avif","gif","tiff","bmp","ico","jxl","pdf","tga","psd"],"default":"auto"}},{"name":"mode","in":"query","description":"smart finds the smallest file that still looks like the original; lossless keeps every pixel.","schema":{"type":"string","enum":["quality","smart","lossless","target"],"default":"quality"}},{"name":"quality","in":"query","description":"Used by mode quality.","schema":{"type":"integer","minimum":1,"maximum":100,"default":75}},{"name":"target_bytes","in":"query","description":"Compress to at most this many bytes.","schema":{"type":"integer","minimum":1,"maximum":1000000000}},{"name":"min_bytes","in":"query","description":"Make a JPEG or PNG result at least this many bytes, by padding the file without changing the picture. With target_bytes it gives a range. Other formats get the warning min_size_unavailable.","schema":{"type":"integer","minimum":1,"maximum":1000000000}},{"name":"crop","in":"query","description":"x,y,width,height in pixels, before flip and rotate.","schema":{"type":"string","example":"0,0,800,600"}},{"name":"crop_ratio","in":"query","description":"Crop to this shape.","schema":{"type":"string","example":"16:9"}},{"name":"crop_gravity","in":"query","description":"Where a crop_ratio crop is taken from.","schema":{"type":"string","enum":["centre","attention"],"default":"centre"}},{"name":"crop_shape","in":"query","description":"circle clears everything outside the ellipse.","schema":{"type":"string","enum":["rect","circle"],"default":"rect"}},{"name":"flip","in":"query","description":"Mirror horizontally, vertically or both.","schema":{"type":"string","enum":["none","h","v","hv"],"default":"none"}},{"name":"rotate","in":"query","description":"Degrees clockwise. Not a quarter turn: the image grows to hold the turned picture and its new corners are transparent (the background colour in JPEG and BMP).","schema":{"type":"integer","minimum":-359,"maximum":359,"default":0}},{"name":"width","in":"query","description":"Target width in pixels.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"height","in":"query","description":"Target height in pixels.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"percent","in":"query","description":"Scale, when neither width nor height is given.","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"fit","in":"query","description":"inside keeps the ratio, exact stretches, cover fills and crops, contain pads.","schema":{"type":"string","enum":["inside","exact","cover","contain"],"default":"inside"}},{"name":"enlarge","in":"query","description":"Allow making the image larger than it is.","schema":{"type":"boolean","default":false}},{"name":"print_width","in":"query","description":"Print width in millimetres. Resizes to this size at dpi; not together with width, height or percent.","schema":{"type":"number","minimum":1,"maximum":5000}},{"name":"print_height","in":"query","description":"Print height in millimetres.","schema":{"type":"number","minimum":1,"maximum":5000}},{"name":"dpi","in":"query","description":"Resolution recorded in the file. Without enlarge, an image too small for the print size keeps its pixels and gets the lower resolution that prints it at that size.","schema":{"type":"integer","minimum":72,"maximum":1200,"default":300}},{"name":"max_width","in":"query","description":"Shorthand: fit inside this width, never enlarge.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"max_height","in":"query","description":"Shorthand: fit inside this height, never enlarge.","schema":{"type":"integer","minimum":1,"maximum":100000}},{"name":"brightness","in":"query","description":"Brightness.","schema":{"type":"integer","minimum":-100,"maximum":100,"default":0}},{"name":"contrast","in":"query","description":"Contrast.","schema":{"type":"integer","minimum":-100,"maximum":100,"default":0}},{"name":"saturation","in":"query","description":"Saturation.","schema":{"type":"integer","minimum":-100,"maximum":100,"default":0}},{"name":"exposure","in":"query","description":"Exposure; two stops at either end.","schema":{"type":"integer","minimum":-100,"maximum":100,"default":0}},{"name":"grayscale","in":"query","description":"Black and white.","schema":{"type":"boolean","default":false}},{"name":"blur","in":"query","description":"Blur, relative to the image size.","schema":{"type":"integer","minimum":0,"maximum":100,"default":0}},{"name":"enhance","in":"query","description":"Stretch levels and lift local contrast.","schema":{"type":"boolean","default":false}},{"name":"sharpen","in":"query","description":"Sharpen.","schema":{"type":"integer","minimum":0,"maximum":100,"default":0}},{"name":"denoise","in":"query","description":"Noise reduction (median filter).","schema":{"type":"integer","minimum":0,"maximum":100,"default":0}},{"name":"border","in":"query","description":"Border width in pixels, on every side.","schema":{"type":"integer","minimum":0,"maximum":2000,"default":0}},{"name":"border_color","in":"query","description":"A #rrggbb colour, or transparent.","schema":{"type":"string","default":"#ffffff"}},{"name":"watermark_text","in":"query","description":"Text to draw on the image.","schema":{"type":"string","maxLength":200}},{"name":"watermark_color","in":"query","description":"Colour of the watermark text.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","default":"#ffffff"}},{"name":"watermark_opacity","in":"query","description":"Watermark opacity.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"watermark_size","in":"query","description":"Watermark width as a percentage of the image's width.","schema":{"type":"integer","minimum":5,"maximum":100,"default":30}},{"name":"watermark_position","in":"query","description":"A corner, an edge, the centre, or tile.","schema":{"type":"string","enum":["tl","tc","tr","cl","c","cr","bl","bc","br","tile"],"default":"br"}},{"name":"metadata","in":"query","description":"What to keep of the source's metadata.","schema":{"type":"string","enum":["strip","keep","no_gps","color"],"default":"strip"}},{"name":"background","in":"query","description":"Painted behind transparent pixels when the output is JPEG.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","default":"#ffffff"}},{"name":"fingerprint","in":"query","description":"Add X-IC-Fingerprint, a perceptual hash of the source.","schema":{"type":"boolean","default":false}},{"name":"score","in":"query","description":"Add X-IC-Similarity, how close the result is to the source.","schema":{"type":"boolean","default":false}},{"name":"deliver_to","in":"query","description":"A pre-signed upload URL of your own storage: the result is PUT there instead of returned, and nothing is stored here.","schema":{"type":"string","format":"uri"}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/inspect":{"post":{"tags":["Images"],"operationId":"inspect","summary":"Facts about an image: format, size, metadata, GPS position, fingerprints","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"What the file is and what it carries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Inspection"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/remove-background":{"post":{"tags":["AI"],"operationId":"removeBackground","summary":"Cut the subject out of a photo","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"background","in":"query","description":"transparent, a #rrggbb colour, gradient, blur, or image (Pro; multipart part background_image).","schema":{"type":"string","default":"transparent"}},{"name":"gradient_from","in":"query","description":"Top colour for background=gradient.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},{"name":"gradient_to","in":"query","description":"Bottom colour for background=gradient.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"}},{"name":"blur","in":"query","description":"Strength for background=blur.","schema":{"type":"integer","minimum":1,"maximum":100,"default":40}},{"name":"feather","in":"query","description":"Softness of the cut-out's edge.","schema":{"type":"integer","minimum":0,"maximum":3,"default":1}},{"name":"refine","in":"query","description":"Pull the mask onto the photo's own edges (hair, fur).","schema":{"type":"boolean","default":false}},{"name":"frame","in":"query","description":"Centre the subject on a canvas of this size.","schema":{"type":"string","example":"2000x2000"}},{"name":"subject_fill","in":"query","description":"Share of the frame the subject takes up.","schema":{"type":"integer","minimum":10,"maximum":100,"default":85}},{"name":"format","in":"query","description":"jpeg needs a background that is not transparent.","schema":{"type":"string","enum":["png","webp","jpeg"],"default":"png"}},{"name":"mask","in":"query","description":"Return the mask itself, a greyscale PNG of at most 1024 pixels (white is the subject), instead of the cut-out. A corrected mask is sent back as a multipart part named mask, next to image; it is then used in place of the model's.","schema":{"type":"boolean","default":false}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/upscale":{"post":{"tags":["AI"],"operationId":"upscale","summary":"Double an image's width and height with a super-resolution model","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"scale","in":"query","description":"Only 2 is supported.","schema":{"type":"string","enum":["2"],"default":"2"}},{"name":"format","in":"query","description":"Output format.","schema":{"type":"string","enum":["auto","jpeg","png","webp","avif","gif","tiff"],"default":"auto"}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/favicon":{"post":{"tags":["Images"],"operationId":"favicon","summary":"Make a favicon pack: every icon size a site needs, the web manifest and the HTML","description":"Returns a ZIP with favicon.ico (16, 32 and 48 pixels), PNG icons of 16, 32, 48, 180 (Apple), 192 and 512 pixels, a maskable 512-pixel icon, site.webmanifest and favicon.html with the lines for the page's head. A picture that is not square is centred, never cropped. X-IC-Warnings is source_small when the picture is under 512 pixels.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"name","in":"query","description":"The site's name, for the web manifest.","schema":{"type":"string","maxLength":60,"default":"My site"}},{"name":"short_name","in":"query","description":"A shorter name for a phone's home screen. Default: the name.","schema":{"type":"string","maxLength":30}},{"name":"theme_color","in":"query","description":"The browser's toolbar colour on phones.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","default":"#ffffff"}},{"name":"background","in":"query","description":"Behind the picture on the Apple and maskable icons, which may not be see-through.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","default":"#ffffff"}},{"name":"padding","in":"query","description":"Percent of the icon's side kept clear around the picture.","schema":{"type":"integer","minimum":0,"maximum":40,"default":0}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The ZIP (output=binary), or where it was stored for an hour (output=json).","content":{"application/zip":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"},"bytes":{"type":"integer"},"files":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"integer"}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/gif":{"post":{"tags":["Images"],"operationId":"editGif","summary":"Crop, trim, speed up, slow down, reverse, thin or resize an animated GIF","description":"Order: trim, keep every Nth frame, reverse, speed, crop, resize, encode. Frames are composed first, so every frame handled is a whole picture. Also reads animated WebP. X-IC-Frames and X-IC-Animation-Ms describe the result; X-IC-Source-Frames and X-IC-Source-Animation-Ms the upload.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"crop","in":"query","description":"x,y,width,height in the animation's pixels, applied to every frame.","schema":{"type":"string","example":"20,10,200,150"}},{"name":"width","in":"query","description":"Resize to this width, keeping the shape. Never enlarges.","schema":{"type":"integer","minimum":1,"maximum":10000}},{"name":"trim_start","in":"query","description":"Seconds from the start to cut away.","schema":{"type":"number","minimum":0}},{"name":"trim_end","in":"query","description":"Seconds from the start where the animation ends.","schema":{"type":"number","minimum":0}},{"name":"speed","in":"query","description":"Percent: 200 plays twice as fast. No frame is shown for less than 20 ms.","schema":{"type":"integer","minimum":25,"maximum":400,"default":100}},{"name":"reverse","in":"query","description":"Play backwards.","schema":{"type":"boolean","default":false}},{"name":"every","in":"query","description":"Keep every Nth frame; the time of the dropped frames goes to the one kept.","schema":{"type":"integer","minimum":1,"maximum":4,"default":1}},{"name":"colours","in":"query","description":"Palette size, for GIF output.","schema":{"type":"integer","minimum":2,"maximum":256,"default":256}},{"name":"loop","in":"query","description":"Times the animation repeats; 0 for ever. Default: as the upload.","schema":{"type":"integer","minimum":0,"maximum":65535}},{"name":"format","in":"query","description":"webp writes an animated WebP, usually far smaller.","schema":{"type":"string","enum":["gif","webp"],"default":"gif"}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/id-photo":{"get":{"tags":["Images"],"operationId":"listIdPhotoPresets","summary":"The ID photo sizes the preset parameter accepts","description":"Country presets carry the official page they were read from and the day it was read.","security":[],"responses":{"200":{"description":"Every preset.","content":{"application/json":{"schema":{"type":"object","properties":{"presets":{"type":"array","items":{"$ref":"#/components/schemas/IdPhotoPreset"}}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Images"],"operationId":"idPhoto","summary":"Make an ID or passport photo: exact size, resolution, file-size range, print sheet","description":"Crops to the photo's shape, resizes to its exact pixel size, records the resolution, and brings the file inside the size range by quality alone: the pixel size never changes. X-IC-Outcome is unreachable when the file cannot be made that small. We size the file; we do not check face position, expression or lighting.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"preset","in":"query","description":"A size from GET /api/v1/id-photo. The parameters below override it.","schema":{"type":"string","example":"35x45"}},{"name":"width_mm","in":"query","description":"Photo width in millimetres, with height_mm.","schema":{"type":"number","minimum":5,"maximum":300}},{"name":"height_mm","in":"query","description":"Photo height in millimetres.","schema":{"type":"number","minimum":5,"maximum":300}},{"name":"width","in":"query","description":"Photo width in pixels, with height. Not together with the millimetres.","schema":{"type":"integer","minimum":16,"maximum":6000}},{"name":"height","in":"query","description":"Photo height in pixels.","schema":{"type":"integer","minimum":16,"maximum":6000}},{"name":"dpi","in":"query","description":"Resolution: turns millimetres into pixels and is recorded in the file.","schema":{"type":"integer","minimum":72,"maximum":1200,"default":300}},{"name":"crop","in":"query","description":"x,y,width,height in the picture as displayed. Default: the largest centred crop of the photo's shape.","schema":{"type":"string","example":"120,40,700,900"}},{"name":"format","in":"query","description":"Output format.","schema":{"type":"string","enum":["jpeg","png"],"default":"jpeg"}},{"name":"min_bytes","in":"query","description":"The file is padded up to this size when it is smaller.","schema":{"type":"integer","minimum":1000,"maximum":50000000}},{"name":"max_bytes","in":"query","description":"The file is compressed to at most this size.","schema":{"type":"integer","minimum":1000,"maximum":50000000}},{"name":"background","in":"query","description":"Painted behind transparent pixels, and behind the person with remove_background.","schema":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","default":"#ffffff"}},{"name":"remove_background","in":"query","description":"Cut the person out and put them on the background colour. Counts as an AI request.","schema":{"type":"boolean","default":false}},{"name":"sheet","in":"query","description":"Return a 4 x 6 inch (10 x 15 cm) sheet of copies with 2 mm gaps instead of the single photo.","schema":{"type":"boolean","default":false}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/faces":{"post":{"tags":["AI"],"operationId":"detectFaces","summary":"Find the faces in a picture","description":"Boxes are in the picture as displayed (after EXIF orientation), largest first. Detection can miss faces that are small, turned away or covered. Nothing is stored.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The faces found.","content":{"application/json":{"schema":{"type":"object","properties":{"width":{"type":"integer"},"height":{"type":"integer"},"faces":{"type":"array","items":{"type":"object","properties":{"x":{"type":"integer"},"y":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"score":{"type":"number","minimum":0,"maximum":1}}}},"duration_ms":{"type":"integer"}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/blur-faces":{"post":{"tags":["AI"],"operationId":"blurFaces","summary":"Blur or pixelate the faces in a picture","description":"Covers an ellipse a little larger than each box. Without boxes, every face the detector finds is covered, and the request counts as an AI request; with boxes, only those areas are covered and no model runs. X-IC-Faces says how many areas were covered. Check the result: detection can miss faces.","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"effect","in":"query","description":"How the faces are hidden.","schema":{"type":"string","enum":["blur","pixelate"],"default":"blur"}},{"name":"strength","in":"query","description":"Blur radius or pixel block size, relative to each face.","schema":{"type":"integer","minimum":1,"maximum":100,"default":60}},{"name":"boxes","in":"query","description":"The areas to cover as x,y,width,height, separated by ;. An empty value covers nothing.","schema":{"type":"string","example":"120,80,200,260;640,90,180,230"}},{"name":"format","in":"query","description":"auto keeps the input's format where it is one of these, else JPEG. Quality 92.","schema":{"type":"string","enum":["auto","jpeg","png","webp","avif","tiff"],"default":"auto"}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image (output=binary), with X-IC-Original-Bytes, X-IC-Bytes, X-IC-Width, X-IC-Height, X-IC-Format, X-IC-Outcome, X-IC-Warnings and X-IC-Duration-Ms headers; or the stored result (output=json).","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/StoredResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ocr":{"post":{"tags":["AI"],"operationId":"ocr","summary":"Read the text in an image","parameters":[{"name":"filename","in":"query","description":"The file's name. Only its extension is used: formats without a signature of their own (TGA, some camera RAW files, old computer formats) are told apart by it. Not needed with multipart, which carries the name, or with a url.","schema":{"type":"string","example":"photo.cr2"}},{"name":"page","in":"query","description":"Which page, frame or plane of a file that holds several (PDF, DjVu, DICOM, a scan volume).","schema":{"type":"integer","minimum":1,"maximum":100000,"default":1}},{"name":"lang","in":"query","description":"One or more of eng, slv, comma-separated.","schema":{"type":"string","default":"eng","example":"eng,slv"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The text and how sure the engine is.","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"confidence":{"type":"integer","minimum":0,"maximum":100},"languages":{"type":"array","items":{"type":"string"}},"width":{"type":"integer"},"height":{"type":"integer"},"duration_ms":{"type":"integer"}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pipeline":{"post":{"tags":["Pipelines and jobs"],"operationId":"runPipeline","summary":"Run several steps on one image (Pro plan)","parameters":[{"name":"pipeline","in":"query","description":"The pipeline as JSON. May also be a multipart field or part of a JSON body.","schema":{"type":"string"}},{"name":"preset","in":"query","description":"A saved pipeline's name, or a template's.","schema":{"type":"string"}},{"name":"version","in":"query","description":"A version of a saved pipeline. Default: the latest.","schema":{"type":"integer","minimum":1,"maximum":1000000}},{"name":"dry_run","in":"query","description":"Report what would run, and the predicted sizes, without processing.","schema":{"type":"boolean","default":false}},{"name":"name","in":"query","description":"The source file's name, for the output name pattern.","schema":{"type":"string"}},{"name":"output","in":"query","description":"binary returns the image; json stores it for an hour and returns a link.","schema":{"type":"string","enum":["binary","json"],"default":"binary"}}],"requestBody":{"description":"The image: raw bytes with any Content-Type, multipart/form-data with a file part named \"image\", or JSON {\"url\": \"https://…\"}.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary"}}}},"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The image, or with output=json the stored result with filename, pipeline and steps; with dry_run the plan.","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"$ref":"#/components/schemas/PipelineResult"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pipelines":{"get":{"tags":["Pipelines and jobs"],"operationId":"listPipelines","summary":"Saved pipelines and the built-in templates","responses":{"200":{"description":"Both lists.","content":{"application/json":{"schema":{"type":"object","properties":{"pipelines":{"type":"array","items":{"type":"object"}},"templates":{"type":"array","items":{"$ref":"#/components/schemas/Pipeline"}}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Pipelines and jobs"],"operationId":"savePipeline","summary":"Save a pipeline under a name; an existing name gets a new version","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","pipeline"],"properties":{"name":{"type":"string","maxLength":60},"pipeline":{"$ref":"#/components/schemas/Pipeline"}}}}}},"responses":{"201":{"description":"The saved version.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/pipelines/{name}":{"get":{"tags":["Pipelines and jobs"],"operationId":"getPipeline","summary":"One saved pipeline","parameters":[{"name":"name","in":"path","required":true,"description":"The pipeline's name.","schema":{"type":"string"}},{"name":"version","in":"query","description":"Default: the latest.","schema":{"type":"integer","minimum":1,"maximum":1000000}}],"responses":{"200":{"description":"The pipeline.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Pipelines and jobs"],"operationId":"deletePipeline","summary":"Delete every version of a saved pipeline","parameters":[{"name":"name","in":"path","required":true,"description":"The pipeline's name.","schema":{"type":"string"}}],"responses":{"200":{"description":"Done.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs":{"get":{"tags":["Pipelines and jobs"],"operationId":"listJobs","summary":"The caller's jobs of the last hour, newest first","responses":{"200":{"description":"The jobs.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Pipelines and jobs"],"operationId":"createJob","summary":"Run a pipeline over several images in the background (Pro plan)","description":"Also reachable as /api/v1/batch. Images come as inputs (addresses) or as multipart file parts image, image_1 … image_19.","parameters":[{"name":"Idempotency-Key","in":"header","description":"Repeat the request safely: the same key returns the original job.","schema":{"type":"string","maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["inputs"],"properties":{"inputs":{"type":"array","items":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}},"pipeline":{"$ref":"#/components/schemas/Pipeline"},"preset":{"type":"string"},"version":{"type":"integer"},"webhook_url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"A replay of an earlier request with the same Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"202":{"description":"The job was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/batch":{"post":{"tags":["Pipelines and jobs"],"operationId":"createBatch","summary":"The same as POST /api/v1/jobs","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"202":{"description":"The job was accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}":{"get":{"tags":["Pipelines and jobs"],"operationId":"getJob","summary":"A job's status, progress and results","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Pipelines and jobs"],"operationId":"cancelJob","summary":"Cancel a job; finished images keep their results","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/optimize":{"post":{"tags":["Website"],"operationId":"optimizeSite","summary":"Scan a website and convert its images to WebP","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string"},"quality":{"type":"integer","minimum":1,"maximum":100,"default":80},"max_pages":{"type":"integer","minimum":1}}}}}},"responses":{"202":{"description":"The scan was started.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/optimize/{id}":{"get":{"tags":["Website"],"operationId":"getSiteJob","summary":"A scan's status and, when done, its report","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The scan.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/tiers":{"get":{"tags":["Website"],"operationId":"getSiteTiers","summary":"What each Website Optimizer tier covers, and the caller's plan, the websites it holds and its scan packages with the pages they have left (credits[].pages_left; scan_pages is what the next scan can take)","responses":{"200":{"description":"The tiers.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans":{"post":{"tags":["Website"],"operationId":"createSiteScan","summary":"Start a scan of a website from an address, a sitemap or a list of addresses","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["url","sitemap","list"],"default":"url"},"url":{"type":"string","description":"The site's address (source url) or the sitemap's (source sitemap). A plan covers a number of websites (domains): one more is refused with upgrade_required."},"urls":{"type":"string","description":"Source list: one address per line, at most 5 MB."},"project_id":{"type":"string","description":"Scan again inside an existing project. The address must be on that project's domain. Without it the scan joins the account's project of the same domain."},"name":{"type":"string"},"package":{"type":"string","enum":["site_1k","site_3k","site_10k","site_50k"],"description":"Draw on a bought scan package: a number of pages, used by any number of scans of any websites. The scan covers at most the pages the package has left and is charged the pages it analyses. Without it the plan's own limits apply. A package scan is not counted among the plan's websites."},"max_pages":{"type":"integer","minimum":1},"review":{"type":"boolean","description":"Stop after discovery so the page list can be looked at first."},"optimize":{"type":"string","enum":["auto","manual"],"default":"auto"},"settings":{"$ref":"#/components/schemas/SiteScanSettings"}}}}}},"responses":{"201":{"description":"The scan was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteScan"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Website"],"operationId":"listSiteScans","summary":"The account's website projects with their scans","responses":{"200":{"description":"The projects.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}":{"get":{"tags":["Website"],"operationId":"getSiteScan","summary":"A scan's status, progress, totals and downloads","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The scan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteScan"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Website"],"operationId":"updateSiteScan","summary":"Select pages, start, cancel, retry, optimize or package a scan","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["select","start","cancel","retry","optimize","package"]},"include":{"type":"array","items":{"type":"string"}},"exclude":{"type":"array","items":{"type":"string"}},"pages":{"type":"array","items":{"type":"integer"},"description":"Page numbers: to tick or untick (select, start) or to optimize."},"assets":{"type":"array","items":{"type":"integer"},"description":"Asset numbers to optimize."},"selected":{"type":"boolean"},"settings":{"$ref":"#/components/schemas/SiteScanSettings"}}}}}},"responses":{"200":{"description":"The scan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteScan"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Website"],"operationId":"deleteSiteScan","summary":"Delete a scan, its results and its files","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/pages":{"get":{"tags":["Website"],"operationId":"listSiteScanPages","summary":"The page inventory of a scan","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"status","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"over_limit","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"q","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"attention","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"optimization","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"min_savings","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"offset","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The pages.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/pages/{seq}":{"get":{"tags":["Website"],"operationId":"getSiteScanPage","summary":"One page with every asset it uses","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/assets":{"get":{"tags":["Website"],"operationId":"listSiteScanAssets","summary":"The asset inventory of a scan","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"kind","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"status","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"issue","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"page","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"q","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"min_savings","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"mapped","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"offset","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The assets.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/assets/{seq}":{"get":{"tags":["Website"],"operationId":"getSiteScanAsset","summary":"One asset, the pages that use it and its line of the replacement map","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Website"],"operationId":"approveSiteScanAsset","summary":"Approve or reject an asset's replacement","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["approval"],"properties":{"approval":{"type":"string","enum":["approved","rejected","auto"]}}}}}},"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/assets/{seq}/file":{"get":{"tags":["Website"],"operationId":"getSiteScanAssetFile","summary":"An asset's optimized file, a variant, a replacement candidate, or the original passed through","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}},{"name":"original","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"candidate","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"variant","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}},{"name":"download","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The file.","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/assets/{seq}/replacement":{"post":{"tags":["Website"],"operationId":"proposeSiteScanReplacement","summary":"Propose another picture for an image: upload one, or ask for one to be generated (not available yet)","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}},{"name":"brief","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["generate"]},"brief":{"type":"string"}}}}}},"responses":{"201":{"description":"The asset with its candidate.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Website"],"operationId":"removeSiteScanReplacement","summary":"Drop an image's replacement candidate","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"seq","in":"path","required":true,"description":"The page's or asset's number within its scan.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/exports":{"get":{"tags":["Website"],"operationId":"getSiteScanExport","summary":"A replacement map (CSV, JSON, XLSX), a report or an agent prompt; without `file`, the list","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"file","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The export, or the list of exports.","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/download":{"get":{"tags":["Website"],"operationId":"downloadSiteScan","summary":"The whole package as a ZIP (in parts when very large)","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}},{"name":"part","in":"query","description":"See the Website Optimizer section of the developer page.","schema":{"type":"string"}}],"responses":{"200":{"description":"The ZIP.","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/sites/scans/{id}/log":{"get":{"tags":["Website"],"operationId":"getSiteScanLog","summary":"What a scan did and what went wrong","parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The log.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/files/{id}":{"get":{"tags":["Images"],"operationId":"getFile","summary":"Download a stored result","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"The file.","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Images"],"operationId":"deleteFile","summary":"Delete a stored result before it expires","security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"The id returned when it was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/assets":{"get":{"tags":["Account"],"operationId":"searchAssets","summary":"Search the asset index","description":"The index holds facts about your images across projects (fingerprints, sizes, paths), never the images themselves.","parameters":[{"name":"q","in":"query","description":"Text to find in the path, project or format.","schema":{"type":"string"}},{"name":"project","in":"query","description":"Only this project.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"How many to return.","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"Matching assets and the list of projects.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Account"],"operationId":"indexAssets","summary":"Replace one project's entries with a fresh scan","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project","assets"],"properties":{"project":{"type":"string"},"assets":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"How many were indexed and removed.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Account"],"operationId":"deleteAssetProject","summary":"Remove a project from the index","parameters":[{"name":"project","in":"query","description":"The project to remove.","schema":{"type":"string"}}],"responses":{"200":{"description":"How many entries were removed.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/assets/duplicates":{"get":{"tags":["Account"],"operationId":"duplicateAssets","summary":"Identical files that appear more than once across your projects","responses":{"200":{"description":"Groups of duplicates and the bytes they waste.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/formats":{"get":{"tags":["Account"],"operationId":"formats","summary":"The formats this server reads and writes","security":[],"responses":{"200":{"description":"Input and output formats, and every known format with whether this server reads it.","content":{"application/json":{"schema":{"type":"object","properties":{"input":{"type":"array","items":{"type":"string"}},"output":{"type":"array","items":{"type":"string"}},"formats":{"type":"array","items":{"type":"object","required":["id","name","category","extensions","readable"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"extensions":{"type":"array","items":{"type":"string"}},"readable":{"type":"boolean"},"via":{"type":"string","enum":["engine","converter"]},"plan":{"type":"string","enum":["pro"]},"reason":{"type":"string","enum":["proprietary","not_an_image","several_files","not_yet","converter_off"]}}}}}}}}}}}},"/api/v1/capabilities":{"get":{"tags":["Account"],"operationId":"capabilities","summary":"Operations, options and limits of this server","security":[],"responses":{"200":{"description":"What the server can do.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/usage":{"get":{"tags":["Account"],"operationId":"usage","summary":"This month's usage and your limits","responses":{"200":{"description":"Usage.","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string"},"period":{"type":"string"},"used":{"type":"integer"},"limit":{"type":"integer"},"ai_used":{"type":"integer","description":"AI requests (background removal, upscaling, image to text) this month."},"ai_limit":{"type":"integer"},"rate_per_minute":{"type":"integer"},"key":{"type":"object","description":"The calling key's own allowance: a test key's day, or a live key's monthly limit. Absent when the key has none.","properties":{"mode":{"type":"string","enum":["live","test"]},"period":{"type":"string"},"used":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"4XX":{"description":"The request was refused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"5XX":{"description":"The server could not do it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/openapi.json":{"get":{"tags":["Account"],"operationId":"openapi","summary":"This document","security":[],"responses":{"200":{"description":"OpenAPI 3.1.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key from your account page: ic_live_…"}},"schemas":{"SiteScanSettings":{"type":"object","properties":{"format":{"type":"string","enum":["webp","avif","keep"],"default":"webp"},"quality":{"type":"integer","minimum":1,"maximum":100,"default":80},"max_width":{"type":["integer","null"],"description":"Images wider than this are scaled down to it."},"responsive_widths":{"type":"array","items":{"type":"integer"},"description":"Extra, narrower copies of each image for srcset."},"optimize_css":{"type":"boolean","default":true},"public_dir":{"type":"string","description":"Folder of the site the files will be served from, e.g. /static."},"include":{"type":"array","items":{"type":"string"},"description":"Path patterns with *; a page must match one."},"exclude":{"type":"array","items":{"type":"string"}}}},"SiteScan":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"status":{"type":"string","enum":["queued","discovering","ready","scanning","optimizing","packaging","completed","partially_completed","failed","cancelled"]},"tier":{"type":"string"},"source":{"type":"string"},"start_url":{"type":"string"},"limits":{"type":"object"},"discovery":{"type":"object"},"totals":{"type":"object","description":"Counts of pages and assets, and bytes: original and transfer (measured and estimated), estimated_savings (a prediction), optimized_from and optimized_to (measured)."},"progress":{"type":"object"},"error":{"type":["object","null"]},"expires_at":{"type":["string","null"]},"downloads":{"type":["object","null"]}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["unauthorized","forbidden","rate_limited","quota_exceeded","file_too_large","unsupported_format","too_many_pixels","password_protected","invalid_request","fetch_failed","busy","storage_full","timeout","not_found","upgrade_required","conflict","internal"]},"message":{"type":"string"},"request_id":{"type":"string"}}}}},"IdPhotoPreset":{"type":"object","properties":{"id":{"type":"string"},"country":{"type":"string","description":"Two-letter country code. Absent on plain sizes."},"document":{"type":"string","enum":["passport","visa"]},"medium":{"type":"string","enum":["print","digital"]},"width_mm":{"type":["number","null"]},"height_mm":{"type":["number","null"]},"dpi":{"type":"integer"},"width":{"type":"integer","description":"Pixels of the file that is made."},"height":{"type":"integer"},"min_bytes":{"type":["integer","null"]},"max_bytes":{"type":["integer","null"]},"format":{"type":["string","null"]},"background":{"type":"string"},"source_url":{"type":"string","format":"uri","description":"The official page the numbers were read from."},"checked_on":{"type":"string","format":"date"}}},"StoredResult":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time"},"original_bytes":{"type":"integer"},"bytes":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"format":{"type":"string"},"outcome":{"type":"string","enum":["done","optimal","unreachable"]},"warnings":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"integer"},"fingerprint":{"type":["string","null"]},"similarity":{"type":["number","null"]}}},"Inspection":{"type":"object","properties":{"format":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"megapixels":{"type":"number"},"bytes":{"type":"integer"},"frames":{"type":"integer"},"has_alpha":{"type":"boolean"},"color_space":{"type":["string","null"]},"bits_per_channel":{"type":["integer","null"]},"density":{"type":["number","null"]},"orientation":{"type":"integer"},"metadata":{"type":"object"},"exif":{"type":["object","null"]},"gps":{"type":["object","null"]},"fingerprint":{"type":"object","properties":{"sha256":{"type":"string"},"dhash":{"type":["string","null"]}}}}},"PipelineStep":{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["remove_background","upscale","resize","crop","rotate","edit","watermark","convert","compress"]},"when":{"type":"object","description":"The step runs only when every condition holds.","properties":{"format":{"type":"array","items":{"type":"string"}},"min_width":{"type":"integer"},"max_width":{"type":"integer"},"min_height":{"type":"integer"},"max_height":{"type":"integer"},"min_bytes":{"type":"integer"},"max_bytes":{"type":"integer"},"has_alpha":{"type":"boolean"}}},"params":{"type":"object","description":"The step's options: the query parameters of the matching endpoint.","additionalProperties":{"type":["string","number","boolean"]}}}},"Pipeline":{"type":"object","required":["steps"],"properties":{"version":{"type":"integer","const":1},"name":{"type":"string"},"steps":{"type":"array","minItems":1,"maxItems":10,"items":{"$ref":"#/components/schemas/PipelineStep"}},"output_name":{"type":"string","description":"File name pattern: {name}, {w}, {h}, {format}."}}},"StepReport":{"type":"object","properties":{"index":{"type":"integer"},"op":{"type":"string"},"status":{"type":"string","enum":["done","skipped","error","would_run","would_skip"]},"reason":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"duration_ms":{"type":"integer"}}},"PipelineResult":{"allOf":[{"$ref":"#/components/schemas/StoredResult"},{"type":"object","properties":{"filename":{"type":"string"},"pipeline":{"type":"object"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/StepReport"}},"dry_run":{"type":"boolean"}}}]},"Job":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","error","cancelled"]},"progress":{"type":"object","properties":{"done":{"type":"integer"},"total":{"type":"integer"}}},"results":{"type":"array","items":{"type":"object"}},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"webhook":{"type":["object","null"]}}}}}}