<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Cox</title>
    <description>The latest articles on DEV Community by Daniel Cox (@daniel_cox_f0c468a48aaeac).</description>
    <link>https://dev.to/daniel_cox_f0c468a48aaeac</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3889212%2Fd13f283e-0d72-4239-a4c2-c30dd907a66f.png</url>
      <title>DEV Community: Daniel Cox</title>
      <link>https://dev.to/daniel_cox_f0c468a48aaeac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daniel_cox_f0c468a48aaeac"/>
    <language>en</language>
    <item>
      <title>I got tired of writing scrapers for my AI agents, so I built Haunt</title>
      <dc:creator>Daniel Cox</dc:creator>
      <pubDate>Wed, 01 Jul 2026 10:29:58 +0000</pubDate>
      <link>https://dev.to/daniel_cox_f0c468a48aaeac/i-got-tired-of-writing-scrapers-for-my-ai-agents-so-i-built-haunt-49pf</link>
      <guid>https://dev.to/daniel_cox_f0c468a48aaeac/i-got-tired-of-writing-scrapers-for-my-ai-agents-so-i-built-haunt-49pf</guid>
      <description>&lt;p&gt;Every time I wanted an AI agent to read a web page, I ended up in the same hole: writing a scraper, picking selectors, spinning up a headless browser for the JavaScript-heavy ones, then babysitting the whole thing as sites changed. Worse, many scraping tools "succeed" on a blocked page by handing you garbage, which quietly poisons whatever you feed it.&lt;/p&gt;

&lt;p&gt;So I built Haunt. You give it a URL and a plain-English prompt, and it hands back clean structured JSON or Markdown. No selectors, no parsing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic call
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://hauntapi.com/v1/extract &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: YOUR_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url": "https://example.com/pricing", "prompt": "every plan with its price and features"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get back something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"plans"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Starter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$19/mo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"features"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"full_structured"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"credits_used"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"credits_remaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;998&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask for Markdown instead of JSON, and you get clean page text, which is what most people actually want for a RAG pipeline or an agent's context.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's built for agents
&lt;/h2&gt;

&lt;p&gt;If your agent speaks MCP, wiring it up is one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--package&lt;/span&gt; @hauntapi/cli@latest haunt-cli init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, your agent has a tool it can call to read any public page, with no glue code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts I actually spent my time on
&lt;/h2&gt;

&lt;p&gt;The "LLM turns a page into JSON" bit is the easy part. The parts that took the real work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Honest failures.&lt;/strong&gt; When a page is blocked, behind a login, or bot-walled, Haunt tells you that. It does not fake a result. And it won't invent fields that aren't on the page: it grounds the output against the real page text and drops anything it can't find there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero retention by default.&lt;/strong&gt; It does not keep your page content, prompts, or results. It holds only the metadata it needs for billing and abuse prevention.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failed calls don't burn credits.&lt;/strong&gt; You pay for extractions that actually worked, not for the ones that didn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;Being straight, because this crowd will rightly ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The free and fast path is a direct fetch plus extraction. It does not run the heavy anti-bot stack (proxy rotation, full browser recovery) on the free tier.&lt;/li&gt;
&lt;li&gt;It does not crack CAPTCHAs or bypass human verification. If you need to defeat every wall on earth, this is not that tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;There is a live demo on the homepage with no signup: paste any public URL and watch it extract. Free tier is 1,000 credits a month, no card.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Site and demo: &lt;a href="https://hauntapi.com" rel="noopener noreferrer"&gt;https://hauntapi.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://hauntapi.com/docs" rel="noopener noreferrer"&gt;https://hauntapi.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built this solo and launched it today. I would genuinely love feedback, especially where it breaks or where it is weaker than you would need. If you try it and it falls over, tell me. That is the most useful thing I can get right now.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ai</category>
      <category>api</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
