Bulk File Downloader: Download Files from URLs to Storage avatar

Bulk File Downloader: Download Files from URLs to Storage

Pricing

from $1.00 / 1,000 file downloaded (first 5 mb included)s

Go to Apify Store
Bulk File Downloader: Download Files from URLs to Storage

Bulk File Downloader: Download Files from URLs to Storage

Bulk download files from a URL list (PDF, ZIP, CSV, images, audio, video) to storage, each with a public link, real file type and SHA-256. $1 per 1,000 files.

Pricing

from $1.00 / 1,000 file downloaded (first 5 mb included)s

Rating

0.0

(0)

Developer

Kaizoku Data

Kaizoku Data

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

13 days ago

Last modified

Security

Limited permissions

Share

Bulk File Downloader: Download Files from a URL List to Storage

Bulk download files from a list of URLs (PDF, ZIP, CSV, images, audio, video, Office documents) into Apify storage, and get one row per file with a public download link, the real file type, size and SHA-256. Paste up to 1,000 direct file links, press Start, and download the files from your key-value store or use the links in your next tool. $1 per 1,000 files up to 5 MB each; failed, refused and skipped files are free.

Give it a list of direct file links. It downloads each file (streamed to disk, not held in memory), checks what the file really is from its first bytes, computes its SHA-256 and size, saves it in an Apify key-value store and returns a dataset row with a public link. PDF, ZIP, CSV, images, audio, video, Office documents and any other file type. Keyless, no browser, no proxy.

Price: $1 per 1,000 files ($0.001 per file saved). The first 5 MB of each file are included; a larger file adds $0.001 per started 10 MB above 5 MB (a 25 MB file is $0.001 + 2 x $0.001 = $0.003; a 100 MB file is $0.011). No start fee on top of Apify's default. Only files that are saved are charged.

  • Real file type, not the name: magic bytes first, then Content-Type, then the extension. Web pages (HTML) are refused for free, so a login page or an error page is never saved as "report.pdf".
  • A row per file: public link, key, final URL after redirects, file name, server type, detected type, size in bytes, SHA-256.
  • Filters and dedupe: keep only the types you list (pdf, application/pdf, image/*), skip a file whose SHA-256 you already saved in this run, cap the file size (default 100 MB, up to 500 MB).
  • Your own names and your own store: give each URL a file name, and pick one of your key-value stores to receive the files.
  • Careful with other people's servers: robots.txt of each host is checked, a Crawl-delay is honoured in full, at most two downloads at a time per host (the host of every redirect hop counts) and at least 250 ms between requests to one host, no crawling, no proxy, no cookies, and social-media and platform hosts are refused.
  • Quick start: press Start. The prefilled input downloads three small public files (a public-domain PDF and a public-domain NASA photo from Wikimedia Commons, and a CC BY 4.0 CSV from GitHub), about 1 second, $0.003.

Use cases

Each input below can be pasted as-is into the JSON tab of the input (the links are public files and work today).

1. Archive a list of report PDFs under your own file names (compliance archives, research libraries, invoices you have links to). Only real PDFs are kept: a login page or an error page that answers instead is refused for free.

{
"fileUrls": ["https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf"],
"fileNames": ["maine-constitution-2013.pdf"],
"allowedTypes": ["pdf"]
}

2. Turn image links from a scraper or a spreadsheet into stored files with stable links (product photos, press images, assets for a catalogue). Keep images only, skip identical content, cap the size:

{
"fileUrls": [
"https://upload.wikimedia.org/wikipedia/commons/a/a8/NASA-Apollo8-Dec24-Earthrise.jpg",
"https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf"
],
"allowedTypes": ["image/*"],
"dedupeBySha256": true,
"maxFileSizeMb": 20
}

The PDF in this list gets a free type-not-allowed row; only the photo is saved and charged.

3. Snapshot data files on a schedule and spot changes by hash (CSV, JSON or Parquet exports for a data pipeline). Run it on an Apify schedule; when a row's sha256 differs from the previous run's, the file changed. With a fixed file name and a store you picked in Save files in this key-value store, each run overwrites the latest copy; leave fileNames empty instead to keep every version, because the automatic key includes the first 8 characters of the SHA-256.

{
"fileUrls": ["https://raw.githubusercontent.com/fivethirtyeight/data/master/airline-safety/airline-safety.csv"],
"fileNames": ["airline-safety-latest.csv"],
"allowedTypes": ["csv"]
}

More input shapes (your own key-value store, files up to 300 MB) are under Example inputs below.

What a run costs, worked out: 1,000 files up to 5 MB each = 1,000 x $0.001 = $1.00, plus Apify's start event ($0.00005 at the default 512 MB). A mixed batch of 900 small files and 100 files of 30 MB = 900 x $0.001 + 100 x ($0.001 + 3 x $0.001) = $0.90 + $0.40 = $1.30 (+ $0.00005). Full table under Pricing.

What it does

For each file URL:

  1. Refuses social-media, video-platform and Google hosts before any DNS lookup (platform).
  2. Reads the host's robots.txt (our User-Agent is file-downloader-actor/0.1 (https://apify.com/ataism/file-downloader)). A disallowed path is not downloaded and gets blocked-by-robots, free. A Crawl-delay is honoured in full, never shortened (see Limits).
  3. Downloads the file (public addresses only, at most 5 redirects with every hop re-checked, size cap, stall limit and a time limit set by the file's price, see Limits) straight to the run's disk, computing the SHA-256 on the way.
  4. Looks at the first 4 KB: a web page is refused (not-a-file), text served under a binary name is refused (type-mismatch), and a type outside your list is skipped (type-not-allowed). All free, and the download stops after a few KB.
  5. Saves the file in the key-value store (the run's, or the one you picked), pushes one dataset row, and only then charges.

Detected types include PDF; ZIP, DOCX, XLSX, PPTX, EPUB, ODT, JAR; GZIP, BZIP2, XZ, 7z, RAR, TAR, ZSTD; JPEG, PNG, GIF, WebP, AVIF, HEIC, TIFF, BMP, ICO, PSD, SVG; MP3, AAC, FLAC, OGG, WAV, AIFF, MIDI, M4A; MP4, MOV, WebM, MKV, AVI, FLV, WMV, MPEG; RTF, PostScript, legacy Office (OLE), SQLite, Parquet, WASM, fonts, executables; and text formats (CSV, TSV, JSON, JSONL, XML, Markdown, plain text) by header or extension. Anything else is application/octet-stream and is still saved.

Input

FieldWhat it does
File URLs (fileUrls)Direct http(s) links, one per line, at most 1,000 per run. Through the API each entry can also be {"url": "...", "fileName": "report.pdf"}. Duplicate URLs collapse into one.
File names (fileNames)Optional, one per URL in the same order (leave a line empty for the automatic name). The name becomes the key in the store, made safe (no folders or odd characters) and numbered (-2, -3) if two files in the run get the same key.
Allowed types (allowedTypes)Optional. Extensions (pdf, .zip) and/or MIME types (application/pdf, image/*). Others are skipped for free. The real type from the bytes decides; for plain text and unknown binaries the header and the extension are used too. Empty = every type except web pages. Add text/html to download HTML pages on purpose (text/* is not enough).
Max file size (MB) (maxFileSizeMb)Default 100, maximum 500. Bigger files are refused from their Content-Length, or cut off while streaming, and are not charged. Lowered automatically if the run's disk (twice its memory) is too small.
Skip duplicate content (dedupeBySha256)Off by default. On: a file whose SHA-256 matches one already saved in this run is not stored again and not charged (status: "duplicate", duplicateOf = key of the first copy).
Save files in this key-value store (outputStore)Optional. Pick one of your stores with the store picker; the Actor then gets write access to that store only (it works with Limited permissions and never asks for an API token). Empty = the run's own default store. A file with the same key in a store you pick is overwritten.
Allow slow hosts (allowSlowHosts)Off by default. Off: files on a host whose robots.txt asks for a Crawl-delay above 1 second are skipped (free slow-host rows). On: delays up to 2 seconds (1.62 s at 1,024 MB of memory) are honoured in full. Above that a host is always skipped.
Download timeout (downloadTimeoutSecs)Per file including redirects, default 300 s (10 to 600). Time spent waiting for a Crawl-delay or for a free per-host slot is not counted. Each file also has a time limit set by its price (3.6 s for a file up to 5 MB at 512 MB, longer for bigger files), counted from the moment the request is sent: connect, TLS, the wait for response headers, the robots.txt check and the download all count. See Minimum speed below.

Example inputs

1. A list of reports, original names, PDF only:

{
"fileUrls": ["https://example.org/reports/q1.pdf", "https://example.org/reports/q2.pdf"],
"fileNames": ["2026-Q1-report.pdf", "2026-Q2-report.pdf"],
"allowedTypes": ["pdf"]
}

2. Mixed assets into your own store, duplicates skipped, images and archives only:

{
"fileUrls": ["https://example.org/a.zip", "https://example.org/photo.jpg", "https://example.org/copy-of-photo.jpg"],
"allowedTypes": ["image/*", "zip"],
"dedupeBySha256": true,
"outputStore": "<your key-value store ID, from the store picker>"
}

3. Large files (up to 300 MB each): the default 512 MB of memory is enough (files are streamed to disk); only the limits change. The source must deliver about 5.2 MB/s or better for a 300 MB file (see Minimum speed):

{
"fileUrls": ["https://example.org/data/export.parquet"],
"maxFileSizeMb": 300,
"downloadTimeoutSecs": 600
}

Output

One dataset row per input URL (inputIndex is its position in your input; rows are saved in completion order):

{
"inputIndex": 0,
"url": "https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf",
"finalUrl": "https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf",
"fileName": "Constitution_of_Maine_2013.pdf",
"status": "ok",
"key": "Constitution-of-Maine-2013-30ee0dfa.pdf",
"publicUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/Constitution-of-Maine-2013-30ee0dfa.pdf?signature=<signature>",
"contentType": "application/pdf",
"detectedType": "application/pdf",
"detectedFrom": "magic",
"sizeBytes": 167843,
"sha256": "30ee0dfacc507a93ef86bde42b5d0e3bb13ae9b5e4355c26e993949f3a88c39f",
"charged": { "file-downloaded": 1, "large-file": 0 },
"downloadedAt": "2026-10-20T14:40:07.913Z"
}
  • key: without a name from you, file name + first 8 characters of the SHA-256 + extension, so the same content always gets the same key and two different files with the same name never collide. With a name from you, the key is that name (made safe).
  • detectedFrom: magic (from the bytes), text (the bytes are text of a recognisable kind), header or extension (plain text or unknown binary: the server's Content-Type or the name decided), unknown.
  • Stored content type: only types a browser cannot run or render as a page keep their own Content-Type in the store (images except SVG, audio, video, fonts, PDF, archives, Office/OpenDocument files, CSV, plain text, JSON). Everything else is stored as application/octet-stream, a download: HTML, XHTML, SVG, every XML type (xml, xsl, +xml), JavaScript and any type not on that short list. detectedType still reports the real type.
  • publicUrl is a key-value-store record link; it carries a signature when the store requires one. A named store you picked adds storeId.
  • The run's default key-value store also holds RUN_SUMMARY (counts, events charged, bytes downloaded, failures by code, peak memory, why the run stopped) and PROGRESS (lets a restarted run skip finished files, so nothing is downloaded or charged twice). On a restart the Actor cross-checks Apify's own charge counts against what it can see; if rows that were already charged are not visible in the dataset yet it waits up to 60 s, and if they still do not show up it stops with an error instead of downloading and charging them again (progress is kept, resurrect the run later). It never charges retroactively.
  • Rows with status: "error" have errorCode and message; status: "duplicate" has duplicateOf. Neither is charged.

Status and error codes (only ok is charged)

errorCodeMeaning
invalid-url, blocked, dnsNot a valid URL; not http(s), or a private, loopback, link-local or internal address (also after a redirect); host does not resolve.
platformSocial-media, video-platform or Google host (YouTube, TikTok, Instagram, Facebook, X, Vimeo, SoundCloud, Spotify, Twitch, Reddit, LinkedIn, Google, Discord, Pinterest and their CDNs). Refused before any lookup, also after a redirect.
blocked-by-robotsThe host's robots.txt disallows the path for our User-Agent. Not downloaded.
robots-unreachablerobots.txt could not be read (server error, HTTP 429 or timeout, tried twice), so the file was not downloaded. A missing robots.txt (HTTP 404) means no restrictions.
slow-hostThe host's robots.txt asks for a Crawl-delay above 1 second and allowSlowHosts is off, or above 2 seconds (1.62 s at 1,024 MB). Free; the delay is never shortened.
refusedThe server answered 401, 403, 407, 429, 451 or 999 (login, ban, rate limit), or answered 200 with a bot-challenge or access-denied page instead of the file. Not retried, with no other method tried.
host-skippedThe host refused or failed three requests earlier in this run (a refusal above, or HTTP 503), so the rest of its files are skipped.
http, network, timeout, redirectsOther HTTP error; connection failure or cut connection; no data for 30 s or over the download timeout; more than 5 redirects.
too-slowDropped, free, because the download would cost more run time than the file is worth: the file (including the wait for the server's first answer) took longer than its price pays for in compute (a file up to 5 MB: 3.6 s at 512 MB; see Minimum speed), or the run as a whole had passed its compute allowance and this was its slowest download. See Limits.
too-largeAbove Max file size.
not-a-fileThe link returned a web page (HTML). Use a direct file link, or allow text/html.
type-mismatchThe name or header promises a binary file (PDF, ZIP, image, ...) but the server sent plain text, usually an error message.
type-not-allowedThe file's real type is not in Allowed types.
empty-fileThe server sent 0 bytes.
disk, store-failedThe file did not fit on the run's disk; the file was downloaded but could not be saved in the key-value store.
budgetThe run's Max total charge cannot pay for this file (big files cost more).
unexpectedInternal error; try again, and tell us if it persists.

Pricing

Pay per event, plus Apify's standard Actor-start event. There is no additional start fee from this Actor.

EventPriceWhen
file-downloaded$0.001One per file saved, after it is stored and its row is pushed.
large-file$0.001 per unitOne per started 10 MB of file size above the first 5 MB (MB = 1,048,576 bytes): up to 5 MB = 0, up to 15 MB = 1, up to 25 MB = 2, up to 100 MB = 10, up to 500 MB = 50. Charged together with file-downloaded.
Each file isCost per file100 files1,000 files
up to 5 MB$0.001$0.10$1.00
10 MB$0.002$0.20$2.00
30 MB$0.004$0.40$4.00
100 MB$0.011$1.10$11.00
500 MB (the maximum)$0.051$5.10$51.00

Failed, blocked, refused, filtered and duplicate files cost nothing. Set Max total charge in the run options to cap spending: the run stops cleanly when the limit is reached (stoppedBy: "max-charge"), never starts a download it cannot pay for, and never charges for a file it did not save. Apify subscription discounts apply on top. You pay only these events: with pay-per-event pricing, Apify bills the run's compute to us, the developer, not to you. The defaults (512 MB) keep it small next to the price.

For AI agents (MCP)

Purpose: one call downloads the direct file links you give it into Apify storage and returns one row per link: status, a publicUrl to the stored file, detectedType, sizeBytes and sha256. It does not find files on pages and does not open or summarise file contents.

Minimal input that works:

{ "fileUrls": ["https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf"] }

Everything else has a default (every type except web pages, 100 MB per file, no dedupe, the run's own store). An empty fileUrls list fails the run with "Add at least one file URL to download."

One output row per URL (trimmed): {"inputIndex": 0, "url": "...", "status": "ok", "key": "Constitution-of-Maine-2013-30ee0dfa.pdf", "publicUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/...", "detectedType": "application/pdf", "sizeBytes": 167843, "sha256": "30ee0dfa..."}. Rows with status: "error" carry errorCode and message and are free; status: "duplicate" is free too.

Cost: $0.001 per saved file up to 5 MB (1 file = $0.001, 100 = $0.10, 1,000 = $1.00), plus $0.001 per started 10 MB above 5 MB, plus Apify's standard small per-run start fee. Cap spend with Apify's Max total charge, maxFileSizeMb or allowedTypes.

Limits: direct file links only, at most 1,000 per run; social-media, video-platform and Google hosts are refused; robots.txt is honoured.

How to call it via the Apify MCP server (https://mcp.apify.com; tool names from the apify-mcp-server README):

  1. search-actors with a query such as bulk file downloader urls (free) may list ataism/file-downloader; search results are ranked, so if it isn't listed, go straight to step 2 with the Actor name.
  2. fetch-actor-details with actor ataism/file-downloader returns the input schema, pricing and output schema (free).
  3. call-actor with actor = ataism/file-downloader and input = {"fileUrls": ["https://example.org/a.pdf"]} runs it. The response holds run metadata and a dataset ID, not the rows.
  4. get-dataset-items with that dataset ID returns the rows (follow the nextStep in the call-actor response).

To expose only this Actor as a tool, connect to https://mcp.apify.com?tools=ataism/file-downloader.

Use it via API, n8n or Make

Get an API token in Apify Console → Settings → API & Integrations, and keep it in an environment variable (APIFY_TOKEN below). Never paste it into shared code.

cURL (starts a run, waits for it and returns one row per file; the synchronous endpoint waits up to 5 minutes, fine for a few dozen small files; for bigger batches use the clients below):

curl -X POST "https://api.apify.com/v2/acts/ataism~file-downloader/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"fileUrls": ["https://upload.wikimedia.org/wikipedia/commons/f/f4/Constitution_of_Maine_2013.pdf"]}'

JavaScript (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('ataism/file-downloader').call({
fileUrls: ['https://example.org/a.pdf', 'https://example.org/b.zip'],
allowedTypes: ['pdf', 'zip'],
dedupeBySha256: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const f of items) console.log(f.url, f.status, f.detectedType, f.sizeBytes, f.sha256, f.publicUrl);

Python (pip install "apify-client>=3"; with versions before 3.0, call() returns a dict: use run["defaultDatasetId"]):

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("ataism/file-downloader").call(run_input={
"fileUrls": ["https://example.org/a.pdf", "https://example.org/b.zip"],
"allowedTypes": ["pdf", "zip"],
})
for f in client.dataset(run.default_dataset_id).iterate_items():
if f["status"] != "ok":
print("not saved (not charged):", f["url"], f.get("errorCode"), f.get("message"))
else:
print(f["publicUrl"], f["sizeBytes"], f["sha256"])

n8n:

  1. Start with any trigger that gives you file links (a form, a sheet row, a webhook).
  2. Add the Apify node, operation Run an Actor and get dataset, Actor ataism/file-downloader, input {"fileUrls": ["{{ $json.fileUrl }}"]}.
  3. Use publicUrl, sha256 or sizeBytes in the next node (a sheet, a database, a storage upload).

Make:

  1. Add the Apify module Run an Actor, choose ataism/file-downloader, put your links in the input JSON and set Run synchronously to Yes.
  2. Add the Apify module Get Dataset Items and map the run's default dataset ID (one bundle per file).
  3. Send publicUrl, hashes or sizes to your next module (Google Sheets, Airtable, a webhook, a storage service).

Privacy and terms

  • You are responsible for having the right to download and copy every file you give this Actor (copyright, licences, contracts, privacy and data-protection law). It does not check this and does not find files for you. Files can contain personal data; the Actor does not open, scan or analyse them beyond reading their first bytes to find the type, and sends them nowhere except to the key-value store you choose.
  • Files are written to the run's disk while they arrive and deleted as soon as they are saved or refused. The only copies that remain are in your key-value store, plus RUN_SUMMARY and PROGRESS in the run's default store. Storages belong to your Apify account and follow your retention settings.
  • The url and finalUrl fields echo what you supplied and what the redirects led to (including a signed query string if you used one), so treat the dataset as sensitive if your URLs are. Logs show only a URL's host and path, never its query string, and never file content. publicUrl carries the store's signature when the store requires one: share it only as widely as you share the file.
  • The Actor sends no cookies, no login and no API token to the sites it downloads from. No data goes to any AI or third-party service.
  • Respect the sites you download from. robots.txt is checked and honoured, but a site's terms of use may still restrict bulk downloads. Bulk downloading is your responsibility. For example, GitHub's Acceptable Use Policies bar "excessive automated bulk activity (for example, spamming)", and Wikimedia asks scripts to identify themselves; this Actor identifies itself, fetches only the files you list and limits itself to two downloads at a time per host, but the volume you request is yours to judge.
  • Credit for the sample data: the default CSV is airline-safety.csv from FiveThirtyEight's data repository (data compiled from the Aviation Safety Network), used under Creative Commons Attribution 4.0: Aviation Safety Network via FiveThirtyEight, CC BY 4.0. The default PDF (Constitution of Maine) and photo (NASA, Apollo 8 Earthrise) are public domain according to Wikimedia Commons.

Safety

Only http and https URLs to public addresses are fetched. Private, loopback, link-local and internal addresses, and non-http schemes (file:, ftp: and so on), are blocked, including after redirects (at most 5, each re-checked, also against robots.txt and the platform list) and at connection time. Social-media and platform hosts are refused before any DNS lookup. Files are checked by content, not by name. A 401, 403, 429 or challenge page is an error row: there is no retry with other headers or methods, no CAPTCHA handling and no proxy; after three refusals the rest of that host's files in the run are skipped.

Limits and honest caveats

  • Direct file URLs only. No page crawling, no link discovery, nothing behind a login, no streaming-site extraction.

  • Up to 1,000 files per run, 100 MB per file by default (500 MB maximum), 4 downloads in parallel, at most 2 per host (the host of each redirect hop too, with at least 250 ms between requests to one host), and at most 100 GB downloaded per run (stoppedBy: "total-size-cap").

  • Memory: the Actor runs with 512 MB by default and at most 1,024 MB (more is never needed, because files are streamed; more memory only makes waiting more expensive, and halves every per-file time limit).

  • Memory and disk: files are streamed to the run's disk, so memory use stays near 100 to 150 MB whatever the file size (measured with a 500 MB file). A run's disk is twice its memory; at the default 512 MB about 800 MB of files can be in flight, and the file-size limit is lowered automatically if the disk is smaller. Files up to 24 MB are handed to the key-value store as one buffer (the Apify client compresses buffer uploads with gzip, which costs CPU), bigger files are streamed from disk.

  • Large records: Apify key-value store records of 17.5 MB were verified to work on the platform (2026-10-20). Records above that, up to 500 MB, work locally (a 70 MB file is tested end to end) but have not been verified on the platform; if a platform upload fails the row says store-failed and is not charged.

  • Crawl-delay: a Crawl-delay in robots.txt is honoured in full for every download from that host (also after a redirect to it), never shortened, and waiting is not part of the download timeout. Waiting costs run time (billed to us, not to you), so a host that asks for more than 1 second is skipped (free slow-host rows) unless you set allowSlowHosts, and one that asks for more than 2 seconds (1.62 s at 1,024 MB of memory: 0.9 x 1.8 s x 1,024 / memory) is always skipped. 10, 10s and 10 seconds all read as 10; if several lines or groups apply, the longest counts.

  • Compute guards (why some slow downloads are dropped): compute is billed to us as run time, so a slow source can cost more than a file earns. Everything is costed at $0.20 per compute unit and kept within 10% of the price: (1) a time limit per file, set by the price that file pays (base $0.001 plus $0.001 per started 10 MB above 5 MB), counted from the moment the request is sent; the size used is the larger of the announced length and the bytes received so far, so unknown sizes are covered too, and before the headers arrive only the base price counts. Connect, TLS, the wait for the first answer, the robots.txt check of the host and the download all count; waits for a Crawl-delay or a free host slot do not. Over the limit: a free too-slow row. (2) The run-level guard: if run seconds x memory x $0.20 per compute unit goes above 10% of what the run has charged, plus the price of the bytes every running download has already received, plus $0.002, no new download starts and the slowest running download is dropped as a free too-slow row; if nothing is running and the run is still over, it stops (stoppedBy: "compute-guard"). The compute of earlier processes of a restarted run counts too. (3) The server must keep sending (30 s without data). Dropped downloads are never charged. If your sources are slow, run fewer files per run or accept that slow ones are skipped.

  • Minimum speed (what the time limit means in practice): a file must arrive, start to finish, within the time its price pays for. MB means MiB (1,048,576 bytes); 1 MiB/s is about 8.4 Mbps.

    File sizePrice512 MB (default): time limit / minimum average speed1,024 MB: time limit / minimum average speed
    1 MB$0.0013.6 s / 0.28 MB/s1.8 s / 0.56 MB/s
    5 MB$0.0013.6 s / 1.39 MB/s1.8 s / 2.78 MB/s
    10 MB$0.0027.2 s / 1.39 MB/s3.6 s / 2.78 MB/s
    30 MB$0.00414.4 s / 2.08 MB/s7.2 s / 4.17 MB/s
    100 MB$0.01139.6 s / 2.53 MB/s19.8 s / 5.05 MB/s
    300 MB$0.031111.6 s / 2.69 MB/s55.8 s / 5.38 MB/s
    500 MB$0.051183.6 s / 2.72 MB/s91.8 s / 5.45 MB/s

    The speeds are the average needed if nothing else took time. Every second spent before the first byte (robots.txt of a new host, connect, TLS, a slow first answer) comes off the limit: with 1 s of such overhead a 5 MB file needs 1.92 MB/s at 512 MB (a 1 MB file: 0.38 MB/s). Small files are limited mostly by the overhead, big files by their throughput (about 2.7 MB/s, roughly 23 Mbps, at 512 MB). The default memory is the cheapest choice for slow sources: doubling the memory halves every time limit.

  • A run stops early (stoppedBy: "unpaid-work-cap") after 200 failed files, 1,000 MB downloaded for files that were not saved, or 10 minutes spent on failed files (downloads still waiting for a server that has not answered count too), so a list of bad links cannot burn compute unpaid. Files you filtered out with Allowed types are not counted as failed.

  • The type check reads the first 4 KB. It cannot tell a ZIP-based format it does not know from a plain ZIP, and an unknown binary is reported as application/octet-stream but still saved. Plain text is typed from the header or the extension.

  • If the same content is downloaded from two URLs without dedupe, both are saved, each with its own key (a number is added when the keys are equal).

  • The public link works for as long as the key-value store exists. Unnamed stores expire after Apify's data-retention period (see Apify's documentation); pick a named store to keep files longer.

FAQ

Does it find files on a web page? No. Give it the file URLs. That keeps it simple and robots.txt-checkable.

Why was my file not charged? Only ok is charged. Check status, errorCode and message.

Can it download from YouTube, Instagram or Google Drive? No. Those hosts are refused on purpose.

Can it save HTML pages? Only when you add text/html to Allowed types; it still does not crawl or render anything.

Does the default run work without setup? Yes. It downloads a public-domain PDF and photo from Wikimedia Commons and a CC BY 4.0 CSV (Aviation Safety Network via FiveThirtyEight, CC BY 4.0) from GitHub, about half a megabyte in total.

How much does it cost to download 1,000 files? $1.00 if each is 5 MB or smaller, plus Apify's start event ($0.00005 at the default memory). Bigger files add $0.001 per started 10 MB above 5 MB: 1,000 files of 30 MB are $4.00. Only saved files are charged.

Does it make a ZIP of all files? No. Each file is stored as its own record with its own public link, so you can fetch, share or delete them one by one.

Can I feed it links from another Actor or a spreadsheet? Yes, as a list of URLs in fileUrls (via the API, n8n or Make, map your link column or dataset field into that list). It does not read another run's dataset by itself.

Can it download from Google Drive, Dropbox share pages or behind a login? Google hosts (including Drive) are refused. Other share pages usually return a web page, which is refused for free as not-a-file; use the direct download link. Nothing behind a login is downloaded.

Where are my files and how long do they stay? In the run's default key-value store, or in the store you picked under Save files in this key-value store. Unnamed stores follow Apify's data-retention period; pick a named store to keep files longer.

Can an AI agent use it? Yes, through the Apify MCP server; see For AI agents (MCP) above.