<?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: Samuel Raphael</title>
    <description>The latest articles on DEV Community by Samuel Raphael (@samuel_raphael_001).</description>
    <link>https://dev.to/samuel_raphael_001</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%2F3992760%2Fdfed48e7-52e4-4e0f-8fa9-5f916fc35fc4.jpg</url>
      <title>DEV Community: Samuel Raphael</title>
      <link>https://dev.to/samuel_raphael_001</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuel_raphael_001"/>
    <language>en</language>
    <item>
      <title>Firecrawl vs Apify vs Quorel</title>
      <dc:creator>Samuel Raphael</dc:creator>
      <pubDate>Sat, 25 Jul 2026 12:04:12 +0000</pubDate>
      <link>https://dev.to/samuel_raphael_001/firecrawl-vs-apify-vs-quorel-1ai0</link>
      <guid>https://dev.to/samuel_raphael_001/firecrawl-vs-apify-vs-quorel-1ai0</guid>
      <description>&lt;p&gt;Firecrawl and Apify both do the hard part well. They render JavaScript, dodge bot detection, and hand you back clean markdown or structured JSON. If you need a page turned into text, either one will do that job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3gpwgisp0upryxoo1uc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3gpwgisp0upryxoo1uc7.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But most of the time the point isn't a single page. It's a page you need to check again tomorrow, and the day after, and the day after that: a price, a listing, a status, a set of rows that might quietly change. And that's where the workflow, not the extraction, starts costing you.&lt;/p&gt;

&lt;p&gt;Firecrawl bills per credit, and the credit math is not what the pricing page implies. Scrape is 1 credit. Add JSON extraction and Enhanced Mode — both of which you probably want for structured data — and it's 9 credits per page. A $16/mo Hobby plan advertised at 3,000 credits works out closer to 300–500 pages once you're actually extracting fields, not just fetching markdown. Credits also don't roll over, so a quiet month doesn't bank anything for a busy one.&lt;/p&gt;

&lt;p&gt;Apify flips the complaint around. Pricing is compute-unit based (RAM × time) plus separate line items for proxy and storage. It's flexible and it scales, but you can't look at a number on the pricing page and know what a job will cost until you've run it. For teams that want a predictable bill, that unpredictability is the whole problem.&lt;/p&gt;

&lt;p&gt;Neither tool keeps history by default. You get the current state of the page. If you want yesterday's version to compare against today's, that's on you to build — a database, a diffing script, a place to store snapshots, a way to roll back if a refresh comes back wrong.&lt;/p&gt;

&lt;p&gt;Quorel starts from a different question: not "how do I fetch this page," but "how do I keep a page as structured, versioned data over time." You describe the fields you want in plain English. Every refresh (nightly by default, or on demand via a ping URL, webhook, or your own cron) is saved as its own immutable version. Nothing is overwritten. You can diff any two versions to see exactly what changed, and roll back in one click if a refresh comes back bad.&lt;/p&gt;

&lt;p&gt;Pricing is flat, not metered. Free tier is one dataset, 20 URLs, full version history included. Pro is $19/mo for 5 datasets and 100 URLs, with on-demand refresh and webhooks. No credit multipliers, no compute-unit math, no surprise bill.&lt;/p&gt;

&lt;p&gt;This isn't a claim that Quorel replaces Firecrawl or Apify at everything they do. If you need to fetch an arbitrary one-off page as clean markdown for an LLM right now, Firecrawl is built for exactly that. If you need thousands of site-specific scrapers off a marketplace, Apify's Actor ecosystem has years of head start. Quorel is built for the narrower, recurring job: turning a page you check regularly into a structured, versioned API you can trust and query later.&lt;/p&gt;

&lt;p&gt;Every dataset ships with an MCP server on every plan, free included, so an agent can query it directly — or pull the raw rows, fix nulls, and publish a new version itself.&lt;/p&gt;

&lt;p&gt;If you've been burned by a scraper that silently broke, or wished you'd kept last week's data to compare against, that's the specific gap Quorel is built to close.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building &lt;a href="https://quorel.vercel.app" rel="noopener noreferrer"&gt;Quorel&lt;/a&gt; — happy to answer questions on versioning, pricing, or how the MCP integration works.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>api</category>
      <category>showdev</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I Built a Job Listing + E-commerce API Dataset in 4 Hours, No Code</title>
      <dc:creator>Samuel Raphael</dc:creator>
      <pubDate>Fri, 24 Jul 2026 21:27:44 +0000</pubDate>
      <link>https://dev.to/samuel_raphael_001/i-built-a-job-listing-e-commerce-api-dataset-in-4-hours-no-code-j1l</link>
      <guid>https://dev.to/samuel_raphael_001/i-built-a-job-listing-e-commerce-api-dataset-in-4-hours-no-code-j1l</guid>
      <description>&lt;h2&gt;
  
  
  The problem with "just build your own API"
&lt;/h2&gt;

&lt;p&gt;If you've ever wanted a personal dataset (job listings, product prices, whatever) you know the real cost isn't the idea, it's the pipeline. Scraping. Cleaning. Storage. Refreshing on a schedule. Serving it over an API. Handling schema drift when the source site redesigns. Every one of those is its own mini-project, and each is its own source of friction.&lt;/p&gt;

&lt;p&gt;I wanted a dataset combining &lt;strong&gt;Amazon products for developers&lt;/strong&gt; and &lt;strong&gt;job listings scraped from multiple sites&lt;/strong&gt;. Normally that's a multi-day side project. I built it in about &lt;strong&gt;4 hours&lt;/strong&gt;, without writing a single line of scraping or backend code.&lt;/p&gt;

&lt;p&gt;Here's how.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63fonflrfz1zyoe880bk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63fonflrfz1zyoe880bk.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The magic part: describing data instead of scraping it
&lt;/h2&gt;

&lt;p&gt;I used a tool called &lt;a href="https://quorel.vercel.app" rel="noopener noreferrer"&gt;Quorel&lt;/a&gt;. The workflow was almost embarrassingly simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I pasted in my source URLs (Amazon product pages, a few job board listing pages).&lt;/li&gt;
&lt;li&gt;I described the schema and extraction intent in plain English: no selectors, no XPath, no code. Something like "product name, price, rating, whether it's in stock" for the Amazon side, and "job title, company, location, salary range, posted date" for the listings side.&lt;/li&gt;
&lt;li&gt;I hit run and left it alone for 30–60 minutes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When I came back, the data was fully structured and ready to query.&lt;/p&gt;

&lt;p&gt;From there I asked Claude to build me a dashboard on top of the API so I could actually see and explore the data. That part took the rest of the 4 hours. The result is live here: &lt;strong&gt;&lt;a href="https://diffboard.vercel.app" rel="noopener noreferrer"&gt;diffboard.vercel.app&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0oyn2e83cgzgk8oexzbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0oyn2e83cgzgk8oexzbu.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1irhzlvvl6kunv34w7xb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1irhzlvvl6kunv34w7xb.png" alt=" " width="800" height="1827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that actually sold me: it's versioned like git
&lt;/h2&gt;

&lt;p&gt;Structuring the data was the easy win. What kept me around is that Quorel treats datasets like a git repo for live web data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nightly refresh&lt;/strong&gt; (or your own cron schedule): the data doesn't go stale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every refresh is a saved version&lt;/strong&gt;, nothing overwrites the last run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diffing between versions&lt;/strong&gt;: I can see exactly what changed, like prices that moved, listings that disappeared, new rows that showed up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time travel&lt;/strong&gt;: I can pull the dataset as it looked days or months ago.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rollback&lt;/strong&gt;: a bad refresh doesn't mean starting over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forking&lt;/strong&gt;: you can clone a public dataset the way you'd fork a repo, and extend it for your own use case.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination, structure plus history, is the part a plain scraper never gives you. Most tools hand you &lt;em&gt;today's&lt;/em&gt; snapshot. This hands you the whole timeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Talking to your data instead of querying it
&lt;/h2&gt;

&lt;p&gt;The other piece that stood out: Quorel ships an MCP server with every dataset, on every plan, including free. That means I can point an AI agent at my dataset and just talk to it, like "find listings with price drops this week" or "fix the null prices and publish a new version," and it does the pull, clean, and push cycle for me, still landing in the same versioned system. It's genuinely like chatting with your data pipeline instead of writing scripts for it.&lt;/p&gt;

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

&lt;p&gt;The datasets I built are public and free to use. You can query them directly, or clone one and extend it to fit your own project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quorel: &lt;a href="https://quorel.vercel.app" rel="noopener noreferrer"&gt;quorel.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Public datasets: &lt;a href="https://quorel.vercel.app/datasets" rel="noopener noreferrer"&gt;quorel.vercel.app/datasets&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;My dashboard: &lt;a href="https://diffboard.vercel.app" rel="noopener noreferrer"&gt;diffboard.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've barely scratched what's possible here. Next I want to enrich the job listings with salary normalization and wire the Amazon dataset into a price-drop alert bot. If you build something on top of this, I'd love to see it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>api</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I Found Firecrawl Too Expensive for My AI Agent's Knowledge Base, So I Built My Own</title>
      <dc:creator>Samuel Raphael</dc:creator>
      <pubDate>Tue, 30 Jun 2026 22:47:51 +0000</pubDate>
      <link>https://dev.to/samuel_raphael_001/i-found-firecrawl-too-expensive-for-my-ai-agents-knowledge-base-so-i-built-my-own-2o25</link>
      <guid>https://dev.to/samuel_raphael_001/i-found-firecrawl-too-expensive-for-my-ai-agents-knowledge-base-so-i-built-my-own-2o25</guid>
      <description>&lt;p&gt;Firecrawl is a great tool. I want to say that upfront, because what I'm about to describe isn't really Firecrawl's fault. It's just not what it was built for.&lt;/p&gt;

&lt;p&gt;I was using it as the data layer behind an AI agent, and the costs kept climbing for a simple reason: every time my agent needed fresh context, I paid to re-fetch the same sources again. Same pages, same data, paid for again and again, just to get a raw dump I then had to clean up myself before my agent could even use it.&lt;/p&gt;

&lt;p&gt;It felt wasteful. Not because the tool was bad, but because I was using a scraper to do a knowledge base's job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Difference That Was Costing Me Money
&lt;/h2&gt;

&lt;p&gt;A scraper gives you data right now: raw, unstructured, one-time. A knowledge base gives you data that's always current, structured, and queryable.&lt;/p&gt;

&lt;p&gt;I didn't need "fetch this page again." I needed something that already knew what I wanted, kept it fresh on its own, and let my agent ask for exactly the slice it needed, not the whole page dumped into context every single call.&lt;/p&gt;

&lt;p&gt;Three things were actually breaking my workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No structure.&lt;/strong&gt; Raw scraped output meant my agent was spending half its context window parsing format instead of using data: nav menus mixed into content, tables that didn't parse cleanly, no consistency between pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No memory.&lt;/strong&gt; I had no way to know what changed between fetches. Did a price update? Did a listing get removed? The only way to find out was diffing two raw dumps by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No queryability.&lt;/strong&gt; I couldn't ask for just the rows I needed. Every call meant everything, whether my agent needed it or not, straight into the context window, every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I Built Quorel
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://quorel.vercel.app" rel="noopener noreferrer"&gt;Quorel&lt;/a&gt; turns any public website into a versioned, queryable API. You describe what you want in plain English, it extracts and structures the data against that schema, and it keeps itself current with a nightly refresh, no re-scraping on my end, no maintenance.&lt;/p&gt;

&lt;p&gt;Every refresh that changes something meaningful creates a new immutable version, so I can see exactly what changed, roll back if something looks wrong, or freeze a version as a stable source while the live one keeps updating.&lt;/p&gt;

&lt;p&gt;The part that actually changed my agent's workflow: Quorel ships with a native MCP server on every plan. My agent doesn't receive a page dump anymore, it calls a tool and gets back exactly what it asked for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;query_dataset(&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;dataset_id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;keywords:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"pricing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tiers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;filter_range:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"updated_at:gte:2026-06-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;sort:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"updated_at:desc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;limit:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Structured, filtered, sorted, fresh: no glue code, no cleanup step, no paying again to re-fetch something I already had last week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Versioning Matters More Than I Expected
&lt;/h2&gt;

&lt;p&gt;This is the part I didn't know I needed until I had it. An agent that reasons about &lt;em&gt;change&lt;/em&gt; (what's different since last week, did this price move) genuinely can't do that with a plain scraper, because a fresh fetch only ever gives you &lt;em&gt;now&lt;/em&gt;. It has no memory of &lt;em&gt;then&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;With versioned data, that comparison is just... there. Diff two versions, see what moved, done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Stands Right Now
&lt;/h2&gt;

&lt;p&gt;I'll be straightforward: Quorel is early. I'm still building out the public dataset marketplace, so right now this is mainly for people who want to point it at their own sources and build their own structured, agent-queryable data layer, not yet a place to browse a library of ready-made datasets. That's coming soon, but I'd rather tell you where it actually stands than oversell it.&lt;/p&gt;

&lt;p&gt;If you're building an AI agent that needs fresh, structured context from the web, and you're tired of paying to re-fetch the same pages over and over, it's worth a look. Free plan, no credit card, MCP server included from day one.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://quorel.vercel.app" rel="noopener noreferrer"&gt;quorel.vercel.app&lt;/a&gt;&lt;br&gt;
→ &lt;a href="https://quorel.vercel.app/docs/mcp" rel="noopener noreferrer"&gt;MCP docs&lt;/a&gt;&lt;br&gt;
→ &lt;a href="https://github.com/var-raphael/QUOREL" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Happy to answer questions about the architecture, the MCP server, or how the versioning works under the hood. This is genuinely the tool I use for my own agent's data layer now.&lt;/em&gt;&lt;/p&gt;

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