{
  "openapi": "3.0.1",
  "info": {
    "title": "Bulk Image Downloader to ZIP with SHA-256 Manifest",
    "description": "Bulk image downloader and file downloader. Image and file URLs become ZIP parts with a SHA-256 manifest, the real file type from the bytes and per-URL status. HTML error pages are rejected and failed downloads are free. Not affiliated with Google, Dropbox, Shopify or YouTube.",
    "version": "1.0",
    "x-build-id": "gIgtqj5vaVKJPYPSo"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/mmdincer~bulk-file-downloader-zip/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-mmdincer-bulk-file-downloader-zip",
        "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/mmdincer~bulk-file-downloader-zip/runs": {
      "post": {
        "operationId": "runs-sync-mmdincer-bulk-file-downloader-zip",
        "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/mmdincer~bulk-file-downloader-zip/run-sync": {
      "post": {
        "operationId": "run-sync-mmdincer-bulk-file-downloader-zip",
        "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": {
          "urls": {
            "title": "File URLs",
            "maxItems": 10000,
            "type": "array",
            "description": "One address per line, <code>http://</code> or <code>https://</code>. Public files only: no login, and addresses that point to private or local networks are refused. Up to 10,000 per run. The same address twice is downloaded once.",
            "items": {
              "type": "string"
            }
          },
          "files": {
            "title": "Files with names and expected hashes (optional)",
            "type": "array",
            "description": "Use this instead of, or together with, the URL list when you want to choose the file name or verify the download. A JSON list of objects: <code>url</code> (required), <code>fileName</code> (optional) and <code>sha256</code> (optional, 64 hex characters). When a hash is given and the download does not match, the file is rejected and not charged."
          },
          "datasetId": {
            "title": "Dataset to read URLs from (optional)",
            "type": "string",
            "description": "ID or name of an Apify dataset, for example the output of another Actor. The Actor reads the address from the field named below in every item (a text field or a list of texts)."
          },
          "urlField": {
            "title": "Field with the URL",
            "type": "string",
            "description": "The dataset field that holds the file address. Used only with a dataset ID.",
            "default": "url"
          },
          "output": {
            "title": "What to store",
            "enum": [
              "zip",
              "files",
              "both",
              "none"
            ],
            "type": "string",
            "description": "<b>ZIP</b> stores the files in ZIP parts with <code>manifest.json</code> and <code>SHA256SUMS</code> inside. <b>Each file</b> stores every file as its own record with its own link. <b>Both</b> does both. <b>Nothing (check only)</b> downloads, hashes and reports without keeping the files. The dataset always has one row per URL.",
            "default": "zip"
          },
          "folders": {
            "title": "Folders inside the ZIP",
            "enum": [
              "none",
              "host",
              "type"
            ],
            "type": "string",
            "description": "<b>Flat</b> puts every file in the ZIP root. <b>By host</b> uses one folder per website. <b>By type</b> uses image, pdf, office, audio, video, archive, text and data folders.",
            "default": "none"
          },
          "fixExtensions": {
            "title": "Fix wrong or missing extensions",
            "type": "boolean",
            "description": "Rename a file when its extension is missing, a script extension such as <code>.php</code>, or contradicts what the bytes show (a PNG saved as <code>photo.jpg</code> becomes <code>photo.png</code>). The original address stays in the manifest.",
            "default": true
          },
          "allowedTypes": {
            "title": "Only these file types",
            "type": "array",
            "description": "Keep only files whose <b>real</b> type (from the bytes, not the address) is in the list. Others are skipped and not charged. Empty means all types. Groups: image, pdf, office (Word, Excel, PowerPoint, OpenDocument, EPUB), audio, video, archive, text, data (JSON, CSV, XML, Parquet, SQLite).",
            "items": {
              "type": "string",
              "enum": [
                "image",
                "pdf",
                "office",
                "audio",
                "video",
                "archive",
                "text",
                "data"
              ]
            }
          },
          "allowHtml": {
            "title": "Allow HTML pages",
            "type": "boolean",
            "description": "By default an address that answers with a web page (a login wall, a 404 page served with status 200, a hotlink-protection page) is rejected as <code>html_page</code> instead of being saved as a fake file. Turn this on only if you want web pages saved as files.",
            "default": false
          },
          "maxFileSizeMb": {
            "title": "Largest file (MB)",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Files bigger than this are rejected as <code>too_large</code>, as soon as the server announces the size or the download passes it. Not charged.",
            "default": 50
          },
          "maxTotalSizeMb": {
            "title": "Total size of the run (MB)",
            "minimum": 1,
            "maximum": 2000,
            "type": "integer",
            "description": "When the files together reach this size, the remaining downloads stop and are marked <code>total_limit_reached</code>. Everything delivered so far is still zipped.",
            "default": 500
          },
          "maxFiles": {
            "title": "Maximum number of files",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Only the first this-many addresses are downloaded. The rest are marked <code>file_limit</code>.",
            "default": 10000
          },
          "fileTimeoutSecs": {
            "title": "Time limit per file (seconds)",
            "minimum": 10,
            "maximum": 900,
            "type": "integer",
            "description": "One download, including retries of the same attempt, is cancelled after this long. A server that sends nothing for 30 seconds is cancelled sooner.",
            "default": 120
          },
          "maxRunMinutes": {
            "title": "Time limit for the run (minutes)",
            "minimum": 1,
            "maximum": 120,
            "type": "integer",
            "description": "When this time is up, running downloads are cancelled, unstarted ones are marked <code>run_time_limit</code>, and the files delivered so far are zipped.",
            "default": 30
          },
          "maxRetries": {
            "title": "Retries per file",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "How many more times a download is tried after a timeout, a network error, HTTP 429 or a 5xx answer. An interrupted transfer continues where it stopped when the server supports it. Refusals (401, 403, 404) are never retried.",
            "default": 2
          },
          "concurrency": {
            "title": "Parallel downloads",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many files are downloaded at the same time.",
            "default": 8
          },
          "perHostConcurrency": {
            "title": "Parallel downloads per website",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "No more than this many connections to one host at a time, so a list of files from a single server does not hammer it. Maximum 5.",
            "default": 3
          },
          "zipPartSizeMb": {
            "title": "ZIP part size (MB)",
            "minimum": 10,
            "maximum": 300,
            "type": "integer",
            "description": "A new ZIP part (FILES-002.zip, ...) starts when the files of the current part reach about this size. A file bigger than this gets a part of its own.",
            "default": 200
          },
          "onlyChanged": {
            "title": "Only new or changed files",
            "type": "boolean",
            "description": "Skip files that are the same as in the last run with the same saved-state name. The Actor asks the server whether the file changed (ETag, Last-Modified) and compares the SHA-256, so unchanged files are not delivered and not charged. The first run delivers everything.",
            "default": false
          },
          "stateName": {
            "title": "Saved-state name",
            "type": "string",
            "description": "Name of the key-value store that remembers each file's fingerprint for Only new or changed files. Use a different name for each schedule. Letters, digits and hyphens.",
            "default": "bulk-file-downloader-zip-state"
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}