Blog/Search & RAG
5 min read

Node Unblocker Proxy: Fetch a Blocked Page From Your Agent

Node Unblocker is a proxy you host, so a site that blocks your scraper blocks it too. We ran both on one page and show the call that returned it.

Node Unblocker Proxy: Fetch a Blocked Page From Your Agent

Read a page that blocks your scraper and your proxy, as clean Markdown. Paste this into your agent:

Set up https://monid.ai/SKILL.md, and then use Monid to read https://www.zillow.com/ as markdown, even though a plain request to it gets a 403, and tell me how many home listings are on the page.

One prompt reads a page that refuses plain requests. 1 min setup · 6-16 hrs saved.

You searched for Node Unblocker and found a Node.js proxy you host yourself. If your real problem is a page that returns a 403 to your scraper, that proxy sends the same request from your own address, and the page is still refused. This guide shows what the library does, what happened when we put a blocked page through it, and the one call that did return the page, with the output and the traps we saw on 2026-10-16. It runs through Monid, the OpenRouter for agent tools: one key, one balance, every tool priced per call.

Is there a Node Unblocker API, and what is the easiest way to read a blocked page?

Node Unblocker has no API and no key, because it is an npm package you run on your own server, and the easiest way to read a page that blocks you is Monid. Install it once, add a key, and your agent calls a fetch endpoint with a URL and gets Markdown back as typed JSON.

  • Pay for what you run. A page is billed per call at $0.002533 (Verified 2026-10-16 on the web extraction tools page), and the endpoint's note says failed or blocked requests are not billed. You buy calls as you need them: no monthly plan and no minimum top-up. Discovery and inspection are free; only a run bills.
  • One install, every tool. The same key and the same balance call the page fetcher, a crawler, a search endpoint and every other tool on Monid, so a second job is another call and not another vendor.
  • Lives inside your agent. Install the CLI, add your key, run the prompt above, and the fetcher is there whenever your agent needs it, with no proxy server to deploy. Your agent reads SKILL.md and learns the rest, so setup is about a minute.

At that price, 100 pages cost about $0.25 (Verified 2026-10-16). Which kind of scraping tool fits which job is laid out in web scraping tools: which kind.

How do you fetch a page that blocks your proxy from your agent?

Send the URL to the Markdown scrape endpoint and read the result out of the response. The endpoint is /web/scrape/markdown from the provider context.dev. Its description says JavaScript rendering, anti-bot bypass and residential proxies are handled on the provider's side and included in the price.

RouteWhat you getCost shapeFits
Run Node Unblocker yourselfA proxy that rewrites pages, leaving from your addressYour server and your hoursA network-level block, or a page served inside your app
Rotating proxy pool you rentNew exit addresses for your own scraperRented by volume, plus your codeHigh volume where you keep the parsing
Marketplace scraperOne actor per site, run on a schedulePlan or per runOne known site, run repeatedly
Monid fetch endpointOne page as Markdown plus metadata, typed JSONPer call, buy flexiblyAny URL, on demand, from an agent

Monid fits a page that refuses you because the work is one call and the failed ones are not billed.

For agents

Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:

set up https://monid.ai/SKILL.md

It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.

For humans

npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main

Find the endpoint, then fetch the page

monid discover -q "scrape a page that blocks plain requests to markdown"
monid inspect -p context.dev -e /web/scrape/markdown

Both are free. The schema lists url as the one required field, plus useMainContentOnly, maxAgeMs, waitForMs, country, includeLinks and includeImages. Then the run, which is the only step that bills:

monid run -p context.dev -e /web/scrape/markdown -w \
  --query '{"url": "https://www.zillow.com/", "useMainContentOnly": true}'

The endpoint is a GET, so the input goes in --query. We ran exactly this shape against the Zillow home page: success was true and the call returned 19,347 characters of Markdown. Whichever site you read, follow its robots.txt and terms.

Read the cost

The run bills one unit when the page comes back. Our first call billed 2,533 micro-dollars, which is $0.002533 (Verified 2026-10-16 with monid inspect). That held for the cached copy as well as for the fresh fetch, so a cache hit is not free.

What is Node Unblocker, and can you run it yourself?

Node Unblocker is an open-source Node.js library, published on npm as unblocker, that fetches a remote page for you and rewrites it so links, cookies and relative paths keep working when the page is served from your domain. The registry listed version 2.3.1 under the AGPL-3.0 licence on 2026-10-16. Its README says it started as a web proxy for evading internet censorship and has since become a general-purpose library for proxying and rewriting remote pages.

Yes, you can run it yourself, and for the job it was built for you should. The install is npm install --save unblocker, and it plugs into Express as middleware:

const express = require('express');
const Unblocker = require('unblocker');

const app = express();
app.use(new Unblocker({ prefix: '/proxy/' }));
app.listen(8080);

A request to http://localhost:8080/proxy/https://example.com/ then returns the page. On 2026-10-16 example.com came back with status 200 and 803 bytes.

What the rewriting covers

The README lists three things: "pretty" URLs so relative links resolve, a redirect for root-relative links using the referrer, and cookie paths adjusted to sit under the proxy. That rewriting is the hard part of serving a third-party page inside your own site, and the library does it properly.

What you take on with it

Three costs come with running it yourself:

  • The server. You deploy it, keep it running and patch it. There is nothing hosted behind it.
  • The exit address. Every request leaves from the address of the machine that runs it. On a cloud VM that is a datacentre address, which the next section shows is not enough for a defended site.
  • The licence. AGPL-3.0 reaches software you offer as a service, so read it before the proxy goes into a product.

Does Node Unblocker get past a site that blocks scrapers?

No. A site that refuses your request refuses it through Node Unblocker too, because the request still leaves from your machine. Here is what we measured on 2026-10-16, from one machine, with the same target.

Request pathHTTP statusSizeWhat the page said
curl with a browser user agent, to example.com200803 bytes"Example Domain"
Through Node Unblocker, example.com200803 bytes"Example Domain"
curl with a browser user agent, to the Zillow home page4035,776 bytes"Access to this page has been denied"
Through Node Unblocker, the Zillow home page4036,000 bytes"Access to this page has been denied"
Monid /web/scrape/markdown, the Zillow home page20019,347 charactersListings, prices and the site navigation

The first rows show the library works: a friendly page passes through unchanged. The Zillow rows are the point. The 403 body carries a PerimeterX bot-detection script, and putting a Node proxy between your code and that page changed only the size of the refusal by 224 bytes.

What the README says it cannot do

The README is consistent with this. It states that OAuth login forms and anything that uses postMessage are not likely to work out of the box, and that more advanced sites such as Roblox, Discord, YouTube and Instagram do not currently work, with no timeframe given. Those pages assemble themselves in the browser from many requests, some to origins the proxy never sees.

If the problem is a network-level block, such as a school or office that blocks a domain, a Node Unblocker you host somewhere unblocked solves it. If the problem is a defended site that returns a 403 to automated requests, the fix is an exit address and a browser that the site accepts, and datacenter proxies versus residential covers the address types.

What does the page look like, and what can you build with it?

The response is the page as Markdown plus a metadata object.

The layers of the response

The top level carries success, markdown, contentLength, url, metadata, cache_metadata, finalDOMState and a request_id. Inside metadata we saw sourceUrl, finalUrl, title, description, language, canonicalUrl, siteName, favicon, robots, openGraph, headings and additionalMeta. The headings list gives each heading with its level and its text, so you get the page outline without parsing the Markdown back.

The Markdown itself held the headline "Rentals. Homes. Agents. Loans." and a carousel of eight listings, each with a price, bedrooms, bathrooms, square footage, a street address, an MLS ID, the listing brokerage and a link to the listing page. The rest of the page was site links: cities, rental searches, mortgage rates by state and browse-by-state lists.

What you can build with it

  • A page-reader tool for your agent. Give the agent the endpoint and it can read any URL a user pastes, including the ones that refuse plain requests. For a whole documentation site, crawl4ai: when to run your own crawler shows the crawl route into a retrieval index.
  • A listing watcher. Fetch a listings page on a schedule, parse the price and address pairs out of the Markdown and diff them between runs.

What goes wrong when you fetch blocked pages?

The page can come back, and still be older than you think, from somewhere you did not expect, or bigger than you asked for. Three things showed up in our runs.

Why is the page older than I asked for?

Our first call returned cache_metadata with status hit and age_ms 206,744,257, which is about 57 hours. The schema says the default for maxAgeMs is one day, and the copy we got was older than that. Set maxAgeMs to 0 when freshness matters. The second call did that and returned status miss and age_ms 0. Both calls billed the same, so a fresh fetch costs no more than a cached one.

Why did the same URL return different listings?

The first call showed "Trending Homes in Springfield, MA" and the second "Trending Homes in Ashburn, VA", both from the same URL with the same parameters. The carousel is personalised to the location the fetch came from, so the listings are a function of the exit location as well as of the URL. If you compare pages over time, pass country and store the fetch date with every document, and do not treat the home page carousel as one stable list.

Why is main-content-only still full of links?

We set useMainContentOnly to true, and the Markdown still ended with the full link lists for cities, rentals, mortgage rates and browse-by-state. The option drops headers, footers and sidebars when it can detect them, which is not the same as clean. The page was 19,318 characters on the fresh call, and the listings were a small part of it. Cut the Markdown before the footer lists before you embed it.

Which endpoint should I use for which job?

Use the Markdown endpoint for a page you want to read, the HTML endpoint when you want to keep your own selectors (the split is worked through in Python web scraping without a scraper), and the crawl endpoint for a whole section of a site.

EndpointWhat it doesInputBillingPrice (Verified 2026-10-16)
context.dev/web/scrape/markdownOne URL to Markdown plus metadataurl, useMainContentOnly, maxAgeMs, waitForMs, countryPer call, failures not billed$0.002533
context.dev/web/scrape/htmlOne URL to rendered HTMLurl, maxAgeMs, waitForMs, countryPer call, failures not billed$0.002533
context.dev/web/crawlFollows links, one Markdown document per pageurl, maxPages, maxDepth, urlRegexPer page scraped, with a hold sized by maxPages$0.002533

Prices Verified 2026-10-16 with monid inspect; current prices are on monid.ai/tools. We ran the Markdown endpoint and inspected the other two. The crawl endpoint holds the price of maxPages while it runs, 100 by default, so set maxPages to the number you need before you start.

When is another route a better fit?

You are getting around a network-level block. A school, office or country blocks a domain, and a Node Unblocker on a server you control that is not blocked fixes it. This is the job the library was built for, and a hosted fetch endpoint would be a worse tool.

You need to serve a third-party page inside your own app. The URL, cookie and relative-link rewriting is the hard part, and Node Unblocker does it. A Markdown endpoint returns text, not a page that still works.

You have a CORS problem. A browser refusing a cross-origin request is a policy in the browser, and a small proxy on your own origin resolves it.

Your targets are friendly and your volume is large. If you read sites that let your address in, there is no block to buy your way out of, and a fetcher you run costs only your server.

You need the exit address to be yours. For sessions bound to one IP, or traffic that must stay inside your network, a proxy you operate is the route.

And the disclosure: we resell the fetch endpoint. The test worth running whoever you buy from is the one in this post, the same blocked URL through your proxy and through the candidate, with status and size side by side.

Conclusion

The quickest way to read a page that blocks your scraper is one call through Monid: $0.002533 a page (Verified 2026-10-16), one key for this and every other tool, about a minute to set up and ready inside your agent whenever you need it. Node Unblocker is a good proxy for the job it was built for; Monid supplies the exit address, the rendering and the conversion for the page that refuses you.

Two things matter more than the choice. A proxy you host changes the route, not the address, so a 403 from a defended site stays a 403. And a page that came back is not necessarily current: our first call was about 57 hours old, so set maxAgeMs when the date matters.

How we estimated the time saved: finding out why a scraper is blocked and trying a self-hosted proxy is roughly 2 to 4 hours, setting up and testing a rotating proxy source and a rendering browser is 3 to 8 hours, and the first month of upkeep is 1 to 4 hours. That is 6 to 16 hours. The 1 minute is the install, key and first call once you already have a Monid key.

Free next step: run monid discover -q "scrape a page that blocks plain requests" and monid inspect -p context.dev -e /web/scrape/markdown, then fetch one URL that returns a 403 to your own code and compare the status with what your proxy gets. Start at monid.ai.

FAQ

What is Node Unblocker?

Node Unblocker is an open-source Node.js proxy library, published on npm as unblocker, that fetches a remote page and rewrites its links and cookies so it works from your own domain. It started as a tool for evading network-level censorship.

Does Node Unblocker work on sites that block scrapers?

No. In our test on 2026-10-16 the Zillow home page returned a 403 "Access to this page has been denied" page directly and the same 403 through Node Unblocker, because the request still leaves from your own address. A fetch endpoint with its own exit addresses returned the page with status 200.

Is Node Unblocker free?

Yes to install: the package is open source under AGPL-3.0, so it costs nothing, and you pay for the server that runs it. If you want a page fetched for you instead, through Monid a page is $0.002533 per call (Verified 2026-10-16), with no monthly plan and no minimum.

How do you use Node Unblocker with Express?

Install it with npm install --save unblocker, then call app.use(new Unblocker({ prefix: '/proxy/' })) before your other routes and request /proxy/<full URL>. It returned example.com with status 200 in our test.

What is the difference between an unblocker and a web unlocker?

A Node-style unblocker is a proxy you host that rewrites pages so they work inside your site. A web unlocker is a hosted service that supplies the exit addresses, the browser rendering and the challenge handling. The first changes how a page behaves in your app, and the second changes whether you get the page at all.

Published August 2026.

node unblockernode unblocker proxyweb proxyblocked scraperweb extraction