PINGDOM_CHECK

#ExtractSummit2026 The world's largest web scraping conference returns. Austin Oct 7–8 · Dublin Nov 10–11

Register now
Data Services
Login
Try Zyte APIContact Sales
  • Unblocking and Extraction

    Zyte API

    The ultimate API for web scraping. Avoid website bans and access a headless browser or AI Parsing

    Ban Handling

    Headless Browser

    AI Extraction

    SERP

    Enterprise

    DocumentationSupport

    Hosting and Deployment

    Scrapy Cloud

    Run, monitor, and control your Scrapy spiders however you want to.

    Coding Agent Add-Ons

    Agentic Web Data

    Plugins that give coding agents the context to build production Scrapy projects. Starts with Claude Code.

  • Data Services
  • Zyte API

    Zyte Data

    Scrapy Cloud

  • Browse

    • BlogArticles, podcasts, videos
    • Case studiesCustomer outcomes
    • White papersIn-depth reports
    • DocumentationGuides & API reference
    • EventsConferences, webinars, recordings

    Subscribe

    • NewsletterSwiftly delivered
    • Join our community2,000+ web scraping engineers
  • Product and E-commerce

    From e-commerce and online marketplaces

    Data for AI

    Collect and structure web data to feed AI

    Job Posting

    From job boards and recruitment websites

    Real Estate

    From Listings portals and specialist websites

    News and Article

    From online publishers and news websites

    Search

    Search engine results page data (SERP)

    Social Media

    From social media platforms online

  • Meet Zyte

    Our story, people and values

    Contact us

    Get in touch

    Support

    Knowledge base and raise support tickets

    Terms and Policies

    Accept our terms and policies

    Open Source

    Our open source projects and contributions

    Web Data Compliance

    Guidelines and resources for compliant web data collection

    Join the team building the future of web data
    We're Hiring
    Trust Center
    Security, compliance & certifications
Login
Try Zyte APIContact Sales
All articles
AI71, 71 articles
Data quality15, 15 articles
Developer interest59, 59 articles
Integration2, 2 articles
Open-source50, 50 articles
Proxies35, 35 articles
Scraping practice35, 35 articles
Scraping strategy48, 48 articles
Search results4, 4 articles
Web data75, 75 articles
Web scraping APIs49, 49 articles
Scrapy47, 47 articles
Scrapy Cloud26, 26 articles
Web Scraping Copilot11, 11 articles
Zyte API70, 70 articles
AI & Machine Learning3, 3 articles
Automotive3, 3 articles
E-commerce & retail35, 35 articles
Entertainment & Streaming2, 2 articles
Financial Services8, 8 articles
Government2, 2 articles
Market Research & Intelligence7, 7 articles
Media & publishing11, 11 articles
Real Estate2, 2 articles
Recruitment & HR3, 3 articles
Transportation & Logistics2, 2 articles
Travel & hospitality3, 3 articles
iPaaS2, 2 articles
Large language model29, 29 articles
MCP3, 3 articles
Python110, 110 articles
Scraping at Scale7, 7 articles
Scraping Fundamentals11, 11 articles
Web Scraping Industry Report20, 20 articles

Appearance

Discord Community
BlogWebFetch is ‘lossy’ by design: give your coding agent a better fetch in one command
ArticleTutorial / How-to

WebFetch is ‘lossy’ by design: give your coding agent a better fetch in one command

Your coding agent built-in webfetch tool is not the best and it's hampering your research and coding workflows, fix it with one CLI tool and never face blocks again.

Ayan Pahwa · Developer Advocate

August 25, 2026

WebFetch is ‘lossy’ by design: give your coding agent a better fetch in one command

Your agent reports that a product page does not list a price. You open the same page in a browser, and the price is right there. Nothing errored, and nothing warned you. The agent was not being careless either: it answered honestly about the text it was handed, and that text was not the page you thought it had read.
That gap between what a page contains and what an agent receives is worth understanding before you reach for a bigger model or a more careful prompt. Neither one can recover information that never arrived. The fix is a different fetcher, and adding one takes a single command.

Why built in fetch tool is lossy?

The built-in fetch tool in Claude Code is documented plainly, and the documentation is more candid than most developers expect. According to Anthropic's tools reference, WebFetch "fetches the page, converts the response to Markdown when the server returns HTML, and runs the prompt against the content using a small, fast model. For most fetches, Claude receives that model's answer, not the raw page." The same page notes that the conversion step "is not configurable."
Then comes the sentence that explains the missing price: "This makes WebFetch lossy by design."
That sentence describes a deliberate design choice rather than a bug, and it is a sensible choice for what the tool is built to do. Compressing a page into an answer works well when an answer is what you wanted. It works badly when you need the page.

image

The same section lists other behaviors that shape what reaches your agent. Large pages "are truncated to a fixed character limit before processing." Responses "are cached for 15 minutes, so repeated fetches of the same URL return quickly." A redirect to a different host comes back as a description of the redirect rather than being followed, which costs a second call. The tool also identifies itself, sending a User-Agent header that begins with Claude-User.

Why is built-in ‘fetch’ letting you down?

An error is cheap to deal with, because your agent sees it, tells you, and you go fix something. A thin result costs far more, because it looks exactly like a complete one and nothing in the response hints otherwise.
Anthropic's documentation names this directly: "The extraction prompt determines what reaches Claude, so a result that says a page doesn't mention something may only mean the prompt didn't ask about it." An agent working from a partial extraction has no way to tell a page that lacks a price from a page whose price did not survive the trip. It reasons sensibly from what it received, and what it received was already missing the answer.
The same reference documents a sharper version of the problem that has since been fixed: before version 2.1.212, "the API error text could reach Claude as if it were the extracted page content." An agent reading an error message as though it were a web page shows the problem without any ambiguity. Keep that picture in mind, because it is what a quiet degradation looks like from the agent's side.

Anthropic's suggested fallback is to : Shell Out

The documentation does not leave you stuck. Its advice when a fetch comes back thin is to "ask Claude to fetch again with a more specific prompt, or use curl via Bash for the unprocessed page."
That second option is the interesting one, because it concedes a useful point: when you need the actual page, the answer is to run a command. Your agent almost certainly has a shell tool already, so nothing has to be rebuilt to close this gap. The only open question is which command you point it at, and curl is the simplest option available rather than the most capable one.

The whole integration is one command

Zyte API has an official command-line client on PyPI, zyte-api, maintained by Zyte. Installing it is the entire integration:

1pip install zyte-api
2export ZYTE_API_KEY="your-api-key"
Copy

From there, a plain text file of URLs is valid input, and one command reads it:

1zyte-api urls.txt --output results.jsonl
Copy

Asking for fields instead of markup

Raw HTML beats a lossy summary, though it is still a large amount of markup for an agent to read and parse. Every token of it competes for context with the actual task. A JSON Lines input file lets you ask for something more useful, using Zyte API's automatic extraction:

1{"url": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html", "product": true}
Copy

Worth knowing before you copy that line: the JSON Lines path sends exactly the fields you write, so browserHtml is not added for you the way it is with a text file. Ban avoidance is part of the service rather than a flag you set per request, so that still applies here. If you also want the page rendered in a browser first, put "browserHtml": true in the record alongside "product": true.
Run the command against that file and the response contains named fields rather than markup:

1{
2  "name": "A Light in the Attic",
3  "price": "51.77",
4  "currency": "GBP",
5  "currencyRaw": "£",
6  "availability": "InStock",
7  "sku": "a897fe39b1053632"
8}
Copy

Most of the parsing work has gone. The price arrives as a decimal string, with the currency reported separately as a code and the raw symbol preserved alongside it. Nothing in your pipeline has to dig £51.77 out of a paragraph of markup, though you will still cast the string before doing arithmetic. Availability arrives as a normalized value instead of whatever markup the page happened to use to express it.
None of that requires a selector, so it is far less likely to break when a site redesigns its templates, and that is the failure that quietly consumes maintenance time on hand-written extraction code. Extraction is a model rather than a fixed rule, so every record also carries a probability score you can threshold on when accuracy matters more than coverage.

image

What the better fetch costs

Worth being straight about the trade, because none of this is free the way curl is. Zyte API's pricing documentation says the target website and the request type, HTTP or browser, "determine the request tier and base cost," and that there are five tiers for each of the two request types. So the text-file path, which switches browser rendering on for you, is opting you into the browser side of that pricing by default. Automatic extraction adds "$0.0004-$0.0016 per data type" on top, before volume discounts. Unsuccessful and rate-limited responses are not charged, so a fetch that fails does not bill.
The practical version: point this at the pages that need it rather than at everything. Run the numbers in Zyte's cost estimator before you wrap a loop around the command.

Wiring it into your agent

The wiring is one line. That is the practical advantage of a command-line tool over a custom integration: your agent already knows how to run commands. The only remaining step is telling it that this particular command exists and is worth reaching for.
One line in your project instructions covers it: ex in CLAUDE.md or AGENTS.md file add:

1When a fetched page comes back thin or incomplete, refetch it with
2`zyte-api urls.txt --output results.jsonl` and work from that result instead.
Copy

Keep that instruction short, and resist the urge to explain the whole API inside it. As we argued in the best agent skill is the one that says the least, an agent instruction competes for attention with everything else in context. The version that earns its place is the one that says what to run and when.
Because this is an ordinary command, nothing here is specific to one vendor's agent. Any harness that can run a shell command can use it, which is a useful property while the tooling in this space keeps changing every few months. The minimal harness we built in an earlier post would take this addition without a single structural change.

When you should build a custom tool instead

A command-line client is the fastest path, though it is not always the right one. If you want the fetch to appear as a first-class tool in your agent's tool list, a custom tool is the better shape: a typed schema, its own permission rules, and results that never touch the filesystem. I walked through building exactly that in part four of the harness engineering series, including the tool definition and the handler behind it.
The honest guidance is to start with the command, because it takes two minutes and answers the question of whether better fetching solves your problem at all. Reach for a custom tool once you know the answer is yes and you want the ergonomics.

Try it yourself

Take a page your agent has struggled with, put its URL in a text file, and run it through the client. If the result looks nothing like what your agent has been reporting back to you, you have found the gap. It was never a prompting problem.
Signing up for Zyte API gives you a standard plan with no commitment and $5 of free credit for the first billing month. The documentation covers the extraction types beyond products, including articles, job postings, and search results.

Try Zyte API

Build your first scraper in minutes

Free trial, no credit card. From a single request to production in an afternoon.

Get started

Ayan Pahwa

Developer Advocate

Ayan is a developer advocate at Zyte. Ayan writes hands-on, personal-project-driven content about applying AI agents and LLMs to real scraping problems — his "Harness Engineering" series explains what an agent harness is and how to build one for data extraction, and he documents…

  • X (Twitter)
  • LinkedIn
  • GitHub
  • Website
More from this author

In this article

  • Why built in fetch tool is lossy?
  • *Why is built-in ‘fetch’ letting you down?*
  • Anthropic's suggested fallback is to : Shell Out
  • The whole integration is one command
  • Asking for fields instead of markup
  • What the better fetch costs
  • Wiring it into your agent
  • When you should build a custom tool instead
  • Try it yourself

Follow

Get the latest

Zyte and the data web in your inbox — or wherever you already are.

Subscribe

Or follow elsewhere

The Community · Newsletter

The best of Zyte and the data web, in your inbox.

One curated edition — new articles, product updates, and the stories shaping the data web. No noise.

Services

Zyte Data

Fully managed web data extraction, delivered to your spec.

Explore Zyte Data

Web Scraping API

Zyte API

Scrape any website at scale with automatic proxy rotation and ban handling.

Sign Up

Developers

Zyte Developers

Docs, tools, and a community to help you build and scale scrapers.

Join Us
    • Zyte API
    • Ban Handling
    • AI Extraction
    • SERP
    • Enterprise
    • Scrapy Cloud
    • Agentic Web Data
    • Pricing
    • Product & E-commerce
    • Data for AI
    • Job Posting
    • Real Estate
    • News & Articles
    • Search
    • Social Media
    • Blog
    • Learn
    • Case Studies
    • Webinars
    • White Papers
    • Join our community
    • Documentation
    • Meet Zyte
    • Contact us
    • Jobs
    • Support
    • Terms and Policies
    • Trust Center
    • Do not sell
    • Cookie settings
    • Web Data Compliance
    • Open Source
    • What is Web Scraping
    • Web Scraping in Python: Ultimate Guide
    • Stop getting blocked, start scraping
  • Logo EWDCILogo Most Loved WorkplaceLogo Job TogetherISO 27001 SealMedal Leader Europe Winter 2025Fastest Implementation Winter 2025Logo Leader Winter 2025Grid Leader Spring 2025Grid Leader Summer 2025Leader Fall 2025Leader Winter 2026
    XFacebookInstagramYouTubeLinkedInDiscord

    © Zyte Group Limited 2026