Apify Actors / Web pages as Markdown, text or HTML, with a browser fallback
Apify ActorWeb pages as Markdown, text or HTML, with a browser fallback
Most pages come back fine from a plain HTTP request. Some answer with a bot check, an empty app shell or a 403, and a fetch tool that stops there leaves an agent guessing. This Actor tries a cheap HTTP request first, retries with Chrome-like headers, and opens headless Chromium only when a page is blocked, needs JavaScript or comes back empty.
You get one row per URL with the content as Markdown, plain text or cleaned HTML, plus the title, author, language and word count. Every row says which step produced the content, and every failed row carries an errorCode, so an agent can tell a dead link from a bot wall and move on. Failed rows cost nothing.
$0.001 per page with content · pay per result, no subscription
Price
| Event | Price | Charged when |
|---|---|---|
page | $0.001 | Once per URL that came back with content. Truncated pages count. |
| Failed URL | $0 | Refused URLs, timeouts, HTTP errors, blocked pages, empty pages and unsupported files, whichever step they reached |
| Example run | Units | Cost |
|---|---|---|
| The input below (1 URL) | 1 × $0.001 | $0.001 |
| 100 pages with content | 100 × $0.001 | $0.10 |
| 1,000 URLs, 950 with content, 50 failed | 950 × $0.001 | $0.95 |
| 10,000 pages with content | 10,000 × $0.001 | $10.00 |
What you get
contentas Markdown, plain text or cleaned HTML, with links and image paths made absolute.fetchedWithandattempts, which show the step that produced the content and how every step ended.title,author,publishedAt,language,wordCountandcharactersnext to the content.errorCodeanderroron failed rows, such asBLOCKED_BY_SITE,JS_REQUIRED,TIMEOUTorUNSUPPORTED_CONTENT_TYPE, free of charge.
Input
Set the run options in the Apify console, or send the same object through the API.
{
"urls": [
"https://example.com/"
],
"outputFormat": "markdown"
}One URL as Markdown. urls takes 1 to 100 lines, and a line without a scheme gets https:// in front. fetchMode can be auto, http or browser, and every mode costs the same $0.001 per page with content.
Output
{
"url": "https://example.com/",
"status": "success",
"errorCode": null,
"error": null,
"httpStatus": 200,
"finalUrl": "https://example.com/",
"fetchedWith": "http",
"attempts": ["http: ok"],
"contentType": "text/html; charset=utf-8",
"format": "markdown",
"extraction": "main-content",
"title": "Example Domain",
"description": null,
"author": null,
"publishedAt": null,
"language": "en",
"content": "This domain is for use in documentation examples without needing permission. This is not a service; avoid relying on it for testing and monitoring purposes.",
"characters": 156,
"wordCount": 25,
"truncated": false,
"elapsedMs": 1829,
"fetchedAt": "2026-11-05T14:57:30.161Z"
}One real row from a run on Apify on 2026-11-05. A page that needed all three steps lists them in order in attempts, for example ["http: HTTP 403 cloudflare", "http-browser-headers: HTTP 403 cloudflare", "browser: ok"], with fetchedWith: "browser".
Run it from your own code
The Actor takes the same input as a JSON body. This call starts a run, waits for it and returns the dataset items.
curl -X POST "https://api.apify.com/v2/acts/zovo-one~web-fetch-fallback/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com/"], "outputFormat": "markdown"}'A sync call waits at most 300 seconds. For longer runs, start a run with POST /v2/acts/zovo-one~web-fetch-fallback/runs, wait for it, then read /v2/datasets/<defaultDatasetId>/items.
Limits
100 URLs per run, 5 MB per page after decompression and 10 redirects per step. Requests go out directly from Apify's servers, with no proxy, and sites that block datacenter addresses end as BLOCKED_BY_SITE, free of charge. It doesn't log in, fill forms, solve captchas or scroll for lazy content. The browser waits up to 5 seconds for the network to go quiet and up to 8 seconds for a bot check to clear itself, within timeoutSecs. PDFs fail with UNSUPPORTED_CONTENT_TYPE and cost nothing. It doesn't read robots.txt, and it refuses localhost, private and reserved address ranges, cloud metadata hosts and URLs with embedded credentials.
Questions
Does a failed page cost anything?
No. Only rows with status: "success" are charged. A 404, a timeout, a bot wall or a PDF costs $0, and the row tells you which one it was.
Will it get past Cloudflare and other bot checks?
Sometimes. The header retry and the headless browser get through some checks, and the browser waits up to 8 seconds for a check to clear itself. It doesn't use proxies or solve captchas, so a site that blocks datacenter addresses ends as BLOCKED_BY_SITE, free of charge.
How do I keep pages small enough for my model's context?
Set maxCharacters. The content is cut there and the row gets truncated: true, while wordCount still counts the words of the whole extracted text. Leaving extractMainContent on also drops menus, footers and sidebars before the cut.
Which fetch mode should my agent use?
Leave it on auto unless you know the sites. http is faster and never starts a browser, but JavaScript-only pages fail with JS_REQUIRED. browser is for sites you know need it every time.
Can I use it as a tool in Claude, Cursor or another MCP client?
Yes. Add https://mcp.apify.com?tools=zovo-one/web-fetch-fallback as a remote MCP server, and the agent sees the Actor's input fields as the tool's arguments. Your browser opens on the first connection so you can sign in to Apify, or you can send your Apify token in an Authorization header instead.
Why do the rows come back in a different order than my URLs?
URLs are fetched in parallel, so rows land as they finish. Match them on url.
Support this work
If this Actor saves you time, you can support the work on GitHub Sponsors. Monthly tiers start at $5, and one-time tiers start at $15. Sponsorship is optional, and the tool works the same without it.
Related tools
Built and maintained by Zovo. Actor on Apify · All Actors.