ZooData - The data layer for AI agents

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.

Add a comment

Replies

Best

data layer is the real bottleneck for agents rn 🙌 clean json instead of raw html is exactly it. nice one!

 Thanks! Same read here: models level up every six months, but if the data feeding them doesn't get cleaner, the agent's ceiling stays stuck at the data layer. 1,000 free credits are ready — put your agent on it and judge for yourself whether the bottleneck actually loosens.

Boundary hydration against the known key set is exactly the fix, and the bonus is our static types stop lying: once every key is present the declared shape and the runtime object finally agree. One thing that bites later though, if you add a field to a page_type down the road my hydration set silently goes stale and I'm back to drift with no signal. So whatever field set you publish, stamp a version on it and I'll pin to that.

 "Our static types stop lying" — we're stealing that line 😄

The staleness problem you're pointing at is real, and worth spelling out both failure shapes: after we add a field, your pinned hydration set dies one of two ways — strict parsers shatter (unknown key rejected), lenient parsers silently leak (new data you never see). Neither gives you a signal, and the second is the more insidious.

So, plainly: no version stamp today. But what you're asking for is right, and it's the cheapest contract of its kind — a monotonic version per page_type field set; you pin it, a bump is your signal, and you decide when to follow. The request is already precise enough that there's nothing left for us to design — noted, and noted heavily.

Until it exists, one practical note: stay tolerant of unknown keys when hydrating (no strict-reject) — that way a future added field degrades to "new data you don't read yet" instead of a parse break. Combined with our "absence ≡ not extracted" contract, your shape layer holds today; what the version stamp adds is the signal for when to update it.

The silent leak is the one that got us. What worked was hashing the sorted key set we hydrate against and storing that hash next to the extracted row, so when the shape changes the hash moves and something fails loudly instead of quietly gaining a field nobody reads. Cheap to add, and it turned a class of invisible drift into a diff I could actually look at.

 "Turn invisible drift into a diff" — that's exactly the right goal, and the sorted-key-set hash is a nice lightweight way to get there on the consumer side.

We attack the same problem from the producer side: every response field belongs to a typed contract, and the pipeline keeps an explicit registry of upstream keys we've either adopted or deliberately excluded. So when a source starts emitting a new field, it can't quietly slip into the response — it surfaces as a decision someone has to make, and our tests fail if the column list and the mapper ever drift apart. Same philosophy as yours: a shape change should be an event, not a surprise you find three weeks later in a field nobody reads.

Honestly might steal the hash trick for our own eval harness 😄 Thanks for sharing the war story.