<?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: Truffle Pig Data</title>
    <description>The latest articles on DEV Community by Truffle Pig Data (@trufflepig).</description>
    <link>https://dev.to/trufflepig</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%2F4032427%2Fd0090288-9c11-47e3-b5bc-5670ada11de5.png</url>
      <title>DEV Community: Truffle Pig Data</title>
      <link>https://dev.to/trufflepig</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/trufflepig"/>
    <language>en</language>
    <item>
      <title>Local Lead Generation with Yelp Data: How to Scrape Yelp Search Results in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Fri, 07 Aug 2026 19:09:36 +0000</pubDate>
      <link>https://dev.to/trufflepig/local-lead-generation-with-yelp-data-how-to-scrape-yelp-search-results-in-2026-52lk</link>
      <guid>https://dev.to/trufflepig/local-lead-generation-with-yelp-data-how-to-scrape-yelp-search-results-in-2026-52lk</guid>
      <description>&lt;p&gt;If you sell anything to local businesses, &lt;a href="https://www.yelp.com/" rel="noopener noreferrer"&gt;Yelp&lt;/a&gt; is one of the best prospect databases that exists: ranked listings, review counts that signal how established a business is, price tiers, phone numbers, neighborhoods. Getting that out of the site programmatically is the annoying part. The &lt;a href="https://apify.com/johnvc/yelp-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Search API&lt;/a&gt; on Apify does it for you: a search term and a location go in, and the ranked business listings come out as clean JSON.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doesn't Yelp already have an API?
&lt;/h2&gt;

&lt;p&gt;It does. The Yelp Fusion API is official, documented, and worth knowing about. It also comes with the usual official-API friction: key registration, daily call quotas, terms that constrain how you store and reuse the data, and responses shaped by what Yelp chooses to expose rather than what the search page shows. The ranked results page, with its sponsored slots and refinement filters, is its own thing. A scraper you call like an API gives you that page as data, with no key and no quota negotiation, which is usually what local lead generation work actually needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Yelp Search API returns
&lt;/h2&gt;

&lt;p&gt;The Yelp Search API returns ranked local business listings as structured JSON: name, rating, review count, price tier, categories, phone, neighborhood, and the place IDs you need to pull full details later.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Business name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Brooklyn Smile Dental&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;As ranked on the page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rating&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4.7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Star rating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviews&lt;/td&gt;
&lt;td&gt;&lt;code&gt;284&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Review count, a proxy for how established they are&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;&lt;code&gt;$$&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yelp's price tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Categories&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dentists, cosmetic dentists&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yelp category aliases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(718) 555-0139&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The outreach field&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each result also carries a &lt;code&gt;filters&lt;/code&gt; object listing the valid category, price, feature, distance, and neighborhood refinements for that search, so you can discover legal filter values straight from the data instead of guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Local lead generation shops building B2B lists by trade and metro. Agencies pitching reputation or marketing services who want review counts and ratings attached to every prospect. And data teams who need a ranked snapshot of a local market, whether that's dentists in Brooklyn or every $$ restaurant near a ZIP code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Yelp's search results render through heavy client-side code, the markup is deliberately unfriendly to parsers, and unattended scripts meet the anti-bot wall quickly. The refinement system runs on URL parameters (&lt;code&gt;find_desc&lt;/code&gt;, &lt;code&gt;find_loc&lt;/code&gt;, &lt;code&gt;cflt&lt;/code&gt;, &lt;code&gt;attrs&lt;/code&gt;) that are documented nowhere, so you reverse-engineer them from your browser bar. I did exactly that while building this Actor, and I can report the parameters change just often enough to keep a DIY scraper permanently on your maintenance list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Yelp Search API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/yelp-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Search API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;location&lt;/code&gt; (city, address, or ZIP) and optionally a &lt;code&gt;search_term&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and export the listings as JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~yelp-search-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "search_term": "plumbers", "location": "Chicago, IL", "sort_by": "review_count", "max_pages": 2 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Standard Apify run endpoints; reference in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search Yelp in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/yelp-search-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_term&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dentists&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Brooklyn, NY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sort_by&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Twenty listings, sorted by rating, with phone numbers attached: that's a cold-call sheet in about ten lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build B2B lists by ZIP code
&lt;/h2&gt;

&lt;p&gt;The task &lt;a href="https://apify.com/johnvc/yelp-search-api/examples/find-dentists-by-zip-code-for-b2b-lead-lists?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find dentists by ZIP code for B2B lead lists&lt;/a&gt; shows ZIP-level targeting, the granularity most sales territories are drawn in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Target one borough at a time
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/yelp-search-api/examples/find-dentists-in-brooklyn-for-lead-generation?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find dentists in Brooklyn for lead generation&lt;/a&gt; is the metro version of the same play, ready to clone for your own city and niche.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover the trades
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/yelp-search-api/examples/find-plumbers-in-chicago-for-lead-generation?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find plumbers in Chicago for lead generation&lt;/a&gt; applies the pattern to home services, where review count doubles as a longevity signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rank the best restaurants in a city
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/yelp-search-api/examples/find-the-best-restaurants-in-newark?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find the best restaurants in Newark&lt;/a&gt; uses rating sort for a market snapshot rather than a lead list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clone it for the next market
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/yelp-search-api/examples/find-the-best-restaurants-in-oakland?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find the best restaurants in Oakland&lt;/a&gt; is the same search pointed at another coast, which is the whole point: one saved task per market, run on demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yelp MCP: let your agent search listings
&lt;/h2&gt;

&lt;p&gt;Through Apify's MCP server, the Actor is callable from Claude, Claude Code, and Cursor as a tool. Ask "find the ten highest-rated plumbers in Chicago and give me their phone numbers" and the agent runs a real search instead of inventing plausible-sounding businesses. Setup is a one-time config, and you can read more about Claude at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about the Yelp scraper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Yelp scraper free, and what does it cost after that?
&lt;/h3&gt;

&lt;p&gt;Runs bill one cent per results page (about 10 businesses) plus a one-cent setup fee, so a 100-listing pull costs roughly eleven cents. New Apify accounts ship with free platform credit that covers early runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use a scraper instead of the Yelp Fusion API?
&lt;/h3&gt;

&lt;p&gt;Use Fusion when its quotas and terms fit your project; it's a fine API. Use the scraper when you want the ranked search page itself, filters and all, without key management or daily caps, and in a shape built for exporting lead lists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude run this Yelp scraper through MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Registered as an MCP tool it works from Claude, Claude Code, and Cursor, returning the same structured listings a direct run produces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the Yelp scraper for rank tracking?
&lt;/h3&gt;

&lt;p&gt;Yes. Multi-location brands do this to watch where each location ranks for its core search. Save a task per location-query pair, attach an Apify schedule, and diff positions over time, starting from the &lt;a href="https://apify.com/johnvc/yelp-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Search API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What data will the search scraper not give me?
&lt;/h3&gt;

&lt;p&gt;Whatever the results page doesn't show: no email addresses, no full review text, no hours. It returns place IDs precisely so you can chain a second Actor for depth on the businesses that matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;The chain I just mentioned: the &lt;a href="https://apify.com/johnvc/Yelp-Place-API?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Place API&lt;/a&gt; turns place IDs into full business detail, the &lt;a href="https://apify.com/johnvc/Yelp-Reviews-API?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Reviews API&lt;/a&gt; pulls the review text, and the &lt;a href="https://apify.com/johnvc/google-local-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local API&lt;/a&gt; gives you the same market from Google's side for comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Local lead generation runs on fresh, ranked, filterable business data, and Yelp has exactly that. The &lt;a href="https://apify.com/johnvc/yelp-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yelp Search API&lt;/a&gt; hands it to you as JSON; start with one niche in one city and scale from there.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Pricing Intelligence for iOS Apps: How to Pull App Store Product Data in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Fri, 07 Aug 2026 11:11:27 +0000</pubDate>
      <link>https://dev.to/trufflepig/pricing-intelligence-for-ios-apps-how-to-pull-app-store-product-data-in-2026-4mk3</link>
      <guid>https://dev.to/trufflepig/pricing-intelligence-for-ios-apps-how-to-pull-app-store-product-data-in-2026-4mk3</guid>
      <description>&lt;p&gt;A surprising amount of product strategy starts with somebody reading an &lt;a href="https://apps.apple.com/" rel="noopener noreferrer"&gt;App Store&lt;/a&gt; page: what a competitor charges, which in-app purchases they sell, what their last ten versions shipped, how their rating moves. I got tired of doing that reading by hand, so I built the &lt;a href="https://apify.com/johnvc/apple-app-store-product-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Product API&lt;/a&gt; on Apify. Feed it App Store IDs or URLs and it returns the full product record for any iOS, iPadOS, or macOS app as structured JSON, one row per app per country.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does the Apple App Store have an API?
&lt;/h2&gt;

&lt;p&gt;Yes, partly, and the partly is why this Actor exists. Apple's iTunes Search and Lookup endpoints are real and free, and for basic metadata they're fine. But the payload reflects an older App Store: you won't find the privacy "nutrition" cards, the itemized in-app purchase price list, version-by-version release notes, or the sample reviews that sit on today's product page, and Apple publishes no firm rate guarantees for it. When the data you need is "everything on the modern product page, per storefront," a scraper consumed as an API is the practical route.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the App Store product API returns
&lt;/h2&gt;

&lt;p&gt;The Apple App Store Product API returns one complete app record per ID and country: title, developer, description, price, ratings, version history, screenshots, in-app purchases, supported languages, privacy cards, and a sample of reviews.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Spotify: Music and Podcasts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;App name as listed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;developer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Spotify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publisher of record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;price_text&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Free&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Localized price for the storefront queried&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ratings&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4.8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Star average plus counts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In-app purchases&lt;/td&gt;
&lt;td&gt;&lt;code&gt;subscription tiers with prices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Itemized, the pricing intelligence core&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lookup_country&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;de&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Which storefront this row came from&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Version history, privacy cards, and supported languages ride along in the same row, and &lt;code&gt;include_reviews_sample&lt;/code&gt; controls whether the page's few visible reviews are attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Pricing intelligence is the headline use: analysts comparing what an app charges across 50 storefronts, or watching a competitor's in-app purchase ladder change quarter to quarter. Product and ASO teams doing competitive research are the second group. The third is AI agent builders who want app metadata as agent context, so "summarize this competitor's app and its monetization" runs on real data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;The product page is public, so scraping it yourself is tempting. The details fight back. Much of the page content lives in embedded data structures that shift with App Store redesigns, storefront selection depends on URL country prefixes and headers that are easy to get subtly wrong, and localized price formatting differs per region, so your parser needs currency logic on day one. Multiply all of that by a country matrix and a retry layer, and the quick script becomes a project. I wrote the throwaway version three times before admitting it wasn't throwaway.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Apple App Store Product API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/apple-app-store-product-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Product API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Paste App Store IDs or full URLs into &lt;code&gt;product_ids&lt;/code&gt; and pick a &lt;code&gt;country&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the records as JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~apple-app-store-product-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "product_ids": ["324684580"], "country": "us" }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ID &lt;code&gt;324684580&lt;/code&gt; is Spotify; a full URL like &lt;code&gt;https://apps.apple.com/us/app/spotify/id324684580&lt;/code&gt; works too, since the ID gets parsed out. Run mechanics are in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetch app records in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/apple-app-store-product-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_ids&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;324684580&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;310633997&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;countries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;de&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lookup_country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price_text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two IDs across three storefronts returns six rows, one per app-country pair, which is the shape you want for a pricing matrix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare prices across country stores
&lt;/h2&gt;

&lt;p&gt;The task &lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/app-store-prices-by-country?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;App Store prices by country&lt;/a&gt; is the regional pricing sweep: one app, many storefronts, localized &lt;code&gt;price_text&lt;/code&gt; per row.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark competitor apps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/compare-competitor-ios-apps-on-price-and-features?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Compare competitor iOS apps on price and features&lt;/a&gt; runs a set of rival apps through one pull, which is the fastest way to build a feature-and-price comparison table that's current.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract in-app purchase price lists
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/extract-ios-app-in-app-purchase-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Extract iOS app in-app purchase prices&lt;/a&gt; targets the monetization ladder specifically, the part Apple's official lookup won't give you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Look up any app by ID
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/get-apple-app-store-app-details-by-app-id?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Apple App Store app details by app ID&lt;/a&gt; is the minimal single-app run, useful as a smoke test before you scale up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch ratings and releases over time
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/track-ios-app-ratings-and-version-history?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track iOS app ratings and version history&lt;/a&gt; shows the monitoring setup: run it on a schedule and you accumulate a longitudinal record of rating drift and release cadence.&lt;/p&gt;

&lt;h2&gt;
  
  
  App data as AI agent context
&lt;/h2&gt;

&lt;p&gt;Hooked up over the Model Context Protocol, the Actor becomes a tool that Claude, Claude Code, and Cursor can call, so an agent can pull a live app record before answering questions about it. The task &lt;a href="https://apify.com/johnvc/apple-app-store-product-api/examples/ios-app-details-in-claude-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;iOS app details in Claude MCP&lt;/a&gt; has the wiring, and there's more on Claude at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping App Store product data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the App Store scraper cost to run?
&lt;/h3&gt;

&lt;p&gt;Two cents per app record returned, plus a two-cent setup fee per run. A 100-app competitive sweep, the per-run maximum, lands around $2. Apify's free credit on new accounts covers plenty of experimentation first.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is this scraper different from Apple's own lookup endpoints?
&lt;/h3&gt;

&lt;p&gt;Apple's endpoints return the classic metadata slice. The scraper returns the product page as it exists now, including in-app purchase pricing, privacy cards, version history, and per-storefront localization, which is where pricing intelligence work actually happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent call this App Store scraper over MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Registered as an MCP tool, it's callable from Claude, Claude Code, and Cursor, and each call returns full app records as tool output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to monitor price changes?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your app list as a task, attach an Apify schedule, and compare &lt;code&gt;price_text&lt;/code&gt; and in-app purchase entries between runs. Start from the &lt;a href="https://apify.com/johnvc/apple-app-store-product-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Product API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What won't this product scraper give you?
&lt;/h3&gt;

&lt;p&gt;The full review corpus. It carries the small review sample Apple displays on the page, typically three, which is enough for flavor but not sentiment analysis. It also reports one storefront per row, so worldwide coverage means listing the countries you care about rather than assuming one row covers all.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;The rest of the Apple toolkit: the &lt;a href="https://apify.com/johnvc/apple-app-store-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Reviews API&lt;/a&gt; when you do need reviews at volume, &lt;a href="https://apify.com/johnvc/apple-app-store-search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Search&lt;/a&gt; for finding app IDs by keyword, and the &lt;a href="https://apify.com/johnvc/apple-maps-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple Maps API&lt;/a&gt; for Apple's places data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Competitive app research shouldn't mean reading product pages in fifty tabs. Point the &lt;a href="https://apify.com/johnvc/apple-app-store-product-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apple App Store Product API&lt;/a&gt; at your competitor set and get the whole picture as JSON.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Google Local AI: Get Local Pack Data as JSON for Agents, Lead Gen, and Rank Tracking</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Thu, 06 Aug 2026 08:10:24 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-local-ai-get-local-pack-data-as-json-for-agents-lead-gen-and-rank-tracking-1j48</link>
      <guid>https://dev.to/trufflepig/google-local-ai-get-local-pack-data-as-json-for-agents-lead-gen-and-rank-tracking-1j48</guid>
      <description>&lt;p&gt;The local pack, that map-plus-three-businesses block at the top of &lt;a href="https://www.google.com/" rel="noopener noreferrer"&gt;Google Search&lt;/a&gt;, decides who gets the phone call for "plumber near me" in every city on earth. For local SEO work and lead generation you need that block as data, and Google doesn't hand it over. The &lt;a href="https://apify.com/johnvc/google-local-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local API&lt;/a&gt; on Apify fixes that: send a query and a city, get back the local results as JSON with ratings, phones, hours, and coordinates.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Google have a local pack API?
&lt;/h2&gt;

&lt;p&gt;Google has the official Places API, and it's genuinely good at what it does: look up businesses, get details, autocomplete addresses. What it will not tell you is what the local pack actually shows for a search in a specific city, in what order, on which device. Pack composition and ranking are SERP features, not Places data, and there's no official endpoint for them. Rank trackers and lead-gen tools need the page as served, which is why a scraper you call like an API fills the gap: it queries Google Local the way a user in that location would and returns the businesses it saw.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Local API returns
&lt;/h2&gt;

&lt;p&gt;The Google Local API returns each local result as structured JSON: business name, rating, review count, address, phone, hours, GPS coordinates, &lt;code&gt;place_id&lt;/code&gt;, and links.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Business name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Smith &amp;amp; Sons Plumbing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;As shown in the pack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rating&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4.8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Star rating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviews&lt;/td&gt;
&lt;td&gt;&lt;code&gt;312&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Review count behind the rating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;phone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(813) 555-0182&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The lead-gen field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hours&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Open until 6 PM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current status as rendered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;place_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChIJd8BlQ2Bx...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stable ID for joins with other Google data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GPS coordinates ride along for mapping, and you can target by &lt;code&gt;google_domain&lt;/code&gt;, country (&lt;code&gt;gl&lt;/code&gt;), language (&lt;code&gt;hl&lt;/code&gt;), and &lt;code&gt;device&lt;/code&gt;. Desktop pages carry about 20 businesses, mobile about 10, which matters because billing is per page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Local SEO agencies tracking pack positions for clients. Lead-gen operators building contact lists of roofers, med spas, or HVAC contractors city by city. And builders wiring local business lookup into AI agents, where "find me the top-rated dentists in Chicago" should return data, not vibes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Scraping the local pack yourself means faking a location. Google decides what you see from where it thinks you are, so you're forging &lt;code&gt;uule&lt;/code&gt; strings, juggling consent pages, and rendering JavaScript before you parse a single card. Then the anti-bot layer notices your datacenter IP. Then the markup changes. I keep a mental list of scrapers I've written twice, and Google SERP parsers sit at the top of it. The location spoofing alone is why I'd rather call something hosted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Local API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-local-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;q&lt;/code&gt; to a search like "plumbers" and &lt;code&gt;location&lt;/code&gt; to a city.&lt;/li&gt;
&lt;li&gt;Run it and export JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-local-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "q": "plumbers", "location": "Tampa, Florida, United States", "max_pages": 1 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The run lifecycle is standard Apify; details in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull local businesses in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-local-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dentists&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Chicago, Illinois, United States&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;device&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;desktop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;biz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;place_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loop the same call over a city list and you've got a scraper-backed prospecting pipeline in thirty lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build lead lists for home services
&lt;/h2&gt;

&lt;p&gt;The biggest family of published tasks does exactly this, one trade per task: &lt;a href="https://apify.com/johnvc/google-local-api/examples/build-a-roofer-contact-list-for-dallas-texas?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;roofer contacts in Dallas&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-local-api/examples/find-hvac-contractor-leads-in-phoenix-arizona?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;HVAC contractors in Phoenix&lt;/a&gt;, and &lt;a href="https://apify.com/johnvc/google-local-api/examples/find-local-plumber-leads-in-tampa-florida?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;plumbers in Tampa&lt;/a&gt;. Each is a preconfigured run you can clone for your own metro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover professional and medical niches
&lt;/h2&gt;

&lt;p&gt;The same pattern extends to higher-ticket verticals: &lt;a href="https://apify.com/johnvc/google-local-api/examples/find-med-spas-in-scottsdale-with-ratings?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;med spas in Scottsdale with ratings&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-local-api/examples/find-dental-implant-leads-phoenix?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;dental implant leads in Phoenix&lt;/a&gt;, and &lt;a href="https://apify.com/johnvc/google-local-api/examples/find-immigration-lawyer-leads-new-york?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;immigration lawyers in New York&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track local pack rankings for SEO
&lt;/h2&gt;

&lt;p&gt;Rank tracking is the other half of the story. &lt;a href="https://apify.com/johnvc/google-local-api/examples/google-local-pack-rank-tracker-seo-agencies?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google local pack rank tracker for SEO agencies&lt;/a&gt; is the agency template, &lt;a href="https://apify.com/johnvc/google-local-api/examples/track-plumber-near-me-local-pack-rankings?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;track "plumber near me" local pack rankings&lt;/a&gt; covers the near-me query class, and &lt;a href="https://apify.com/johnvc/google-local-api/examples/monitor-local-serp-visibility-for-dentist-seo?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;monitor local SERP visibility for dentist SEO&lt;/a&gt; shows ongoing monitoring for one niche.&lt;/p&gt;

&lt;h2&gt;
  
  
  No code, just a spreadsheet
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/google-local-api/examples/export-google-local-results-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Google Local results to CSV&lt;/a&gt; is the Console-only path from search to sheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Local AI: give your agent the pack
&lt;/h2&gt;

&lt;p&gt;Where this gets interesting in 2026 is agents. Over the Model Context Protocol, the Actor becomes a tool Claude, Claude Code, or Cursor can call, so a prompt like "who ranks in the local pack for roofers in Denver, and what are their ratings?" triggers a live run and comes back grounded in the actual SERP. Wire it up through Apify's MCP server, and read more about Claude at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about the Google Local scraper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the local pack scraper cost per run?
&lt;/h3&gt;

&lt;p&gt;Two cents per page of results, plus a small setup fee per run. A desktop page holds around 20 businesses, so a city-level lead pull works out to about a tenth of a cent per business. &lt;code&gt;max_pages&lt;/code&gt; caps spend, and new Apify accounts include free credit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can this scraper power a local rank tracker on a schedule?
&lt;/h3&gt;

&lt;p&gt;Yes, that's the core SEO use. Save one task per query-city pair, attach an Apify schedule, and diff positions run over run. Start from the &lt;a href="https://apify.com/johnvc/google-local-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local API&lt;/a&gt; and the agency rank-tracker task above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper support "near me" and precise locations?
&lt;/h3&gt;

&lt;p&gt;It does. Use &lt;code&gt;location&lt;/code&gt; for city-level targeting or a &lt;code&gt;uule&lt;/code&gt; string for finer control, plus &lt;code&gt;gl&lt;/code&gt;, &lt;code&gt;hl&lt;/code&gt;, and &lt;code&gt;google_domain&lt;/code&gt; for country and language. The &lt;code&gt;device&lt;/code&gt; setting switches between desktop and mobile results, which often differ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude call this scraper as an MCP tool?
&lt;/h3&gt;

&lt;p&gt;Yes. Registered through Apify's MCP server, it shows up as a callable tool in Claude, Claude Code, and Cursor, and returns the same structured rows an API call would.&lt;/p&gt;

&lt;h3&gt;
  
  
  What won't a local pack scraper give you?
&lt;/h3&gt;

&lt;p&gt;Email addresses, for one: Google Local shows phone, hours, and links, so email prospecting needs an enrichment step. And the pack is inherently local and personalized, so your run reflects the location and device you requested, not the exact page every user sees. Treat positions as a consistent measurement, not a universal truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Adjacent Actors for local data work: the &lt;a href="https://apify.com/johnvc/google-maps-places-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Places API&lt;/a&gt; for place detail lookups, the &lt;a href="https://apify.com/johnvc/google-local-services-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local Services API&lt;/a&gt; for the sponsored pros block, and the &lt;a href="https://apify.com/johnvc/google-maps-directions-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Directions API&lt;/a&gt; for travel times between the businesses you find.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The local pack is where local revenue starts, and now it's queryable. Point the &lt;a href="https://apify.com/johnvc/google-local-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local API&lt;/a&gt; at your niche and city, and you'll have the block as JSON before your coffee cools.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>geospatial</category>
    </item>
    <item>
      <title>Business Development with SEC Data: How to Build Investment Advisor Lead Lists in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Wed, 05 Aug 2026 19:09:42 +0000</pubDate>
      <link>https://dev.to/trufflepig/business-development-with-sec-data-how-to-build-investment-advisor-lead-lists-in-2026-ig7</link>
      <guid>https://dev.to/trufflepig/business-development-with-sec-data-how-to-build-investment-advisor-lead-lists-in-2026-ig7</guid>
      <description>&lt;p&gt;Every SEC-registered investment advisor in the United States sits in a public registry, the &lt;a href="https://adviserinfo.sec.gov/" rel="noopener noreferrer"&gt;Investment Adviser Public Disclosure database&lt;/a&gt;, and almost nobody in business development uses it directly because the raw data is a chore to work with. I kept rebuilding the same parsing pipeline for finance prospecting projects, so I turned it into the &lt;a href="https://apify.com/johnvc/SECInvestmentAdvisorContacts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;SEC Investment Advisors Search&lt;/a&gt; on Apify: 250,000+ investment professionals and 15,000+ RIA firms, queryable by name, location, or CRD number, returned as structured JSON.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there an API for SEC investment advisor data?
&lt;/h2&gt;

&lt;p&gt;Sort of, and that "sort of" is the problem. The registry is public and the SEC does publish compiled advisor data, but as bulk snapshot files meant for downloading, not a query API you can hit with a city and a firm name. There's no endpoint for "give me the contacts at RIA firms in Texas updated since March." So the practical version of an SEC advisor API is a scraper-backed database you query like an API: filters in, contact and firm records out, with pagination and incremental updates handled for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the advisor contacts API returns
&lt;/h2&gt;

&lt;p&gt;The SEC Investment Advisors Search returns firms, contacts, or both as structured JSON, with each contact linked to their firm.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Contact name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Jane Smith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Individual advisor or representative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsmith@examplecapital.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Includes a verification status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone&lt;/td&gt;
&lt;td&gt;&lt;code&gt;+1 212 555 0140&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contact-level number when present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Professional profile URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;linkedin.com/in/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Link to the person's profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firm name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Example Capital Advisors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;With firm-level identifiers like CRD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Office address&lt;/td&gt;
&lt;td&gt;&lt;code&gt;New York, NY, US&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Plus firm website&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Records carry timestamps and identifiers for deduplication, which matters once you start running this on a schedule and only want what changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;The obvious crowd is business development and sales teams selling into financial services: fintech vendors, compliance software, custodians, anyone whose buyer is an RIA. The less obvious users are market researchers mapping how advisory firms distribute across geographies, and CRM operators who need to enrich a stale contact database with firm associations and verified emails.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;The DIY path is to download the SEC's compiled advisor data, unpack a very large file, and write parsers to join individuals to firms. I've done it, and it works once. Then next month's snapshot lands and you rerun everything from scratch, because the bulk files don't tell you what changed. Filtering by geography means loading the whole country to keep one state. And the compilation gives you registrations, not an outreach-ready record; profile links and email verification are on you. None of it is hard, exactly. It's just a data-engineering project standing between you and a prospect list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the SEC Investment Advisors Search
&lt;/h2&gt;

&lt;p&gt;One JSON input, one filtered result set, pay per contact returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/SECInvestmentAdvisorContacts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;SEC Investment Advisors Search&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Pick a &lt;code&gt;query_type&lt;/code&gt; (firms, contacts, or both) and set filters like &lt;code&gt;firm_city&lt;/code&gt; or &lt;code&gt;firm_state&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~SECInvestmentAdvisorContacts/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "query_type": "both", "firm_city": "New York", "firm_state": "NY", "contacts_limit": 25 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Endpoint mechanics are in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query advisor contacts in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/SECInvestmentAdvisorContacts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contacts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_firm_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Morgan Stanley&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contacts_limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap &lt;code&gt;contact_firm_name&lt;/code&gt; for &lt;code&gt;organization_crds&lt;/code&gt; when you already know the firms you're targeting; CRD numbers are exact where name matching is fuzzy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build an RIA list for one city
&lt;/h2&gt;

&lt;p&gt;The task &lt;a href="https://apify.com/johnvc/secinvestmentadvisorcontacts/examples/build-an-ria-contact-list-for-new-york-city?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build an RIA contact list for New York City&lt;/a&gt; shows the metro-area pattern: city plus state filters, firms and contacts together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn registry data into lead lists
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/secinvestmentadvisorcontacts/examples/build-financial-advisor-lead-lists-from-sec-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build financial advisor lead lists from SEC data&lt;/a&gt; is the general business development recipe, going from filters to an outreach-ready sheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skip the code entirely
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/secinvestmentadvisorcontacts/examples/download-sec-investment-advisor-data-as-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Download SEC investment advisor data as CSV&lt;/a&gt; runs in the Console and ends in a spreadsheet, no Python required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cover a whole state
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/secinvestmentadvisorcontacts/examples/list-sec-registered-investment-advisors-in-texas?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;List SEC registered investment advisors in Texas&lt;/a&gt; demonstrates state-level coverage, useful for territory planning and market sizing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prospect from Claude via MCP
&lt;/h2&gt;

&lt;p&gt;Because Apify exposes Actors over the Model Context Protocol, Claude, Claude Code, and Cursor can run advisor searches as a tool call. "Find me RIA firms in Austin and pull their contacts" becomes a prompt instead of a script, and the structured records land in the conversation. The task &lt;a href="https://apify.com/johnvc/secinvestmentadvisorcontacts/examples/prospect-sec-investment-advisors-from-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Prospect SEC investment advisors from Claude via MCP&lt;/a&gt; has the setup, and you can read about Claude itself at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about the SEC advisor scraper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the SEC advisor scraper cost per contact?
&lt;/h3&gt;

&lt;p&gt;About a cent per contact returned, plus a couple of tenths of a cent in run setup fees. &lt;code&gt;contacts_limit&lt;/code&gt; caps the spend before a run starts, and the free credit on a new Apify account covers a real first list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where does the scraper's contact data come from?
&lt;/h3&gt;

&lt;p&gt;The underlying registry is the SEC's public Investment Adviser Public Disclosure data, covering registered firms and their professionals. The Actor layers structure on top: linked firm associations, profile URLs, and email verification status. It's public-record data, and your outreach still has to follow the usual email and telemarketing rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use this scraper for CRM enrichment on a schedule?
&lt;/h3&gt;

&lt;p&gt;Yes, and the &lt;code&gt;date_updated&lt;/code&gt; filter is the key. Run it monthly with an Apify schedule, request only records updated since your last sync, and you pay for changes rather than the whole registry. Start from the &lt;a href="https://apify.com/johnvc/SECInvestmentAdvisorContacts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;SEC Investment Advisors Search&lt;/a&gt; and save the filter set as a task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper work from Claude or other MCP clients?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect it through Apify's MCP server and it appears as a callable tool, so an agent can pull advisor lists mid-conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What won't this scraper give you?
&lt;/h3&gt;

&lt;p&gt;It covers SEC-registered investment advisors, so brokers, insurance agents, and state-only registrants outside that registry won't appear. Emails carry a verification status but no guarantee of deliverability, and profile URLs exist only where a profile was found. Treat it as a strong starting list, not a finished campaign.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;If you're building a finance prospecting stack, these sit next door: the &lt;a href="https://apify.com/johnvc/linkedin-company-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Company API&lt;/a&gt; for firmographic detail, the &lt;a href="https://apify.com/johnvc/crunchbase-company-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Crunchbase Company API&lt;/a&gt; for funding context, and the &lt;a href="https://apify.com/johnvc/pitchbook-company-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;PitchBook Company API&lt;/a&gt; for the private-markets view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The SEC already published the best advisor database in the country; it just didn't ship a query API for it. The &lt;a href="https://apify.com/johnvc/SECInvestmentAdvisorContacts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;SEC Investment Advisors Search&lt;/a&gt; fills that gap, one filtered run at a time.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Yandex Tracking at Scale: Build a Rank Tracker for 1,000 Keywords in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Wed, 05 Aug 2026 13:15:10 +0000</pubDate>
      <link>https://dev.to/trufflepig/yandex-tracking-at-scale-build-a-rank-tracker-for-1000-keywords-in-2026-3i0f</link>
      <guid>https://dev.to/trufflepig/yandex-tracking-at-scale-build-a-rank-tracker-for-1000-keywords-in-2026-3i0f</guid>
      <description>&lt;p&gt;Most rank trackers price &lt;a href="https://yandex.com/" rel="noopener noreferrer"&gt;Yandex&lt;/a&gt; like an afterthought, when they cover it at all. If your clients sell into Russia, Turkey, Kazakhstan, or anywhere else Yandex matters, the tooling gap is real: you either pay for an enterprise tier you don't need or you track rankings by hand. I built the &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Rank Tracker API&lt;/a&gt; to close that gap. It's a per-result Yandex SERP scraper: you pay for exactly the rows you pull, whether that's a 10-keyword daily check or a 1,000-keyword monthly sweep.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Yandex have a search API?
&lt;/h2&gt;

&lt;p&gt;Technically yes, which makes this different from most sources I scrape. Yandex offers developer search APIs, but getting there means account registration in the Yandex ecosystem, API keys, quota tiers, and output built for site owners rather than rank trackers. What you don't get is the SERP as users see it: the ads, the knowledge graph card, the inline image and video blocks. A scraper-as-API fills that hole. You send a keyword and a region, and you get back the live results page as structured JSON, no key ceremony involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Yandex tracking data looks like
&lt;/h2&gt;

&lt;p&gt;The Yandex Rank Tracker API returns each search result as its own JSON row: ranking position, title, target URL, snippet, favicon, publication date, and rich snippets when present.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Position&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rank on the page, the number you're tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CRM для малого бизнеса&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Result headline as served&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://example.ru/crm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Target link for domain matching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snippet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Попробуйте бесплатно...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Description text under the title&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publication date&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-06-12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When Yandex shows one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rich snippets&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sitelinks, ratings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Present on enhanced results&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Optional result types add paid ads with advertiser metadata, knowledge-graph entity cards, inline image strips, and video carousels. You can localize by domain (yandex.com, .ru, .by, .kz, .uz, .com.tr), pick from 19 interface languages, target a region ID, sort by relevance or date, and paginate as deep as you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;SEO agencies with clients in CIS or Turkish markets, in-house teams that need daily Russian-language rank checks, ad-intelligence analysts watching who bids on which keywords, and builders giving an AI agent a second search engine beyond Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;You can request a Yandex results page yourself and parse it. I tried, and the failure list got long fast. Yandex ships one of the more aggressive captcha walls in search, so unattended scripts stall within minutes. Regional targeting rides on an &lt;code&gt;lr&lt;/code&gt; region ID system you have to map by hand. Cyrillic queries need careful encoding, the markup differs by domain and language, and ad blocks shift position between runs. Every one of those is fixable, and together they become a part-time job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Yandex Rank Tracker API
&lt;/h2&gt;

&lt;p&gt;Documented input in, structured rows out, per-result billing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Rank Tracker API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;text&lt;/code&gt; to your keyword, pick a &lt;code&gt;yandex_domain&lt;/code&gt;, and optionally a region.&lt;/li&gt;
&lt;li&gt;Run it and export the rows as JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~yandex-scrape-yandex-search-results-at-scale---per-result/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "text": "купить квартиру москва", "yandex_domain": "yandex.ru", "lr": "225", "max_pages": 1 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Region &lt;code&gt;225&lt;/code&gt; is Russia; the run endpoint itself is covered in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track Yandex rankings in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/yandex-scrape-yandex-search-results-at-scale---per-result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRM для малого бизнеса&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yandex_domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yandex.ru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;225&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;position&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Match &lt;code&gt;url&lt;/code&gt; against your domain and you have a rank check; loop it over a keyword list and you have a tracker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track 1,000 keywords without a subscription
&lt;/h2&gt;

&lt;p&gt;The flagship task, &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/track-yandex-rankings-for-1-000-keywords?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track Yandex rankings for 1,000 keywords&lt;/a&gt;, shows the bulk pattern. Per-result pricing keeps the budget predictable: 1,000 keywords times a top-10 pull is 10,000 rows, about $150, whether that happens in one run or fifty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitor SERPs and ads on a schedule
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/bulk-collect-yandex-serps-for-seo-monitoring?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Bulk collect Yandex SERPs for SEO monitoring&lt;/a&gt; is the recurring-snapshot setup, and &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/monitor-yandex-search-ads-by-keyword?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Monitor Yandex search ads by keyword&lt;/a&gt; points the same machinery at paid results, advertiser metadata included.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull knowledge graph, images, and video blocks
&lt;/h2&gt;

&lt;p&gt;Rankings are not the whole SERP. &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/get-yandex-knowledge-graph-entity-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Yandex knowledge graph entity data&lt;/a&gt; extracts the entity card, &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/extract-yandex-inline-images-by-query?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Extract Yandex inline images by query&lt;/a&gt; grabs the image strip, and &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/track-yandex-video-results-by-query?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track Yandex video results by query&lt;/a&gt; covers the video carousel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go beyond Russian
&lt;/h2&gt;

&lt;p&gt;There are ready-made tracks for 18 languages and several country markets, from &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/track-turkish-yandex-serps-at-scale?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Turkish SERPs&lt;/a&gt; to &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/track-kazakh-yandex-serps-at-scale?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Kazakh SERPs&lt;/a&gt; to country-level runs like &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/track-yandex-serps-in-georgia?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex SERPs in Georgia&lt;/a&gt;. For the no-code crowd, &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/export-yandex-search-results-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Yandex search results to CSV&lt;/a&gt; skips the code entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let your AI agent read the SERPs
&lt;/h2&gt;

&lt;p&gt;Over the Model Context Protocol, the Actor becomes a tool that Claude, Claude Code, or Cursor can call mid-conversation. Ask "where does mysite.ru rank for 'CRM для малого бизнеса', and who outranks it?" and the agent runs the check against live rows instead of guessing. The task &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result/examples/get-yandex-serp-data-in-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Yandex SERP data in Claude via MCP&lt;/a&gt; walks through the config, and there's more on Claude at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about Yandex tracking with a scraper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How is this Yandex scraper different from the per-page Yandex Search API?
&lt;/h3&gt;

&lt;p&gt;Same structured data, different meter. This Actor bills per result row, which wins for bulk rank tracking where you control exactly how many rows you pull. Its sibling, the &lt;a href="https://apify.com/johnvc/Scrape-Yandex?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Search API&lt;/a&gt;, bills per SERP page and wins for occasional full-page pulls.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does the Yandex scraper cost per run?
&lt;/h3&gt;

&lt;p&gt;About $0.015 per result row plus a small start fee, with no subscription underneath. A top-10 check on one keyword is roughly fifteen cents; new Apify accounts include free platform credit, so trial runs usually cost nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude run this Yandex scraper through MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Add it as an MCP tool and Claude or Cursor can run rank checks during a conversation, with the structured rows coming back as tool output.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I schedule the Yandex scraper for daily tracking?
&lt;/h3&gt;

&lt;p&gt;Save your keyword list as a task, attach an Apify schedule with a cron expression, and each run appends fresh rows you can diff over time. Start from the &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Rank Tracker API&lt;/a&gt; and save your first task.&lt;/p&gt;

&lt;h3&gt;
  
  
  What won't this Yandex scraper tell you?
&lt;/h3&gt;

&lt;p&gt;It reports the SERP for the domain, language, and region you request, which is not the personalized page any single logged-in user sees. It also can't see data Yandex doesn't render, search volume included; pair it with a keyword tool for that half of the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;I've written about the rank-tracking angle elsewhere: the Medium piece &lt;a href="https://medium.com/p/78726be9f96a" rel="noopener noreferrer"&gt;Build a Yandex Rank Tracker: Bulk SERP Monitoring at $0.015 per Result&lt;/a&gt;, the same story &lt;a href="https://www.linkedin.com/pulse/build-yandex-rank-tracker-bulk-serp-monitoring-0015-per-yn0be/" rel="noopener noreferrer"&gt;on LinkedIn&lt;/a&gt;, and a shorter build note &lt;a href="https://peerlist.io/johnvc/articles/how-to-build-a-yandex-rank-tracker-for-1000-keywords" rel="noopener noreferrer"&gt;on Peerlist&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;If your rank tracker goes blank east of Warsaw, this is the fix: per-result Yandex tracking that costs what you pull. Start with the &lt;a href="https://apify.com/johnvc/yandex-scrape-yandex-search-results-at-scale---per-result?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Rank Tracker API&lt;/a&gt; and a ten-keyword test list.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>seo</category>
    </item>
    <item>
      <title>Case Law API: How to Search US Court Opinions in 2026 (Python, MCP, AI Agents)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Tue, 04 Aug 2026 12:03:38 +0000</pubDate>
      <link>https://dev.to/trufflepig/case-law-api-how-to-search-us-court-opinions-in-2026-python-mcp-ai-agents-4klm</link>
      <guid>https://dev.to/trufflepig/case-law-api-how-to-search-us-court-opinions-in-2026-python-mcp-ai-agents-4klm</guid>
      <description>&lt;p&gt;Commercial legal databases charge hundreds of dollars per seat per month, while &lt;a href="https://scholar.google.com/" rel="noopener noreferrer"&gt;Google Scholar's case law search&lt;/a&gt; is free and covers US federal and state opinions back well over a century. The catch is that it only exists as a web page. I wanted that corpus as JSON I could query from scripts and agents, which is what the &lt;a href="https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Case Law API&lt;/a&gt; on Apify does: give it a query like "qualified immunity" and it returns opinions with courts, dates, and citations as structured data.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Google Scholar have a case law API?
&lt;/h2&gt;

&lt;p&gt;No. Google Scholar has never shipped a public API for anything it indexes, and the case law collection is no exception. There is no key to request, no endpoint, no bulk export. The commercial alternatives license their own databases and price accordingly. So in practice a case law API means a scraper you consume like an API: send a query with court and year filters, get opinions back as JSON. That is what this Actor is, and it stays scoped to what Scholar actually publishes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the case law API returns
&lt;/h2&gt;

&lt;p&gt;The case law API returns US court opinions as structured JSON: case title and party names, deciding court, decision date, reporter citation, a snippet, the cited-by count, and the list of cases each opinion cites.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Case title&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Harlow v. Fitzgerald&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Party names as Scholar renders them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Court&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Supreme Court of the United States&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The deciding court&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision date&lt;/td&gt;
&lt;td&gt;&lt;code&gt;June 24, 1982&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Argument and filed dates included when published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Citation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;457 US 800&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reporter citations, page ranges, docket numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cited by&lt;/td&gt;
&lt;td&gt;&lt;code&gt;30,000+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Citation count plus inline citation links&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;result_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;9124178popularname...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identifier used to fetch the full case detail&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A search hit is the light record. Pass its &lt;code&gt;result_id&lt;/code&gt; back through &lt;code&gt;caseIds&lt;/code&gt;, or set &lt;code&gt;fetchCaseDetailsForResults&lt;/code&gt; to true, and you get the full case detail including the complete list of cases the opinion cites. That second layer is what makes citation-graph work possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Three groups keep showing up. Legal researchers and litigation support teams assembling jurisdiction-specific corpora or preloading case metadata before discovery. Developers doing citation analysis, where cited-by counts and cited-case lists become edges in a graph. And people wiring legal search into AI agent workflows, where an agent needs to check real precedent mid-conversation instead of guessing.&lt;/p&gt;

&lt;p&gt;One caution worth stating plainly: this is a research tool that returns what Google Scholar indexes. It is not legal advice, and anything you plan to file should be verified against the official reporter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;The DIY version is a script that requests &lt;code&gt;scholar.google.com/scholar?as_sdt=2006&amp;amp;q=...&lt;/code&gt; and parses the result cards. It works for about ten queries. Scholar is one of the most aggressively bot-protected properties Google runs, so you hit captchas fast, and from a datacenter IP you often get blocked on request one. The court filter is a numeric code system buried in the UI that you have to reverse-engineer, pagination tops out quietly, and the markup shifts under your selectors. I got a prototype working in an afternoon and then spent far longer keeping it alive than building it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Scholar Case Law API
&lt;/h2&gt;

&lt;p&gt;The hosted route is a documented JSON input and a documented JSON output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Case Law API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Enter a &lt;code&gt;query&lt;/code&gt;, and optionally &lt;code&gt;courts&lt;/code&gt;, &lt;code&gt;yearFrom&lt;/code&gt;, and &lt;code&gt;yearTo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON or CSV.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-scholar-case-law/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "query": "qualified immunity", "courts": ["158"], "yearFrom": 2015, "maxResults": 20 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Court code &lt;code&gt;158&lt;/code&gt; is the Supreme Court; leave &lt;code&gt;courts&lt;/code&gt; empty to search every US state and federal court. Endpoint details live in the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search case law in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-scholar-case-law&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Chevron deference&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;courts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;158&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yearFrom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResults&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;court&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feed the &lt;code&gt;result_id&lt;/code&gt; values back in a second run through &lt;code&gt;caseIds&lt;/code&gt; when you want full detail on specific opinions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope a search to one circuit
&lt;/h2&gt;

&lt;p&gt;The task &lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/find-ninth-circuit-opinions-on-qualified-immunity?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Ninth Circuit opinions on qualified immunity&lt;/a&gt; shows court scoping in practice: one court code turns a national search into a jurisdiction-specific corpus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trace a doctrine through the Supreme Court
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/find-supreme-court-cases-citing-chevron-deference?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Supreme Court cases citing Chevron deference&lt;/a&gt; pairs a doctrine query with the SCOTUS court code, which is the starting point for tracking how a standard evolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export results to a spreadsheet
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/export-case-law-search-results-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export case law search results to CSV&lt;/a&gt; is the no-code path: run the search, download the dataset as CSV, hand it to whoever works in Excel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the free credit
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/search-us-case-law-with-a-free-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Search US case law with a free API&lt;/a&gt; shows the cheapest possible run. New Apify accounts include platform credit, and a search-only run bills half a cent per result, so first experiments usually cost nothing out of pocket.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search US precedent in Chinese
&lt;/h2&gt;

&lt;p&gt;A pair of tasks serve Chinese-speaking legal researchers who need US precedent. The first, &lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/meiguo-shangye-mimi-panli-jiansuo?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;US trade secret case search&lt;/a&gt;, covers trade secret disputes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull US patent infringement precedents
&lt;/h2&gt;

&lt;p&gt;The companion task &lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/meiguo-zhuanli-qinquan-panli?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;US patent infringement case law&lt;/a&gt; does the same for patent litigation, using the &lt;code&gt;language&lt;/code&gt; input to localize the interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put case law inside AI agent workflows
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor over the Model Context Protocol, so Claude, Claude Code, and Cursor can call it as a tool. An agent can search a doctrine, pull the full detail for the top hit, and cite real opinions instead of hallucinating them, which is the failure mode that gets people sanctioned. The task &lt;a href="https://apify.com/johnvc/google-scholar-case-law/examples/do-legal-research-in-claude-with-a-case-law-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Do legal research in Claude with a case law MCP&lt;/a&gt; has the setup, and you can read more about Claude at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google Scholar case law
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does the case law scraper cost to run?
&lt;/h3&gt;

&lt;p&gt;Billing is per event: half a cent per search result and one cent per full case detail, plus a fraction of a cent when a run starts. A 20-result search-only run is about a dime. Full details are off by default so a cheap search stays cheap, and Apify's free credit covers early usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I run the case law scraper from Python?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;apify-client&lt;/code&gt; as shown above: pass a &lt;code&gt;query&lt;/code&gt; with optional &lt;code&gt;courts&lt;/code&gt; and year bounds, then iterate the dataset. For citation-graph work, collect &lt;code&gt;result_id&lt;/code&gt; values and run them back through &lt;code&gt;caseIds&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent use this case law scraper through MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Connected over MCP, the Actor shows up as a callable tool in Claude, Claude Code, or Cursor, so agent workflows can ground their legal answers in opinions that actually exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to watch for new opinions?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your query as a task, attach an Apify schedule, and enable &lt;code&gt;sortByDate&lt;/code&gt; so the newest decisions surface first. Repeated runs against a watchlist query is how the monitoring use case works; start from the &lt;a href="https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Case Law API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the honest limits of a case law scraper?
&lt;/h3&gt;

&lt;p&gt;It returns what Google Scholar indexes, nothing more. You get citations and cited-by counts, but not editorial treatment signals, so it will not tell you a case was overruled the way a paid citator does. Coverage of very recent or very obscure opinions depends on Scholar's own indexing. Treat the output as research input, not legal advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Related Actors from the same shop, all returning structured JSON: the &lt;a href="https://apify.com/johnvc/google-scholar-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar API&lt;/a&gt; for academic papers and citations, the &lt;a href="https://apify.com/johnvc/google-scholar-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Lite API&lt;/a&gt; for lighter search runs, and the &lt;a href="https://apify.com/johnvc/google-patents-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Patents API&lt;/a&gt; for the patent side of IP research.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Google Scholar's case law collection is the best free corpus of US opinions, and now it behaves like an API. Run the &lt;a href="https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Case Law API&lt;/a&gt; and start with a single query and a court code.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>legaltech</category>
    </item>
    <item>
      <title>Google Scholar API for Bulk Paper Search: $1.50 per 1,000 Papers (2026)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Mon, 03 Aug 2026 17:09:01 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-scholar-api-for-bulk-paper-search-150-per-1000-papers-2026-4cn7</link>
      <guid>https://dev.to/trufflepig/google-scholar-api-for-bulk-paper-search-150-per-1000-papers-2026-4cn7</guid>
      <description>&lt;p&gt;Every literature review starts the same way: a search on &lt;a href="https://scholar.google.com" rel="noopener noreferrer"&gt;Google Scholar&lt;/a&gt;, then hours of copying titles, authors, years, and citation counts into a spreadsheet. Scholar has no API, blocks scrapers with enthusiasm, and caps how fast a human can click. The &lt;a href="https://apify.com/johnvc/google-scholar-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Lite API&lt;/a&gt; on Apify is my answer for the bulk half of that problem: send a list of queries, get clean paper records back at $1.50 per 1,000 papers.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Google Scholar have an API?
&lt;/h2&gt;

&lt;p&gt;No, and it never has. There is no official endpoint, no key to request, and the site is notoriously quick to throw captchas at anything that looks automated. For one-off searches that is a nuisance; for a systematic review with forty queries, it is a wall. So a Google Scholar API in practice means a scraper-style service you call like an API: queries in, structured paper metadata out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Scholar Lite API returns
&lt;/h2&gt;

&lt;p&gt;The Google Scholar Lite API returns one record per paper as structured JSON: title, authors, journal, publication year, citation count, result snippet, and links to the paper and its PDF or HTML full text.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;title&lt;/td&gt;
&lt;td&gt;"Attention Is All You Need"&lt;/td&gt;
&lt;td&gt;Paper title&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;authors&lt;/td&gt;
&lt;td&gt;Vaswani et al.&lt;/td&gt;
&lt;td&gt;Author list&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;journal&lt;/td&gt;
&lt;td&gt;NeurIPS&lt;/td&gt;
&lt;td&gt;Venue or journal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;year&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2017&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publication year&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;citation count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;140000+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The bibliometric headline number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;links&lt;/td&gt;
&lt;td&gt;paper page, PDF or HTML&lt;/td&gt;
&lt;td&gt;Full-text link when one is available&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each record also carries a stable identifier and the originating query, which matters when you run dozens of searches in one batch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Researchers and grad students building literature-review shortlists across many queries, bibliometrics folks assembling citation datasets, and developers giving a research agent a live paper-search tool instead of a stale index.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Scraping Scholar directly is a rite of passage that ends the same way for everyone: the first page works, the fifth page gets a captcha, and by page twenty your IP is on a timeout. Add parsing citation counts out of HTML and stitching pagination, and the collection script becomes the project. I wrote one in grad-school style years ago; the captchas won.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Scholar Lite API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-scholar-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Lite API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Add your &lt;code&gt;searchTerms&lt;/code&gt;, optionally a &lt;code&gt;yearFrom&lt;/code&gt; and &lt;code&gt;yearTo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-scholar-lite-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "searchTerms": ["transformer attention mechanism"], "yearFrom": 2020, "maxResultsPerSearch": 50 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bulk paper search in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-scholar-lite-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;searchTerms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transformer attention mechanism&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CRISPR gene editing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yearFrom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResultsPerSearch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;paper&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each query is searched independently, so the records arrive pre-grouped for per-topic shortlists, with the citation count and full-text link in every row.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export Scholar results to CSV in bulk
&lt;/h2&gt;

&lt;p&gt;Most reviews live in spreadsheets, and the dataset export goes straight there. The task &lt;a href="https://apify.com/johnvc/google-scholar-lite-api/examples/export-google-scholar-search-results-to-csv-in-bulk?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Google Scholar search results to CSV in bulk&lt;/a&gt; runs a batch and hands you the CSV.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scrape Scholar for a PRISMA systematic review
&lt;/h2&gt;

&lt;p&gt;Systematic reviews need reproducible, screening-ready records: fixed queries, year bounds, exported results. &lt;a href="https://apify.com/johnvc/google-scholar-lite-api/examples/scrape-google-scholar-for-a-prisma-systematic-review?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Scrape Google Scholar for a PRISMA systematic review&lt;/a&gt; is that protocol saved as a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  It works in other languages too
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;language&lt;/code&gt; input localizes results, and two Chinese-language tasks show it in practice: &lt;a href="https://apify.com/johnvc/google-scholar-lite-api/examples/piliang-daochu-google-xueshu-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;bulk export Google Scholar to CSV in Chinese&lt;/a&gt; and a &lt;a href="https://apify.com/johnvc/google-scholar-lite-api/examples/wenxian-zongshu-jiansuo-nianfen?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;literature review search by year range in Chinese&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Research agents are the newest heavy users of Scholar data, and this Actor is MCP-ready: Claude, Claude Code, and Cursor can call it mid-conversation to ground an answer in actual papers. The task &lt;a href="https://apify.com/johnvc/google-scholar-lite-api/examples/bulk-google-scholar-search-for-claude-agents-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Bulk Google Scholar search for Claude agents via MCP&lt;/a&gt; has the setup, and you can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google Scholar
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Google Scholar have an official API, or do I need a scraper?
&lt;/h3&gt;

&lt;p&gt;There is no official API and no sign of one coming, so programmatic access means a scraper-style service. This one behaves like an API: JSON input, JSON output, no captchas on your side.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does the Google Scholar scraper cost?
&lt;/h3&gt;

&lt;p&gt;Pay per paper, from $1.50 per 1,000 papers, with no setup or per-run fee. &lt;code&gt;maxResultsPerSearch&lt;/code&gt; caps each query (default 100), so a forty-query review has a predictable ceiling, and new Apify accounts include free credit that covers a pilot run.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is the Lite scraper different from the full Google Scholar API?
&lt;/h3&gt;

&lt;p&gt;Lite does one thing at bulk prices: search results with core metadata (title, authors, venue, year, citation count, links). The full &lt;a href="https://apify.com/johnvc/google-scholar-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar API&lt;/a&gt; adds the deeper Scholar surfaces: citation formats like BibTeX and APA, author profiles with h-index, per-article citation history, and co-author networks. Shortlists on Lite, deep dives on the full version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper support a PRISMA-style systematic review?
&lt;/h3&gt;

&lt;p&gt;Yes. Fixed queries plus &lt;code&gt;yearFrom&lt;/code&gt; and &lt;code&gt;yearTo&lt;/code&gt; bounds give you a reproducible search protocol, and the exported records are ready for title-and-abstract screening. The PRISMA task above is the template.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude use this Scholar scraper over MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Connected through the Apify MCP server, the Actor becomes a tool an agent can call, which is what people searching for a Google Scholar MCP are usually trying to build.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to track citations over time?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your query set as a task, attach an Apify schedule, and re-run monthly; comparing citation counts across runs gives you a citation-velocity view of a field. Start from the &lt;a href="https://apify.com/johnvc/google-scholar-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Lite API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;The academic shelf has three neighbors: the full &lt;a href="https://apify.com/johnvc/google-scholar-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar API&lt;/a&gt; for citations, profiles, and networks, the &lt;a href="https://apify.com/johnvc/google-scholar-case-law?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Case Law API&lt;/a&gt; for court opinions, and the &lt;a href="https://apify.com/johnvc/google-patents-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Patents API&lt;/a&gt; for the prior-art side of research.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Literature reviews should start with data, not data entry. The &lt;a href="https://apify.com/johnvc/google-scholar-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Scholar Lite API&lt;/a&gt; turns a query list into a paper dataset for less than the coffee you would drink copying it by hand.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Reverse Image Search API: Trace Any Image Across the Web in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Mon, 03 Aug 2026 12:10:08 +0000</pubDate>
      <link>https://dev.to/trufflepig/reverse-image-search-api-trace-any-image-across-the-web-in-2026-4m9a</link>
      <guid>https://dev.to/trufflepig/reverse-image-search-api-trace-any-image-across-the-web-in-2026-4m9a</guid>
      <description>&lt;p&gt;Ask anyone who does image investigations and they will tell you the same quiet truth: &lt;a href="https://yandex.com/images" rel="noopener noreferrer"&gt;Yandex Images&lt;/a&gt; is the strongest reverse image engine on the open web, especially for finding re-uses and earlier versions of a picture. The catch is that it only works one image at a time, in a browser. The &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Reverse Image Search API&lt;/a&gt; on Apify removes the catch: give it an image URL, get everything Yandex knows about that image as structured JSON.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a reverse image search API?
&lt;/h2&gt;

&lt;p&gt;Not from the engines themselves. The reverse image tools people actually rely on are browser interfaces, and Yandex has never shipped a public API for its image engine. Cloud vision products will label an image for you, but "what is in this picture" is a different question from "where does this picture appear online," and the second one is what usage tracking, fact-checking, and brand protection need. So a reverse image search API in practice means a scraper you call like an API: image URL in, typed result rows out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Yandex Reverse Image Search API returns
&lt;/h2&gt;

&lt;p&gt;The Yandex Reverse Image Search API returns typed JSON rows for one image: matching pages, visually similar images, other sizes, product matches, descriptive tags, and an entity card when the subject is recognizable.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;result_type&lt;/th&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;matching_page&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;page title, link, snippet&lt;/td&gt;
&lt;td&gt;Every page where the image appears&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;similar_image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;thumbnail and source link&lt;/td&gt;
&lt;td&gt;Visually similar content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;other resolutions&lt;/td&gt;
&lt;td&gt;Large, medium, small versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shopping_result&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;product match with price&lt;/td&gt;
&lt;td&gt;E-commerce listings that match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image_tag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;descriptive search terms&lt;/td&gt;
&lt;td&gt;What Yandex thinks is in the image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;knowledge_graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;entity card&lt;/td&gt;
&lt;td&gt;For recognizable people, places, brands&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every row carries the query image reference, the source domain, and a search timestamp, and section toggles control which types a run returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Photographers and brands tracking unauthorized use of their images, fact-checkers and OSINT researchers tracing a photo back to its first appearance, and e-commerce teams hunting marketplace listings that look suspiciously like their products.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;The manual loop is uploading an image to Yandex, scrolling the sections, and copying links into a sheet, then doing it again for the next 200 product photos. Automating that interface yourself means driving a JavaScript-heavy page through regional domains and parsing several visually distinct result sections. It is exactly the kind of scraper that works on Tuesday and not on Friday. I would rather write the analysis code than babysit the collection code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Yandex Reverse Image Search API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Reverse Image Search API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Paste a public &lt;code&gt;image_url&lt;/code&gt; and pick the result sections you want.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~yandex-reverse-image-search/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "image_url": "https://substack-post-media.s3.amazonaws.com/public/images/edbfb2cd-ebcb-4527-bec7-5315c182278f_445x445.png", "max_results": 20 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;. The task &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/reverse-image-search-with-yandex-results-as-json?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Reverse image search with Yandex, results as JSON&lt;/a&gt; is this call saved and runnable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse image search in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/yandex-reverse-image-search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image_url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://substack-post-media.s3.amazonaws.com/public/images/edbfb2cd-ebcb-4527-bec7-5315c182278f_445x445.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;include_matching_pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;include_similar_images&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source_domain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Filter on &lt;code&gt;result_type&lt;/code&gt; and each section becomes its own dataset: pages for usage tracking, similar images for dataset building, shopping rows for brand protection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find where an image appears online
&lt;/h2&gt;

&lt;p&gt;The core move for usage tracking: matching pages with title, link, and context per appearance. The task &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/find-where-an-image-appears-online-with-yandex?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find where an image appears online with Yandex&lt;/a&gt; runs it in one click.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trace an image to its original source
&lt;/h2&gt;

&lt;p&gt;For provenance work, other sizes and earlier appearances are the trail. &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/trace-an-image-to-its-original-source-with-yandex?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Trace an image to its original source with Yandex&lt;/a&gt; is tuned for exactly that fact-checking workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find visually similar images
&lt;/h2&gt;

&lt;p&gt;Similarity search feeds ML datasets and content curation. &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/find-visually-similar-images-from-an-image-url?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find visually similar images from an image URL&lt;/a&gt; returns the lookalikes with thumbnails and source links.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find products from an image
&lt;/h2&gt;

&lt;p&gt;Turn on shopping matches and the Actor becomes a counterfeit detector: listings that match your product photo, with prices. &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/find-products-from-an-image-with-yandex?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find products from an image with Yandex&lt;/a&gt; shows it working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Over MCP, Claude, Claude Code, and Cursor can run reverse image searches as a tool call: paste an image URL into a conversation and ask "where else does this appear online." The task &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search/examples/reverse-image-search-in-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Reverse image search in Claude via MCP&lt;/a&gt; has the config, and you can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping reverse image results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is there a free reverse image search scraper?
&lt;/h3&gt;

&lt;p&gt;This one bills per result row, and &lt;code&gt;max_results&lt;/code&gt; puts a hard cap on a run before it starts, so a 20-row test run costs very little. New Apify accounts include free platform credit, which covers your first investigations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI like Grok or Claude do reverse image search, or do I need a scraper?
&lt;/h3&gt;

&lt;p&gt;Chat AIs can describe an image, but describing is not indexing; they cannot tell you which pages host that exact file. The scraper queries a real reverse-image index, and over MCP an AI can call it, which gets you both halves: retrieval from Yandex, reasoning from the model.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the scraper help with source hunting?
&lt;/h3&gt;

&lt;p&gt;Source hunting is working backward from a compressed, cropped copy to the original. The other-sizes rows surface higher-resolution versions, and matching pages show every appearance with context, so you can follow the trail to the earliest, cleanest instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper work in Claude via MCP?
&lt;/h3&gt;

&lt;p&gt;Yes, and there is a saved task demonstrating it linked above. The Actor shows up as a callable tool once the Apify MCP server is connected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to monitor image use?
&lt;/h3&gt;

&lt;p&gt;Yes. Save a task per image set, attach an Apify schedule, and diff the matching-page domains between runs to catch new unauthorized uses early. Start from the &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Reverse Image Search API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the limits of this reverse image scraper?
&lt;/h3&gt;

&lt;p&gt;The image must be publicly reachable over http(s), since Yandex fetches it; localhost and private links will not work. Results reflect Yandex's index and can differ across the six regional domains. And its face-matching strength deserves the obvious caveat: use it responsibly and lawfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Two related Actors from the same shelf: the &lt;a href="https://apify.com/johnvc/Scrape-Yandex?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Search Scraper&lt;/a&gt; for Yandex's text SERPs, and the &lt;a href="https://apify.com/johnvc/google-images-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Images API&lt;/a&gt; for keyword-driven image search on the Google side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Reverse image search was the last search vertical without an API. The &lt;a href="https://apify.com/johnvc/yandex-reverse-image-search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Yandex Reverse Image Search API&lt;/a&gt; fixes that with typed JSON rows you can filter, schedule, and build on.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>computervision</category>
    </item>
    <item>
      <title>Google News API at Scale: Monitor 100 Keywords for Headlines in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sun, 02 Aug 2026 17:09:43 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-news-api-at-scale-monitor-100-keywords-for-headlines-in-2026-45a6</link>
      <guid>https://dev.to/trufflepig/google-news-api-at-scale-monitor-100-keywords-for-headlines-in-2026-45a6</guid>
      <description>&lt;p&gt;News monitoring gets expensive fast when every article costs a full-fat scrape. Most monitoring jobs do not need full articles; they need headlines, sources, and links for a hundred keywords, every morning. &lt;a href="https://news.google.com" rel="noopener noreferrer"&gt;Google News&lt;/a&gt; already aggregates that, so I built the &lt;a href="https://apify.com/johnvc/google-news-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News Lite API&lt;/a&gt; on Apify to read it cheaply: send search terms, get one JSON row per matching article.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Google News have an API?
&lt;/h2&gt;

&lt;p&gt;No. Google retired its official News API years ago and never replaced it, so the question "how do I get a Google News API" keeps getting asked and keeps having the same answer. RSS feeds exist, but they were built for feed readers, not for monitoring: filtering is limited and running a hundred keyword feeds gets unwieldy. The working answer is a scraper you call like an API: search terms in, structured headline rows out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google News Lite API returns
&lt;/h2&gt;

&lt;p&gt;The Google News Lite API returns one row per article as structured JSON: title, link, source, snippet, date, and image, plus the rank, the matching query term, and your targeting metadata.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Apple Vision Pro gets enterprise push"&lt;/td&gt;
&lt;td&gt;The headline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;article URL&lt;/td&gt;
&lt;td&gt;Direct to the publisher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;source&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"The Verge"&lt;/td&gt;
&lt;td&gt;Publisher name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;snippet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;short excerpt&lt;/td&gt;
&lt;td&gt;Enough for triage and sentiment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"3 hours ago"&lt;/td&gt;
&lt;td&gt;Relative publication date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;thumbnail URL&lt;/td&gt;
&lt;td&gt;When available&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rows are de-duplicated by URL per query, and each run collects up to about 100 articles per search term.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;PR and comms teams watching brand and executive coverage, analysts tracking markets or technologies for breaking developments, and developers feeding fresh headlines into agent workflows, alerting, or NLP pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Scraping Google News directly starts with consent pages and ends with parser archaeology. The markup rotates, dates arrive as relative strings in whatever language the region serves, and the same story appears five times under five URLs. By the time you have handled localization, de-duplication, and blocking, your "quick headline fetch" has a backlog. I keep a graveyard folder of half-finished news parsers; it is not small.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google News Lite API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-news-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News Lite API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Add your &lt;code&gt;searchTerms&lt;/code&gt; and pick a &lt;code&gt;timeRange&lt;/code&gt; like &lt;code&gt;day&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-news-lite-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "searchTerms": ["Apple Vision Pro", "OpenAI"], "timeRange": "day", "maxResultsPerSearch": 25 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitor headlines in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-news-lite-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;searchTerms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Apple Vision Pro&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OpenAI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timeRange&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;day&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResultsPerSearch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each term is searched separately, so the output is already grouped for per-keyword reporting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a daily news digest feed
&lt;/h2&gt;

&lt;p&gt;The digest is the classic setup: a fixed term list, &lt;code&gt;timeRange&lt;/code&gt; set to &lt;code&gt;day&lt;/code&gt;, one run every morning. The task &lt;a href="https://apify.com/johnvc/google-news-lite-api/examples/build-a-daily-news-digest-feed-by-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build a daily news digest feed by API&lt;/a&gt; is that configuration ready to clone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bulk monitor 100 keywords at once
&lt;/h2&gt;

&lt;p&gt;Per-article billing is what makes wide keyword nets affordable, since a quiet keyword costs almost nothing. &lt;a href="https://apify.com/johnvc/google-news-lite-api/examples/bulk-monitor-news-for-100-keywords-at-once?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Bulk monitor news for 100 keywords at once&lt;/a&gt; shows the wide-net pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  It works in other languages too
&lt;/h2&gt;

&lt;p&gt;Country and language are input fields, not an afterthought. Two Chinese-language tasks prove the point: a &lt;a href="https://apify.com/johnvc/google-news-lite-api/examples/meiri-zhongwen-xinwen-zhaiyao?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;daily Chinese news digest&lt;/a&gt; and &lt;a href="https://apify.com/johnvc/google-news-lite-api/examples/piliang-jiankong-pinpai-xinwen?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;bulk brand monitoring in Chinese&lt;/a&gt;. Swap &lt;code&gt;country&lt;/code&gt; and &lt;code&gt;language&lt;/code&gt; and the same recipes run for any market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Because the Actor is MCP-ready, Claude, Claude Code, and Cursor can pull fresh headlines mid-conversation: "what happened around our brand in the last 24 hours" becomes a tool call with real citations. The task &lt;a href="https://apify.com/johnvc/google-news-lite-api/examples/feed-google-news-headlines-to-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Feed Google News headlines to Claude via MCP&lt;/a&gt; has the setup, and you can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google News
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is this Google News scraper free?
&lt;/h3&gt;

&lt;p&gt;It bills per article returned, with no setup fee, and &lt;code&gt;maxResultsPerSearch&lt;/code&gt; caps each term at up to 100 articles so spend is bounded before the run starts. New Apify accounts include free platform credit, which covers a lot of headlines.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is the Lite scraper different from the full Google News API?
&lt;/h3&gt;

&lt;p&gt;Lite is the cheap, headline-level variant: title, link, source, snippet, date, and image, capped at 100 articles per term, with country and language targeting. The full &lt;a href="https://apify.com/johnvc/GoogleNewsAPI?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News API&lt;/a&gt; adds location-based searches, safe search, and pagination control. If you need those, use the full version; if you are monitoring keywords at volume, Lite is the better price.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper return full article text?
&lt;/h3&gt;

&lt;p&gt;No, and that is a deliberate trade. You get the headline, snippet, source, and a direct link; if a story matters, fetch the article from the link. Keeping rows headline-level is what keeps 100-keyword monitoring cheap.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does a media monitoring scraper actually collect?
&lt;/h3&gt;

&lt;p&gt;Coverage over time: who wrote about a term, when, where, and with what framing in the headline and snippet. Stack daily runs and you have share-of-voice, source breakdowns, and a timeline of how a story developed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude call the news scraper through MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect the Apify MCP server and the Actor appears as a callable tool, so agents and chat sessions can ground themselves in the day's coverage instead of last year's training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper for an automatic daily digest?
&lt;/h3&gt;

&lt;p&gt;Yes, that is its natural habitat. Save your term list as a task, attach an Apify schedule (a cron line like &lt;code&gt;0 7 * * *&lt;/code&gt;), and read the fresh dataset each morning. Start from the &lt;a href="https://apify.com/johnvc/google-news-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News Lite API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Related Actors for adjacent feeds: the full &lt;a href="https://apify.com/johnvc/GoogleNewsAPI?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News API&lt;/a&gt; when you need deeper search control, the &lt;a href="https://apify.com/johnvc/google-finance-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Finance API&lt;/a&gt; for the market-data side of a monitoring stack, and the &lt;a href="https://apify.com/johnvc/google-forums-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Forums Search API&lt;/a&gt; for what discussion boards say before the press does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Headline monitoring should be boring and cheap, not a scraping project. The &lt;a href="https://apify.com/johnvc/google-news-lite-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google News Lite API&lt;/a&gt; keeps it that way: search terms in, one row per article out, billed per article.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Google Ads Transparency API: See Every Ad a Competitor Runs (2026 Guide)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sun, 02 Aug 2026 12:10:28 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-ads-transparency-api-see-every-ad-a-competitor-runs-2026-guide-1jkm</link>
      <guid>https://dev.to/trufflepig/google-ads-transparency-api-see-every-ad-a-competitor-runs-2026-guide-1jkm</guid>
      <description>&lt;p&gt;Your competitor's entire Google ad history is public. The &lt;a href="https://adstransparency.google.com" rel="noopener noreferrer"&gt;Google Ads Transparency Center&lt;/a&gt; lists every ad an advertiser runs: format, when it first appeared, whether it is still live. What it does not offer is any way to get that list out; you scroll and squint. The &lt;a href="https://apify.com/johnvc/google-ads-transparency-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Ads Transparency API&lt;/a&gt; on Apify closes the loop: give it an advertiser ID, get the ad library back as structured JSON.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does the Ads Transparency Center have an API?
&lt;/h2&gt;

&lt;p&gt;No. Google built the Transparency Center as a browsing experience, and there is no official endpoint, no export button, and no bulk access. For a growth team that wants to diff a competitor's creatives month over month, that is a dead end. So a Google Ads Transparency API in practice means a scraper you call like an API: advertiser ID in, one JSON row per ad out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Ads Transparency API returns
&lt;/h2&gt;

&lt;p&gt;The Google Ads Transparency API returns every ad in an advertiser's public library as structured JSON: advertiser identity, creative identifier, ad format, first and last shown dates, total days running, and a preview link.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;advertiser&lt;/td&gt;
&lt;td&gt;name and ID&lt;/td&gt;
&lt;td&gt;Whose library you pulled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;creative ID&lt;/td&gt;
&lt;td&gt;stable identifier&lt;/td&gt;
&lt;td&gt;For diffing across runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;format&lt;/td&gt;
&lt;td&gt;text, image, or video&lt;/td&gt;
&lt;td&gt;Creative type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;first shown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2025-11-02&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When the ad first appeared&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;last shown&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-07-12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Most recent sighting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;days running&lt;/td&gt;
&lt;td&gt;&lt;code&gt;252&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Longevity, the cheap proxy for performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Long-running creatives are the interesting ones: nobody pays to run a loser for eight months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Growth marketers who want a competitor ad library they can query, agencies auditing a prospect's creative mix before a pitch, researchers tracking political advertisers, and builders wiring competitive ad data into AI marketing agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;The manual approach is opening the Transparency Center, scrolling an infinite list, and screenshotting ads into a slide deck. It produces an artifact you cannot query, sort, or diff, and it is stale the day you make it. Automating the browsing yourself runs into the usual wall: a JavaScript-rendered interface with pagination behavior and markup that shift under you. I did the screenshot-deck version once for a client review; never again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Ads Transparency API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-ads-transparency-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Ads Transparency API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Paste an &lt;code&gt;advertiserId&lt;/code&gt;, the &lt;code&gt;AR...&lt;/code&gt; code from any Transparency Center advertiser URL.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-ads-transparency-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "advertiserId": "AR01614014350098432001", "maxResultsPerAdvertiser": 50 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull an ad library in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-ads-transparency-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;advertiserIds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AR01614014350098432001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResultsPerAdvertiser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ad&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each row is one creative with its format, run dates, and preview link, which is everything a diff or a dashboard needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spy on competitor Google ads
&lt;/h2&gt;

&lt;p&gt;The starter move: pull a rival's full library and see what they are actually running, not what they say they are running. The task &lt;a href="https://apify.com/johnvc/google-ads-transparency-api/examples/spy-on-competitor-google-ads?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Spy on competitor Google ads&lt;/a&gt; is that pull, saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit an advertiser's creative mix
&lt;/h2&gt;

&lt;p&gt;Formats tell a strategy story: an advertiser shifting from text to video is changing their funnel. &lt;a href="https://apify.com/johnvc/google-ads-transparency-api/examples/audit-advertiser-google-ad-creatives?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Audit advertiser Google ad creatives&lt;/a&gt; breaks a library down by format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Track how long competitor ads run
&lt;/h2&gt;

&lt;p&gt;Days-running is the closest thing to public performance data. &lt;a href="https://apify.com/johnvc/google-ads-transparency-api/examples/track-competitor-ad-duration?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track competitor ad duration&lt;/a&gt; surfaces the long-lived creatives worth studying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch political advertisers
&lt;/h2&gt;

&lt;p&gt;The same mechanics work for accountability research. &lt;a href="https://apify.com/johnvc/google-ads-transparency-api/examples/political-advertiser-google-ads?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Political advertiser Google ads&lt;/a&gt; pulls a political advertiser's public library into analyzable rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export an ad library to CSV
&lt;/h2&gt;

&lt;p&gt;For the spreadsheet crowd, &lt;a href="https://apify.com/johnvc/google-ads-transparency-api/examples/export-advertiser-google-ads-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export advertiser Google ads to CSV&lt;/a&gt; runs the pull and hands you a CSV, no code involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;The Actor is MCP-ready, so Claude, Claude Code, and Cursor can call it as a tool: "pull the last 100 ads from these two competitors and tell me what changed since last month" becomes a prompt instead of a project. You can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping the Ads Transparency Center
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is there a free Google Ads Transparency scraper?
&lt;/h3&gt;

&lt;p&gt;This one bills per ad returned, and &lt;code&gt;maxResultsPerAdvertiser&lt;/code&gt; (default 50, up to 500) caps the count before a run starts. New Apify accounts include free platform credit, so a first competitor pull usually costs nothing out of pocket.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the scraper find an advertiser's ID?
&lt;/h3&gt;

&lt;p&gt;Open the advertiser in the Transparency Center and copy the &lt;code&gt;AR...&lt;/code&gt; code from the URL; that code is the input. You can pass one ID or a list, and the Actor de-duplicates them for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper show ad spend or targeting data?
&lt;/h3&gt;

&lt;p&gt;No, and be suspicious of anything claiming it can. The public record carries format, run dates, days running, and previews; spend and targeting are not published there. Days running is the honest proxy most teams use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper work in Claude via MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect the Apify MCP server and the Actor appears as a callable tool in Claude, Claude Code, or Cursor, which is how the AI-marketing-agent use case runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to watch competitors' ad libraries?
&lt;/h3&gt;

&lt;p&gt;Yes, snapshots are the whole game: run the same advertiser list weekly, diff the creative IDs, and you get alerts on new launches and quiet retirements. Start from the &lt;a href="https://apify.com/johnvc/google-ads-transparency-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Ads Transparency API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Adjacent lenses on the same competitive questions: the &lt;a href="https://apify.com/johnvc/google-local-services-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Local Services API&lt;/a&gt; for the Local Services Ads side of Google advertising, and the &lt;a href="https://apify.com/johnvc/Google-AI-Overview-API?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google AI Overview API&lt;/a&gt; for how Google's AI answers describe your market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The Transparency Center already publishes the data; it just never offered a way to use it. The &lt;a href="https://apify.com/johnvc/google-ads-transparency-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Ads Transparency API&lt;/a&gt; turns any advertiser's library into JSON you can diff, chart, and act on.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>datascience</category>
    </item>
    <item>
      <title>YouTube Shorts API: See What Ranks in Google Short Videos in 2026 (Shorts, Reels, TikTok)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sat, 01 Aug 2026 17:08:53 +0000</pubDate>
      <link>https://dev.to/trufflepig/youtube-shorts-api-see-what-ranks-in-google-short-videos-in-2026-shorts-reels-tiktok-475l</link>
      <guid>https://dev.to/trufflepig/youtube-shorts-api-see-what-ranks-in-google-short-videos-in-2026-shorts-reels-tiktok-475l</guid>
      <description>&lt;p&gt;Short-form video has its own SERP now. Search a topic on your phone and &lt;a href="https://www.google.com/search?q=workout+tips" rel="noopener noreferrer"&gt;Google&lt;/a&gt; shows a dedicated short-videos block mixing YouTube Shorts, TikTok, and Instagram Reels, ranked. That block is the scoreboard for short-form content, and no official API returns it. The &lt;a href="https://apify.com/johnvc/google-short-videos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Short Videos API&lt;/a&gt; on Apify scrapes it for you: query in, flat rows of ranked short videos out.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a YouTube Shorts API?
&lt;/h2&gt;

&lt;p&gt;Sort of, and that is the problem. The official YouTube Data API is real and works for YouTube metadata, but it has no view of what ranks in Google's short-videos block, and it knows nothing about TikTok or Reels. Nobody ships an official cross-platform endpoint for "which short videos does Google rank for this topic." So a YouTube Shorts API in the ranking sense means a scraper you call like an API: send a query, get the ranked block back as JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Short Videos API returns
&lt;/h2&gt;

&lt;p&gt;The Google Short Videos API returns each short-form result as a structured row: rank, title, link, preview image, source platform, creator or channel, and clip duration, plus related-search suggestions on mobile and tablet.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rank&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Position in the short-videos block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;title&lt;/td&gt;
&lt;td&gt;"10 minute no-equipment workout"&lt;/td&gt;
&lt;td&gt;As Google shows it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;link&lt;/td&gt;
&lt;td&gt;video URL&lt;/td&gt;
&lt;td&gt;Direct to the clip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;source&lt;/td&gt;
&lt;td&gt;YouTube, TikTok, Facebook&lt;/td&gt;
&lt;td&gt;Platform tag per result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;channel&lt;/td&gt;
&lt;td&gt;creator name&lt;/td&gt;
&lt;td&gt;Who posted it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;duration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0:42&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clip length&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On mobile or tablet device profiles you also get the "people also search for" suggestions, which is free keyword research.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Content strategists deciding what to film next, social teams tracking which platform wins a topic, and SEO folks mining the related-search suggestions for short-form keyword ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Scraping this block yourself means emulating a mobile device, because the desktop page often does not even show it. So you are spoofing user agents, rendering JavaScript, and parsing a carousel whose markup was not designed to be read. Every result looks slightly different depending on the source platform, and the block's layout changes more often than regular results. I would rather maintain almost anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Short Videos API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-short-videos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Short Videos API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Enter a search query in &lt;code&gt;q&lt;/code&gt;; keep &lt;code&gt;device&lt;/code&gt; on mobile to get related searches.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-short-videos-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "q": "air fryer recipes", "device": "mobile", "max_pages": 1 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get ranked short videos in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-short-videos-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;workout tips&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;device&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mobile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_pages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;list_items&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first row shows the shape: rank, title, link, source platform, channel, and duration, ready for a dataframe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search across platforms in one call
&lt;/h2&gt;

&lt;p&gt;One query returns YouTube Shorts, TikTok, and Reels results side by side, each tagged with its source, so platform comparison is a groupby instead of three scrapers. The task &lt;a href="https://apify.com/johnvc/google-short-videos-api/examples/cross-platform-short-video-search-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Cross-platform short video search API&lt;/a&gt; is that setup saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scrape YouTube Shorts and Reels by keyword
&lt;/h2&gt;

&lt;p&gt;For keyword-first research, two tasks cover the recipe: &lt;a href="https://apify.com/johnvc/google-short-videos-api/examples/scrape-youtube-shorts-and-reels-by-keyword?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Scrape YouTube Shorts and Reels by keyword&lt;/a&gt; and &lt;a href="https://apify.com/johnvc/google-short-videos-api/examples/search-youtube-shorts-by-keyword-via-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Search YouTube Shorts by keyword via API&lt;/a&gt;. Point either at your topic list and export.&lt;/p&gt;

&lt;h2&gt;
  
  
  See which TikToks rank on Google
&lt;/h2&gt;

&lt;p&gt;TikTok's own analytics will not tell you what Google ranks. &lt;a href="https://apify.com/johnvc/google-short-videos-api/examples/see-which-tiktoks-rank-on-google-for-air-fryer-recipes?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;See which TikToks rank on Google for air fryer recipes&lt;/a&gt; filters the block down to one platform for one niche, a pattern that transfers to any topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Over MCP, Claude, Claude Code, and Cursor can run this research mid-conversation: "what short videos rank for 'meal prep' and which platform dominates" becomes one prompt. The task &lt;a href="https://apify.com/johnvc/google-short-videos-api/examples/do-short-video-serp-research-in-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Do short video SERP research in Claude via MCP&lt;/a&gt; has the setup, and you can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping short video results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is there a free YouTube Shorts scraper?
&lt;/h3&gt;

&lt;p&gt;Billing here is per page fetched, with about 10 short videos per page and &lt;code&gt;max_pages&lt;/code&gt; capping the spend before a run starts. New Apify accounts include free platform credit, so early research runs typically cost nothing out of pocket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper cover TikTok and Instagram Reels too?
&lt;/h3&gt;

&lt;p&gt;Yes. The block itself is cross-platform, and every row carries a source tag, so you can compare how YouTube, TikTok, and Facebook or Instagram content splits the ranking for a topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper get YouTube Shorts transcripts?
&lt;/h3&gt;

&lt;p&gt;No, this one returns ranking metadata: titles, links, sources, channels, durations. For the words inside the videos, pair it with the &lt;a href="https://apify.com/johnvc/YoutubeTranscripts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;YouTube Transcripts API&lt;/a&gt;, which takes the video links this scraper returns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use this scraper for AI-generated Shorts research?
&lt;/h3&gt;

&lt;p&gt;It will not make videos for you, but it answers the question that should come first: what already ranks for your topic, in what format, at what duration. Plenty of AI-shorts pipelines use exactly this data to pick topics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper work in Claude via MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect the Apify MCP server and it becomes a callable tool in Claude, Claude Code, or Cursor, which is what the SERP-research task above demonstrates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to track short video trends?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your queries as a task, attach an Apify schedule, and the dataset accumulates a ranking history per topic, which is how you catch a format trend early. Start from the &lt;a href="https://apify.com/johnvc/google-short-videos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Short Videos API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Two neighbors in the video and search family: the &lt;a href="https://apify.com/johnvc/YoutubeTranscripts?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;YouTube Transcripts API&lt;/a&gt; for what the videos actually say, and the &lt;a href="https://apify.com/johnvc/google-images-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Images API&lt;/a&gt; for the image side of the SERP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Short-form video rankings are public; they were just never queryable. The &lt;a href="https://apify.com/johnvc/google-short-videos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Short Videos API&lt;/a&gt; makes them a JSON feed you can build on.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>youtube</category>
    </item>
    <item>
      <title>Google Travel API: Get Destination Ideas with Flight Prices as JSON in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sat, 01 Aug 2026 12:10:20 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-travel-api-get-destination-ideas-with-flight-prices-as-json-in-2026-4ngn</link>
      <guid>https://dev.to/trufflepig/google-travel-api-get-destination-ideas-with-flight-prices-as-json-in-2026-4ngn</guid>
      <description>&lt;p&gt;Most flight tools answer "how much to fly from A to B?" The more interesting question is "where can I even go?", and &lt;a href="https://www.google.com/travel/explore" rel="noopener noreferrer"&gt;Google Travel Explore&lt;/a&gt; answers it beautifully: a map of destinations from your airport with flight prices, hotel prices, and suggested dates. Beautifully, but only in a browser. The &lt;a href="https://apify.com/johnvc/google-travel-explore-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Travel Explore API&lt;/a&gt; on Apify turns that surface into structured JSON: one ranked destination list per departure airport.&lt;/p&gt;

&lt;p&gt;Disclosure: the Apify links in this post are affiliate links. If you run the Actor, I may earn a referral commission at no extra cost to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a Google Travel API?
&lt;/h2&gt;

&lt;p&gt;No. Google retired its public flights API years ago and never shipped anything for the Explore surface, so there is no official endpoint that returns "destinations reachable from JFK with prices and dates." A Google Travel API today means a scraper you consume like an API: airport code in, ranked destination ideas out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Travel Explore API returns
&lt;/h2&gt;

&lt;p&gt;The Google Travel Explore API returns ranked destination ideas as structured JSON: destination name and country, destination airport with GPS coordinates, estimated round-trip flight price, estimated nightly hotel price, suggested trip dates, flight duration, and stops.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;destination&lt;/td&gt;
&lt;td&gt;"Lisbon, Portugal"&lt;/td&gt;
&lt;td&gt;Name plus country and destination airport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flight price&lt;/td&gt;
&lt;td&gt;&lt;code&gt;412&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Estimated round trip from your airport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hotel price&lt;/td&gt;
&lt;td&gt;&lt;code&gt;98&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Estimated nightly rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;trip dates&lt;/td&gt;
&lt;td&gt;suggested start and end&lt;/td&gt;
&lt;td&gt;Date-bound, not vague&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;duration and stops&lt;/td&gt;
&lt;td&gt;7h 45m, nonstop&lt;/td&gt;
&lt;td&gt;Flight time and connection count&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;link&lt;/td&gt;
&lt;td&gt;Google Travel URL&lt;/td&gt;
&lt;td&gt;Plus a thumbnail and airline info&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One run can batch several departure airports, and each destination row is self-contained enough to publish or feed to an agent as-is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;Travel content sites building "where can I go on a budget" features, agencies pitching clients ranked ideas instead of one-off quotes, newsletter writers hunting deals from specific hubs, and developers giving an AI travel agent real prices and dates to reason over.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Explore is an interactive map. You pan, hover, and read cards one at a time, and there is no stable URL that captures the result set you are looking at. Automating it means driving a JavaScript-heavy map interface in a headless browser and untangling how the destination data loads behind it, and every layout tweak resets your work. I tried to eyeball-copy twenty destinations into a sheet once and gave up at nine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Google Travel Explore API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apify Console&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/google-travel-explore-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Travel Explore API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;departureId&lt;/code&gt; to an airport code like &lt;code&gt;ATL&lt;/code&gt;, or batch several in &lt;code&gt;departureIds&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it and download the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/johnvc~google-travel-explore-api/runs?token=YOUR_APIFY_TOKEN"&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;"Content-Type: application/json"&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;'{ "departureId": "ATL", "maxResultsPerDeparture": 25 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run endpoint reference: the &lt;a href="https://docs.apify.com/api/v2" rel="noopener noreferrer"&gt;Apify API docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get destination ideas in Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johnvc/google-travel-explore-api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;departureIds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JFK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SFO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxResultsPerDeparture&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;destination&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each row carries the destination, the estimated flight and hotel prices, the suggested dates, and the duration, which is everything a "where should I go" feature needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cheapest places to fly from 20 major cities
&lt;/h2&gt;

&lt;p&gt;The classic use case ships as a ready-made series: one saved task per departure city, twenty in all. A few to start from: &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-atlanta-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Atlanta&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-new-york-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;New York&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-los-angeles-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Los Angeles&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-chicago-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Chicago&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-seattle-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Seattle&lt;/a&gt;, and &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/cheapest-places-to-fly-from-toronto-with-prices?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Toronto&lt;/a&gt;. Each one runs the Explore lookup for that hub and returns the ranked, priced list; the rest of the series lives on the Actor's examples tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export travel destinations to CSV
&lt;/h2&gt;

&lt;p&gt;For editorial workflows the spreadsheet is the product. &lt;a href="https://apify.com/johnvc/google-travel-explore-api/examples/export-travel-destinations-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export travel destinations to CSV&lt;/a&gt; runs a lookup and hands you a CSV ready for sorting, filtering, and publishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;The Actor is MCP-ready, so Claude, Claude Code, and Cursor can call it live: ask "where can I fly from JFK for under $400 with a hotel under $120 a night" and the agent filters real rows instead of hallucinating fares. You can read more about Claude and Claude Code at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google Travel Explore
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is there a free Google Travel scraper?
&lt;/h3&gt;

&lt;p&gt;The Actor bills per destination returned, and &lt;code&gt;maxResultsPerDeparture&lt;/code&gt; (default 50, max 200) caps the count before a run starts, so cost is predictable. New Apify accounts include free platform credit, which easily covers a first exploration.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the scraper choose which destinations to return?
&lt;/h3&gt;

&lt;p&gt;It returns the ranked list Google Travel Explore shows for your departure airport, localized by your &lt;code&gt;gl&lt;/code&gt; and &lt;code&gt;hl&lt;/code&gt; settings. You are getting Google's ordering, not a re-ranking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are the scraper's prices exact bookable fares?
&lt;/h3&gt;

&lt;p&gt;No, and it is worth being clear about this: flight and hotel figures are Google's estimates for the suggested dates, built for discovery rather than checkout. For live itineraries and bookable prices on a specific route, pair it with a flights-level search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI travel agent use this scraper?
&lt;/h3&gt;

&lt;p&gt;Yes, it was built with that in mind. Over MCP the Actor becomes a tool an agent can call, and each destination row arrives with price, dates, and duration attached, so the agent can filter and recommend without extra lookups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to track deals from my airport?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your departure airport as a task, attach an Apify schedule, and each run appends a fresh ranked list, which over time becomes a record of how prices and reachable destinations shift. Start from the &lt;a href="https://apify.com/johnvc/google-travel-explore-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Travel Explore API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More from Truffle Pig Data
&lt;/h2&gt;

&lt;p&gt;Explore answers "where"; two sibling Actors answer the follow-ups. The &lt;a href="https://apify.com/johnvc/Google-Flights-Data-Scraper-Flight-and-Price-Search?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Flights API&lt;/a&gt; prices a specific route with real itineraries, and the &lt;a href="https://apify.com/johnvc/google-hotels-search-scraper?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Hotels Search Scraper&lt;/a&gt; covers where you sleep when you get there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Destination discovery data used to be locked inside an interactive map. The &lt;a href="https://apify.com/johnvc/google-travel-explore-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Travel Explore API&lt;/a&gt; returns it as ranked, priced JSON from any departure airport you care about.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>traveltech</category>
    </item>
  </channel>
</rss>
