ZooData - The data layer for AI agents
by•
ZooData turns any URL into agent-ready JSON, so AI agents can work with structured data instead of raw HTML or bloated markdown. Use ~75% fewer LLM tokens, pay only for the fields you use, and skip extra extraction credits.Beyond extraction, ZooData gives agents pre-analyzed e-commerce intelligence — competitor, market, traffic, and consumer insights — live for Amazon and TikTok. API, CLI, and MCP server included. Start with 1,000 free credits, no card required.


Replies
ZooClaw
Hi PH 👋,
I'm Ning from ZooData.
Quick context on why we built this.
If you've built anything with agents, you know the data problem. You scrape a page — with browser-use, Playwright, whatever — and what comes back is raw HTML or "clean" markdown. Either way it's stuffed with nav bars, footers, ads, and boilerplate. For a human reading it, fine. For an LLM, you're burning thousands of tokens on stuff the model has to filter out before it can do anything useful. At scale that's real money, and most of it is waste.
Markdown is the usual fix. But markdown was built for humans to read, not for an agent that has to act on the data. Different reader, different format — an agent doesn't need prose, it needs structure.
ZooData does the extraction step right:
Any URL → structured JSON. No schema to define, no per-site parsers, no selector glue to maintain.
~75% fewer tokens than raw markdown on the same page — roughly 1/5 the cost of other extractors. And you only pay for the fields you actually use; the extraction itself doesn't burn credits.
API, CLI, and MCP server, so it drops into your agent stack without rewriting anything.
Pre-analyzed e-commerce platform intelligence — competitor, market, traffic, and consumer signals your agent can query directly, instead of scraping and stitching it together itself. More platforms coming.
We believe the next bottleneck for AI agents won't be how smart the models get — it will be the quality of the data they rely on.
As AI-generated content floods the web, agents need data that's clean, structured, and verifiable to make reliable decisions. That's the layer we're building, and it compounds: every page we process makes the next request cheaper, faster, and more trustworthy.
ZooData is the foundation the rest of it runs on — we launched ZooClaw (agents for individuals) here not long ago, and ZooWork (the enterprise version) is coming soon.
1,000 free credits, no card. Just tell your agent:
and you're off.
Would love your feedback. And I'm curious — what's the messiest site you've ever had to scrape? 🙏
@ninghu This is a real pain point. HTML to markdown sounds clean until you realize the model is still reading cookie banners, nav links, footer junk, and six versions of the same product title
The no schema JSON angle is interesting. I’d be curious how ZooData handles pages where the useful data is ambiguous, like marketplaces with sponsored listings, variant pricing, hidden pagination, or content that only appears after interaction. The messiest scraping targets are usually the ones that look simple until every page has a slightly different idea of what a “product” is.
ZooData
@ninghu @vahid_davoudi That's a professional list — one by one:
Sponsored listings: on the e-commerce intelligence side, organic-vs-sponsored is a typed distinction — organic results and the various sponsored placements are labeled separately in the data, so ads never blend into organic data masquerading as market signal.
Variant pricing: variants are first-class — each carries its own SKU, options, price, and availability; there's no "one product, one price" assumption. And when a page displays a price that's inherently ambiguous (an asterisked promo like "$1*"), that raw state is exactly what we return — ambiguity is preserved verbatim, never flattened by a guess.
Hidden pagination: listing extractions carry a next_url field — the next-page (or "load more") link is extracted as data and handed to your agent. Whether and how deep to page is its decision, each call flat-priced — depth belongs to you, not to a black box of ours. Interaction-gated content goes through the interactive variant: an explicit action sequence (click / scroll / wait), executed before extraction.
As for "every page has its own idea of what a product is" — exactly, and that's our whole philosophy: structure what's unambiguous; preserve genuine ambiguity verbatim for you to judge; degrade honestly when a page defeats the type (absent fields, never invented values). Ambiguity is a property of the page — our job is to relay it faithfully, not to pretend it isn't there.
@ninghu @kyle_dong Thanks Kyle, this is a strong answer. I really like the philosophy of preserving ambiguity instead of hiding it behind guessed fields.The next_url approach and explicit action sequence for interaction-gated content also make sense. That feels much more useful for agents than pretending messy pages are clean.
ZooData
@ninghu @vahid_davoudi Thanks! The principle in one line: messiness belongs to the page; honesty belongs to the API. Put it to the test — and if you find an exception, you know where we are.
ZooData
@grrigore Thanks for flagging — it's not English-only by design; the open-web extraction is language-agnostic. One thing worth knowing: when we encounter a brand-new page type, the first extraction takes extra time (the system first works out the structure for that type of page — after that, similar pages are fast). Please give it another try in a bit; if you still get nothing back, send us the two URLs (here or at support@zoodata.ai) and we'll confirm what's going on — and report back.
@kyle_dong Yes, it works now. It might be helpful to share that explanation with the user as well. Is there a way to automatically scrape "outgoing_links"?
ZooData
@grrigore Great question! Two cases:
① Entity-style pages — outgoing links are already included by default. If the page is about one specific named thing (think a HuggingFace model page, an IMDB movie page, a Goodreads book page — one subject, structured facts around it), the extracted JSON already carries the page's outgoing links, no extra parameters needed.
② Other page types — a dedicated endpoint exists, just not public yet. We've built a dedicated outgoing-links capability internally but haven't opened it up. So: try the default output on your actual pages first. If it covers you, great; if it doesn't, tell us your page types and use case — your scenario is exactly the push we need to release it. Find us here or at support@zoodata.ai.
curious how this holds up against anti-bot layers - a lot of the messiest sites to scrape aren't messy because of markup, they're messy because they actively try to block automated requests. does the per-field pricing still apply if a site just serves you a captcha wall instead of html, or is that a separate failure case
ZooData
@omri_ben_shoham1 Fair question, straight answer: a captcha wall / block = a failure case, not billed — credits are only consumed when a call successfully returns data, and the status code in the response is the upstream's real one, so a block is never disguised as a success. The anti-bot arms race is our infrastructure's job (rendering, retries, network diversity), but we won't claim 100% — throw your nastiest site at it; if it fails, it costs you nothing.
Great launch! The token math is the part that really matters, at least for agents. Paying to filter boilerplate out of 'clean' markdown is a tax you don't price in until the bill shows up! Wondering - when a site quietly ships a layout change or runs an A/B test, does that learned template keep mapping to the old fields and hand back a confidently wrong value?
ZooData
@artstavenka1 This is the question to ask any extraction system — "fast but wrong" is far scarier than "slow." Our defense: templates are never trusted unconditionally; every request is validated. Extraction output must pass core-field and type checks, and the moment a page stops matching expectations (missing/abnormal core fields), that request auto-escalates to full model extraction — the same slow path a brand-new page type takes. In other words, the default failure mode of a layout change is degrading to "slower but correct," not "fast but confidently wrong."
And an honest caveat: if an A/B variant happens to yield a value that's type-valid but semantically wrong, no extraction system can rule that out 100%. We run continuous quality evals against live pages to catch that kind of drift — and if you ever hit a confidently-wrong value in the wild, send it to support@zoodata.ai. We treat those as bugs, not noise.
the field-level trust discussion above is the real meat of this thread. one I didn't see covered: what happens on a listing/search-results page that needs pagination or infinite scroll to surface everything - does a single call return just what's in the initial DOM, or does ZooData drive the scroll/pagination itself to assemble the full result set before handing back JSON?
ZooData
@galdayan One call = one rendered page-view — we deliberately don't drive scroll/pagination behind a flat price (that's a cost black box, against everything in this thread). For full result sets: infinite scroll → the interactive variant (you pass explicit scroll/click/wait actions, hard-capped cumulative time, bounded cost); classic pagination → your agent loops over page URLs, flat price each, linear spend. Your agent owns the depth decision; we keep each unit deterministic.
@kyle_dong That's a clean split - keeps the flat-price unit honest instead of hiding variable cost inside it. Makes sense that the agent should own the depth decision rather than you guessing at it server-side. Good answer, thanks for walking through both paths.
ZooData
@galdayan Thanks! You summed it up better than we did: primitives stay honest, orchestration belongs to the agent. We keep the first half true — the second half is your stage. Come back and show us what you build with it.
@kyle_dong will do, bookmarking this one to try once I've got a real scrape target to point it at.
The data-quality point is the right one, most agent tools skip straight past it to the model.
One thing I'd add from the support side, where we build agents. Clean JSON fixes the token cost, but it quietly adds a different risk. Raw HTML looks messy so you distrust it. A structured field looks authoritative even when the extractor grabbed the wrong element, or the value went stale between the scrape and the moment the agent acts on it. For an agent that only reads, fine. For one that acts on the field, answers a customer or changes a price, a confidently wrong value is worse than a missing one, because nothing tells it to stop.
So the question, does ZooData give the agent anything per field, a confidence score or a freshness timestamp, or is it flat JSON it has to trust fully? On live Amazon/TikTok data I'd expect the real failures to sit there, not in the extraction.
ZooData
@jernej_jan_kocica Good question — and you've split it into the two failures that actually matter: extraction correctness (did we grab the right element) and freshness (has it gone stale before the agent acts). Let me take both honestly.
Confidence (extraction side): no, we don't expose a per-field confidence score today — it's on the roadmap. And your framing is exactly the spec for it: for an acting agent, "a confidently wrong value with nothing telling it to stop" is the failure worth engineering against. A missing value fails safe; a wrong one doesn't. That's the signal we want to give the agent.
Freshness (the side you'd bet the real failures sit on): this is the part we've actually designed hard around, so I can be concrete —
scrape/realtime endpoints force a live fetch on every call. No cache, ever. There's no gap between capture and read — the value is fresh at the moment the agent asks.
analytics/commerce endpoints run on a daily cycle, so every value is explicitly time-bounded rather than pretending to be real-time — the agent knows exactly how old it is.
So interestingly, the live Amazon/TikTok data you flagged as the danger zone is the part we deliberately don't cache — the open gap you've correctly found is extraction-confidence, not staleness. Since you build support agents that act on fields, I'd genuinely like to design that confidence signal with input from your seat rather than guess at it. Happy to swap notes.
@kyle_dong Fair. If freshness is a live fetch with no cache, then that gap is smaller than I guessed. Good.
On the confidence signal, one thing from acting on this data every day. A 0-1 score is the obvious shape but it's the wrong one for an agent that acts, a number gets rubber-stamped, 0.82 means nothing at the moment it has to decide. What you actually want is closer to a boolean per field: was this value read from a labeled source (a data attribute, schema.org, an obvious price node), or was it inferred because something looked like a price. Sourced, act on it. Inferred, never act, only surface for a human. The dangerous field is always the inferred one that came out looking clean.
And keep it per field, not per page. The same page can have a solid title and a guessed price, one score for the whole extraction hides exactly the field that will bite.
Happy to swap notes on it.
ZooData
@jernej_jan_kocica This one's getting framed — you've just articulated the right shape for the confidence problem. Fully agree: a float invites a threshold; a source boolean invites a decision. The destiny of every 0.82 is to become > 0.8 → pass on day one and never be looked at again.
Your sourced/inferred split happens to run with the grain of our architecture: because extraction is deterministic, every value has a concrete origin in the page — which node, what kind of labeling it was read from, is knowable inside the system. Exposing that origin per field is an engineering problem, not a research problem — it's exactly where our quality work is heading, and your comment describes the API shape more crisply than our internal notes do.
On per-field vs per-page — that's already how we behave: on the same page, the title can come back as a clean string while the price, if the page itself doesn't show a clean number ("Free", "Contact for price", an asterisked promo), comes back as the page's own text — or null if it can't be read at all. Each field degrades on its own: one suspect field doesn't sink the page, and a good-looking page doesn't cover for the field that's off.
Taking you up on "swap notes" — support@zoodata.ai anytime, or right here in this thread. Feedback like this is worth more than the upvotes.
@kyle_dong The origin being knowable already, because extraction is deterministic, that's the part I didn't have. Most systems can't tell you where a value came from after the fact, so that's a real advantage.
One thing I'd add from acting on fields on the support side. Sourced-vs-inferred catches "did we read a labeled node". It doesn't catch "did we read the right one" when there is more than one.
Concrete: a customer has two open orders. We pull an order number and a tracking link, both clean strings, both straight from labeled fields, sourced = true on all of it. And it's the wrong order. Same on a product page, compare-at price and sale price are both clean numbers in labeled nodes. Read the strikethrough one and you are confidently wrong with sourced = true.
So for an agent that acts I think you want two bits, not one. Was it read from a labeled source, and was that source unambiguous, one plausible node, one entity it belongs to. The first you have. The second is where the confidently-wrong values actually sit for us.
Happy to swap notes on it, we've been chewing on the same thing…
NexaSDK for Mobile
Been testing this for a few weeks with my research agent.
The token savings are real: product pages that used to eat half the context window now come back as compact JSON. My LLM bill noticed before I did. Congrats on the launch! 🎉
ZooData
@power_valsha Weeks of real usage before a comment — that's the feedback that actually means something. Thank you. The context-window savings compounding into real bill savings is exactly the problem we set out to kill. Would love to hear what you're building with it.
CapCut AI Suite
Congrats on the launch!
Clean JSON by default is such an obvious idea in hindsight. I can't believe I've been feeding my agents markdown soup this whole time 😅
ZooData
@lavana_cricko Haha, that's literally how this started — we got fed up feeding our own agents markdown soup 😅 The loop was always: fetch → clean → write parsers → page changes → everything breaks. The realization: agents never wanted "text that reads like a webpage," they wanted fields they can act on. That's ZooData. Treat your agents to the 1,000 free credits — they deserve better than soup!
@Kyle Dong that's the right answer honestly, "we don't disguise a block as a success" is the thing that actually matters, most tools I've tried just eat the failure silently and you don't find out until your data looks wrong three steps downstream. does the response include which failure mode it hit, like captcha vs rate limit vs structure change, or is it just a generic fail code?
ZooData
@omri_ben_shoham1 Finer than a generic fail code — but honestly, not a full forensic report either. The design is neutral classified codes + real status codes:
- Blocked / access denied (captcha walls fall here) → an access-denied class error, with the target's real HTTP status in meta.statusCode — never one we made up;
- Rate limiting on our side → you get an explicit 429 with X-RateLimit headers before any work runs — and nothing ran, so nothing's billed;
- Structure change → that one's actually not an error: the page is still there and readable, so markdown comes back as normal — only the structured json goes absent or degraded. You get an honest less, never a silent wrong. Which loops right back into the field-trust discussion above.
As for why we don't put finer anti-bot attribution (exactly whose wall, which signal) in the response: two reasons. One, those internal signals change shape and name — letting you integrate against them is handing you a landmine. Two, frankly, precise block-detection details published in an API mostly benefit the wrong audience. We watch the full attribution on our internal dashboards — its job is for us to go fix things, not for you to triage.
What your agent actually needs collapses to three lanes: retryable (transient upstream) / don't-retry (access refused) / content-ok-but-structure-degraded. All three are distinguishable from the response.
Mom Clock
Hey Product Hunt! 👋
I am very happy to hunt ZooData today.
If you’ve spent any time building AI agents, you already know the massive pain point they are solving: raw HTML and heavy markdown burn through LLM tokens like crazy, and maintaining custom scrapers is a constant headache.
Personally, what impressed me is how effortlessly it turns any URL into clean, structured JSON—saving up to 75% on tokens. It’s built specifically for the agent era (with an MCP server right out of the box), meaning you only pay for the data fields you actually use instead of bloated prose.
Huge congrats to Ning and the team on the launch! Please give them your support if you find the product useful, test out their 1,000 free credits, and drop your feedback in the comments below!
ZooData
@justin2025 Thanks for the amazing hunt! 🙌
You nailed it — agents don't need prose, they need fields. Any URL in, clean typed JSON out, plus an MCP server out of the box so Claude/Cursor can pull live Amazon & TikTok Shop data as native tools.
Grab the 1,000 free credits and tell us what breaks — I'll be in the comments all day!