{
  "openapi": "3.0.1",
  "info": {
    "title": "Bulk Image Downloader & Website Image Extractor",
    "description": "Bulk image downloader and website image extractor: get images from website pages and extract all images from a website with alt text, size and type, or get product images by CSS selector. Image URL lists, plus bulk file downloader from a URL list or CSV, with ZIP. $0.002 per image.",
    "version": "0.1",
    "x-build-id": "J8xSJhyJDdT7VXQyR"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/pennydata~website-image-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-pennydata-website-image-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/pennydata~website-image-extractor/runs": {
      "post": {
        "operationId": "runs-sync-pennydata-website-image-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/pennydata~website-image-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-pennydata-website-image-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "images",
              "files"
            ],
            "type": "string",
            "description": "images = extract image URLs from web pages ($0.002 per image). files = bulk file downloader: download every file in a URL list, CSV or dataset ($0.001 per file).",
            "default": "images"
          },
          "zipOutput": {
            "title": "ZIP output (images.zip)",
            "type": "boolean",
            "description": "Images mode: download the images found (up to maxImages) into one images.zip in the key-value store. The link (zipUrl) is in each row, the SUMMARY record and the OUTPUT record. No extra charge: you pay only the normal per-image price. Same as downloadZip.",
            "default": false
          },
          "startUrls": {
            "title": "Page URLs",
            "type": "array",
            "description": "Public web pages to read. Each page is fetched with plain HTTP (no browser, no JavaScript rendering).",
            "default": [
              {
                "url": "https://en.wikipedia.org/wiki/Cat"
              },
              {
                "url": "https://books.toscrape.com/"
              }
            ],
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "altAudit": {
            "title": "SEO alt-text audit summary",
            "type": "boolean",
            "description": "Add one extra uncharged dataset record (status alt_audit_summary) with, per page, how many images lack alt text. Every image row always has altMissing; the same counts are in the SUMMARY key-value record.",
            "default": false
          },
          "onlyMissingAlt": {
            "title": "Only images missing alt text",
            "type": "boolean",
            "description": "Return only <img> rows whose alt text is absent, empty or blank (missingAlt = true). Filtered-out images are not charged.",
            "default": false
          },
          "cssSelector": {
            "title": "CSS selector (optional)",
            "type": "string",
            "description": "Only return images inside elements matching this selector, e.g. .product-gallery or main. Empty = whole page (og:image/twitter:image meta tags are only included when empty)."
          },
          "inputUrls": {
            "title": "Page URLs (alias: inputUrls)",
            "type": "array",
            "description": "Alias of startUrls; both are merged.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "urls": {
            "title": "Page URLs (alias: urls)",
            "type": "array",
            "description": "Alias of startUrls; both are merged.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "url": {
            "title": "Page URL (alias: url)",
            "type": "string",
            "description": "Alias of startUrls for a single page."
          },
          "maxPagesPerStart": {
            "title": "Pages per start URL",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "1 = only the page you list. Higher values also follow same-site links, up to this many pages per start URL.",
            "default": 1
          },
          "minWidth": {
            "title": "Minimum width (px)",
            "minimum": 0,
            "type": "integer",
            "description": "Skip images narrower than this. Width is measured from the image file header (first 64 KB, no full download) when measureDimensions is on, else the declared width. Unknown width is kept. 0 = off.",
            "default": 0
          },
          "minHeight": {
            "title": "Minimum height (px)",
            "minimum": 0,
            "type": "integer",
            "description": "Skip images shorter than this. Height is measured from the image file header when measureDimensions is on, else the declared height. Unknown height is kept. 0 = off.",
            "default": 0
          },
          "formats": {
            "title": "Image formats",
            "type": "array",
            "description": "Only deliver these formats, e.g. [\"jpg\",\"png\",\"webp\",\"svg\",\"gif\"]. Format comes from the URL extension or the Content-Type; images of unknown format are kept. Empty = all formats.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "imageFormats": {
            "title": "Image formats (alias)",
            "type": "array",
            "description": "Alias of Image formats: e.g. [\"jpg\",\"png\",\"webp\",\"gif\",\"svg\"]. Merged with 'formats'. Empty = all formats.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "imageType": {
            "title": "Image type",
            "enum": [
              "all",
              "ogImage",
              "logo",
              "favicon"
            ],
            "type": "string",
            "description": "all = every image (default). ogImage = only og:image / twitter:image share images. logo = images whose src, alt, class or id contains logo, plus apple-touch-icon. favicon = link rel=icon variants, with /favicon.ico as fallback. Every row has an imageType field. Same price per image.",
            "default": "all"
          },
          "excludeJunk": {
            "title": "Exclude junk images",
            "type": "boolean",
            "description": "Drop tracking pixels (1x1, declared width/height of 2 px or less, known tracker hosts), spacer/blank images, and sprite/icon/favicon images under 100 px. Turn off to get everything.",
            "default": true
          },
          "dedupe": {
            "title": "Deduplicate size variants",
            "type": "boolean",
            "description": "Treat URLs that differ only by size markers (?w=, ?width=, -300x200 filename suffixes) as one image and deliver (and charge) it once. Turn off to keep every variant.",
            "default": true
          },
          "measureDimensions": {
            "title": "Measure width and height",
            "type": "boolean",
            "description": "Read the real width and height of each image from its file header (PNG, JPEG, GIF, WebP, BMP, ICO) with a small range request, no full decode. Used by minWidth/minHeight and the width/height output fields. Turn off for the fastest run.",
            "default": true
          },
          "upgradeToOriginals": {
            "title": "Get full-size originals",
            "type": "boolean",
            "description": "Swap thumbnail URLs for the full-size original (WordPress -300x200, Shopify _300x300, Wikimedia /thumb/, ?w= resize params) and use the link target when a thumbnail is wrapped in <a href=full.jpg>. The original is only used when a HEAD request confirms it is an image; otherwise the thumbnail is kept. Output rows get thumbnailUrl. Default off.",
            "default": false
          },
          "includeVideo": {
            "title": "Include video files and posters",
            "type": "boolean",
            "description": "Also collect <video src>, <source src> inside <video>, og:video and the video poster image. Rows get mediaType video or poster. Each delivered row is charged like an image row. Default off.",
            "default": false
          },
          "includeAudio": {
            "title": "Include audio files",
            "type": "boolean",
            "description": "Also collect <audio src>, <source src> inside <audio> and og:audio. Rows get mediaType audio. Each delivered row is charged like an image row. Default off.",
            "default": false
          },
          "dedupeByContentHash": {
            "title": "Deduplicate by file content (SHA-1)",
            "type": "boolean",
            "description": "Download every image and skip files whose bytes are identical to one already delivered, even when the URLs differ. Skipped duplicates are not charged. Slower: needs a full download of each image. Default off.",
            "default": false
          },
          "minBytes": {
            "title": "Minimum file size (bytes)",
            "minimum": 0,
            "type": "integer",
            "description": "Skip images whose Content-Length (from a HEAD request) is smaller. Images with unknown size are kept. 0 = off.",
            "default": 0
          },
          "includeCssBackgrounds": {
            "title": "Include CSS background images",
            "type": "boolean",
            "description": "Also collect url() images from inline style attributes and <style> blocks (external stylesheets are not read).",
            "default": false
          },
          "includeLazyAndBackground": {
            "title": "Include lazy-load, all srcset sizes and CSS backgrounds",
            "type": "boolean",
            "description": "Also collect every srcset/picture candidate (not only the largest) and url() images from inline styles, <style> blocks and up to 5 linked stylesheets. Only adds rows; default output stays a superset. Turn off for the smaller legacy result.",
            "default": true
          },
          "dedupeAcrossPages": {
            "title": "Deduplicate across pages",
            "type": "boolean",
            "description": "Deliver (and charge) each image URL once per run, even when it appears on several pages. Turn off to get one row per page and image.",
            "default": true
          },
          "sameDomainOnly": {
            "title": "Same domain only",
            "type": "boolean",
            "description": "Keep only images hosted on the same site (or a subdomain) as the page; drops CDN and third-party images.",
            "default": false
          },
          "fetchMetadata": {
            "title": "Fetch content type and size",
            "type": "boolean",
            "description": "Send one HEAD request per image to fill contentType and bytes. Turn off for faster runs.",
            "default": true
          },
          "downloadMode": {
            "title": "Download mode (save images)",
            "type": "boolean",
            "description": "Image downloader: save every image to the run's key-value store and return a kvsUrl download link per row. Same as 'Download files to key-value store'.",
            "default": false
          },
          "downloadToKvs": {
            "title": "Download files to key-value store",
            "type": "boolean",
            "description": "Also download each image (max 10 MB) into the run's key-value store and add kvsKey/kvsUrl to the row. Images that fail to download are not delivered or charged.",
            "default": false
          },
          "maxImages": {
            "title": "Max images per run",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Stop after this many image rows. Caps your cost: 100 rows cost about $0.20.",
            "default": 100
          },
          "respectRobotsTxt": {
            "title": "Respect robots.txt",
            "type": "boolean",
            "description": "Skip pages disallowed for all bots in robots.txt. Skipped pages cost nothing.",
            "default": true
          },
          "timeoutSecs": {
            "title": "Request timeout (s)",
            "minimum": 5,
            "maximum": 60,
            "type": "integer",
            "description": "Per-request timeout in seconds (5-60).",
            "default": 20
          },
          "pageBudgetSecs": {
            "title": "Time budget per page (s)",
            "minimum": 10,
            "maximum": 3600,
            "type": "integer",
            "description": "Max seconds spent on one page (its stylesheets and images) before moving on, so one slow site cannot use up the run timeout. The run also stops cleanly about 20 s before its timeout and keeps all results found so far.",
            "default": 120
          },
          "fileUrls": {
            "title": "File URLs (files mode)",
            "type": "array",
            "description": "Files mode only. Direct links to files of any type (PDF, images, CSV, ZIP...). Plain URL list.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "csvUrl": {
            "title": "CSV URL (files mode)",
            "type": "string",
            "description": "Files mode only. Public link to a CSV or Google Sheet CSV export containing file URLs."
          },
          "csvColumn": {
            "title": "CSV column (files mode)",
            "type": "string",
            "description": "Header name or 0-based column number holding the URLs. Empty = first column that contains URLs."
          },
          "datasetId": {
            "title": "Dataset ID (files mode)",
            "type": "string",
            "description": "Files mode only. ID or name of an Apify dataset whose items contain file URLs."
          },
          "datasetField": {
            "title": "Dataset field (files mode)",
            "type": "string",
            "description": "Field holding the URL in each dataset item. Empty = first URL-like value in the item."
          },
          "filenameTemplate": {
            "title": "Filename template (files mode)",
            "type": "string",
            "description": "Name of each stored file. Placeholders: {index} (0001...), {basename} (name.ext from the URL), {name}, {ext}, {host}.",
            "default": "{index}-{basename}"
          },
          "downloadZip": {
            "title": "Download all images as one ZIP",
            "type": "boolean",
            "description": "Images mode: download every image and put them all into one images.zip record in the key-value store. The link is in each row (zipUrl) and in the OUTPUT record. No extra charge.",
            "default": false
          },
          "maxZipMb": {
            "title": "Max ZIP size MB",
            "minimum": 1,
            "maximum": 400,
            "type": "integer",
            "description": "Images mode with zipOutput: size of one ZIP part in MB (capped at 100). Bigger jobs are split into images-part-001.zip, images-part-002.zip, ... so memory stays low; every image is also saved individually.",
            "default": 200
          },
          "createZip": {
            "title": "Create ZIP (files mode)",
            "type": "boolean",
            "description": "Also put all downloaded files into files.zip in the key-value store. Large jobs are split into files-part-001.zip, files-part-002.zip, ... (250 MB each); every file is also saved individually.",
            "default": false
          },
          "retries": {
            "title": "Retries (files mode)",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Extra attempts for timeouts, network errors, HTTP 429 and 5xx, with backoff.",
            "default": 2
          },
          "maxFileMb": {
            "title": "Max file size MB (files mode)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Files larger than this are skipped and not charged.",
            "default": 50
          },
          "maxFiles": {
            "title": "Max files per run (files mode)",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Stop after this many files.",
            "default": 1000
          },
          "maxCostUsd": {
            "title": "Max cost USD (files mode)",
            "type": "number",
            "description": "Spending guard: at most floor(maxCostUsd / 0.001) files are downloaded. Empty = no extra cap."
          },
          "concurrency": {
            "title": "Concurrency (files mode)",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Parallel downloads.",
            "default": 5
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Route page and image requests through Apify Proxy or your own proxies, for sites that block datacenter IPs. Default: direct requests."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}