<?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>AI Visibility: Find the Pages Where You Rank but Google's AI Cites a Competitor</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Wed, 16 Sep 2026 19:09:37 +0000</pubDate>
      <link>https://dev.to/trufflepig/ai-visibility-find-the-pages-where-you-rank-but-googles-ai-cites-a-competitor-3d75</link>
      <guid>https://dev.to/trufflepig/ai-visibility-find-the-pages-where-you-rank-but-googles-ai-cites-a-competitor-3d75</guid>
      <description>&lt;p&gt;Ranking and being cited are two different problems, and &lt;a href="https://search.google.com/search-console" rel="noopener noreferrer"&gt;Google Search Console&lt;/a&gt; only shows you the first one. You can sit at position 4 on a query, watch an AI Overview answer it with somebody else's page, and see nothing in your reports except a CTR that quietly sags. This post is about closing that gap with evidence: the &lt;a href="https://apify.com/johnvc/ai-overview-rewrite-queue?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;AI Overview Rewrite Queue&lt;/a&gt; on Apify joins your Search Console export with live citation data and hands back a scored list of which pages to rewrite first.&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;
  
  
  Why citation tracking alone is not enough
&lt;/h2&gt;

&lt;p&gt;Most AI visibility tools answer one question: were you cited. That is useful and incomplete, because "not cited" on its own does not tell you whether to act. Not cited on a query you rank 40th for is noise. Not cited on a query you rank 6th for, where a competitor is cited instead, is a page Google already understands that somebody else is answering better. Telling those apart needs your ranking data and your citation data in the same row, which is the join this Actor does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the rewrite queue returns
&lt;/h2&gt;

&lt;p&gt;The API returns one row per query, sorted so the rewrites worth the most come first, with your Search Console metrics and live citation data side by side.&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;query&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;what is a crm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The keyword&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A to X, biggest opportunity first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tier_reason&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One plain sentence&lt;/td&gt;
&lt;td&gt;Explains the call without a legend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;position&lt;/code&gt; / &lt;code&gt;impressions&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;8.4&lt;/code&gt; / &lt;code&gt;1900&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;From your export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ai_overview_present&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether an overview appeared at all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;citation_state&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;competitor_cited&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cited, competitor cited, or no references&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reference_domains&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;["reddit.com", "ibm.com"]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every domain the overview cited, in order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;join_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;matched&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Or &lt;code&gt;gsc_only&lt;/code&gt; / &lt;code&gt;check_only&lt;/code&gt;, never dropped&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A whole-run summary lands in the key-value store: counts per tier, the join rate, and the competitor domains cited most often across your keyword set.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five tiers, and what to do with each
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt; is the money tier: you rank 5 to 20 and a competitor is cited instead of you. Rewrite these first. &lt;strong&gt;B&lt;/strong&gt; is the one people miss, an answer-shape problem rather than an authority problem: you rank top 4 and the AI still passes you over, so restructure the answer instead of chasing links. If citation simply tracked ranking, tier B would always be empty. &lt;strong&gt;C&lt;/strong&gt; means you are cited and still converting below your own baseline, so the overview is satisfying the search. &lt;strong&gt;D&lt;/strong&gt; is ordinary SEO. &lt;strong&gt;X&lt;/strong&gt; means the check did not complete, which is evidence rather than a conclusion.&lt;/p&gt;

&lt;p&gt;Tier C compares each query against your own median CTR at a similar position, computed from the no-overview queries in your export. It never uses an industry benchmark table, because every account's normal is different.&lt;/p&gt;

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

&lt;p&gt;SEO and content people who want a rewrite backlog built from evidence rather than opinion. Anyone tracking AI visibility over time who has noticed that a single check is noise, since the same query can cite you Monday and drop you Thursday. And builders wiring an agent that can pull the tier A list and draft the rewrites in the same session.&lt;/p&gt;

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

&lt;p&gt;You can do this by hand: export Search Console, search each query, note who got cited, paste it into a sheet. It works for twenty queries and falls apart at two hundred. Worse, it quietly produces bad data, because an overview that failed to load looks identical to a query with no overview and both get written down as a zero. That is the failure mode that matters in measurement tools, where a plausible zero reads as an answer instead of a bug, and you end up confidently deprioritizing a page you should have rewritten.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the queue
&lt;/h2&gt;

&lt;p&gt;Open the &lt;a href="https://apify.com/johnvc/ai-overview-rewrite-queue?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;AI Overview Rewrite Queue&lt;/a&gt;, put your domain in &lt;code&gt;target_domains&lt;/code&gt;, and give it your Search Console export as a published-Sheet CSV URL or as pasted rows. No Google sign-in, no OAuth, no service account: it reads an export you already have. From the command line:&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~ai-overview-rewrite-queue/runs?token=YOUR_APIFY_TOKEN"&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="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{ "target_domains": ["example.com"], "search_console_csv_url": "https://docs.google.com/spreadsheets/d/e/EXAMPLE/pub?output=csv", "min_impressions": 50 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;p&gt;To get the export: open the Performance report, pick a date range, open the Queries tab, then Export. For scheduled runs, send it to Google Sheets and use File, Share, Publish to web, comma-separated values, so every run picks up fresh data. Localized headers, semicolon delimiters, comma decimals, and percent signs on CTR all parse without editing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Score your queries 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/ai-overview-rewrite-queue&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;target_domains&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;example.com&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;search_console_csv_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://docs.google.com/spreadsheets/d/e/EXAMPLE/pub?output=csv&lt;/span&gt;&lt;span class="sh"&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="k"&gt;if&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;tier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&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;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;query&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;impressions&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reference_domains&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;Filter to tier A and you have this month's rewrite list in a dozen lines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the queue from Claude via MCP
&lt;/h2&gt;

&lt;p&gt;Through the Model Context Protocol the Actor is a callable tool in Claude, Claude Code, and Cursor. Ask for the tier A list and an agent can pull it and start drafting in the same session, which is a better loop than exporting a CSV and pasting it into a chat window. 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 AI Overview citation scrapers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How does this scraper tell a real "no AI Overview" from a failed check?
&lt;/h3&gt;

&lt;p&gt;They are separate fields and are never conflated. &lt;code&gt;ai_overview_present: false&lt;/code&gt; means the query was checked and no overview appeared. A null with &lt;code&gt;check_status&lt;/code&gt; of &lt;code&gt;retrieval_failed&lt;/code&gt; or &lt;code&gt;blocked&lt;/code&gt; means it could not be checked, and those land in tier X where they can never be scored as a rewrite priority. A failure that reads as a zero is worse than no data at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does this scraper cost to run?
&lt;/h3&gt;

&lt;p&gt;Pay per event: a one-time setup charge per run covering the export parsing, the citation checks, and your CTR baseline, plus a scored-row event per query returned. One thing to know is that the citation checks run on 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; under your own account and are billed separately under that Actor's pricing. That is the larger part of a run's cost. Use &lt;code&gt;min_impressions&lt;/code&gt; to keep the checked set to queries with traffic worth having.&lt;/p&gt;

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

&lt;p&gt;Yes, and you should. A single check is a snapshot, and overviews are volatile enough that one run is not a verdict. Put a published Sheet URL in &lt;code&gt;search_console_csv_url&lt;/code&gt;, attach a Schedule to the &lt;a href="https://apify.com/johnvc/ai-overview-rewrite-queue?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;rewrite queue&lt;/a&gt;, and trend the tiers instead of reading one run.&lt;/p&gt;

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

&lt;p&gt;Yes. Connect the Apify MCP server and it becomes a callable tool in any MCP client, so an agent can fetch the queue and act on it without leaving the conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What can this scraper not tell me?
&lt;/h3&gt;

&lt;p&gt;Whether you were recommended, as opposed to cited. It reports citation, meaning a link to your domain in the overview's sources. Whether the surrounding text recommends you, merely mentions you, or contradicts you is a text-analysis question this does not answer. It also runs the checks from datacenter addresses, so set &lt;code&gt;gl&lt;/code&gt;, &lt;code&gt;hl&lt;/code&gt;, and &lt;code&gt;location&lt;/code&gt; deliberately or a lost citation is indistinguishable from a different exit node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent pay for this scraper in USDC with x402?
&lt;/h3&gt;

&lt;p&gt;Yes. The AI Overview Rewrite Queue supports agentic payments via the &lt;a href="https://docs.apify.com/platform/integrations/x402" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt;, so AI agents and MCP clients can pay for runs in USDC on Base with no Apify account or API token. Point your agent at the &lt;a href="https://mcp.apify.com/?tools=actors,docs,johnvc/ai-overview-rewrite-queue" rel="noopener noreferrer"&gt;Apify MCP server&lt;/a&gt; and it can discover, pay for, and run the scraper autonomously; the &lt;a href="https://apify.com/change-log/pay-for-apify-actors-with-x402?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apify x402 announcement&lt;/a&gt; has the details.&lt;/p&gt;

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

&lt;p&gt;The citation checks behind this one, usable on their own for raw overview text and sources: &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;. The same visibility question on a different answer engine: &lt;a href="https://apify.com/johnvc/brave-ai-mode-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Brave AI Mode API&lt;/a&gt;. For Korean search: &lt;a href="https://apify.com/johnvc/naver-ai-overview-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Naver AI Overview API&lt;/a&gt;. And to find the question-shaped queries that trigger overviews in the first place: &lt;a href="https://apify.com/johnvc/google-autocomplete-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Autocomplete API&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;A citation trendline can sit flat and green while your clicks fall, because the overview is answering for you either way. Export Search Console once, point the &lt;a href="https://apify.com/johnvc/ai-overview-rewrite-queue?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;AI Overview Rewrite Queue&lt;/a&gt; at it, and open the tier A rows first.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>Companies Using Workday: How to Build a Customer List with Live Open-Role Counts in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Tue, 15 Sep 2026 19:08:58 +0000</pubDate>
      <link>https://dev.to/trufflepig/companies-using-workday-how-to-build-a-customer-list-with-live-open-role-counts-in-2026-32ia</link>
      <guid>https://dev.to/trufflepig/companies-using-workday-how-to-build-a-customer-list-with-live-open-role-counts-in-2026-32ia</guid>
      <description>&lt;p&gt;Ask a sales rep or a recruiter which companies run their hiring on &lt;a href="https://www.workday.com/" rel="noopener noreferrer"&gt;Workday&lt;/a&gt; and you get a spreadsheet somebody built two years ago. The career sites are public, but each sits at &lt;code&gt;{tenant}.{datacenter}.myworkdayjobs.com&lt;/code&gt; with a datacenter you cannot guess, and a big employer runs several. I'll show the manual route and where it breaks, then the shortcut: the &lt;a href="https://apify.com/johnvc/workday-career-sites-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Career Sites API&lt;/a&gt;, which turns a company name into one JSON row per career site with a live open-role count.&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 Workday publish a list of companies using Workday?
&lt;/h2&gt;

&lt;p&gt;No. Workday's own APIs are tenant-scoped: they serve a customer's HR integrations, need that customer's credentials, and never say who the customers are. What it does publish is the sites, thousands of public careers pages on &lt;code&gt;myworkdayjobs.com&lt;/code&gt; and &lt;code&gt;myworkdaysite.com&lt;/code&gt;. So a companies-using-Workday list is a discovery job: find the tenants, resolve each to its boards, verify they answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Workday Career Sites API returns
&lt;/h2&gt;

&lt;p&gt;The Workday Career Sites API returns one row per Workday career site as structured JSON: tenant, datacenter, site slug, public careers URL, direct jobs API URL, and the open-role count at run time.&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;tenant&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kla&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hostname prefix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;datacenter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wd1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not guessable from the name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;careersUrl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://kla.wd1.myworkdayjobs.com/en-US/Penang_Semicon&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ready to open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apiUrl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://kla.wd1.myworkdayjobs.com/wday/cxs/kla/Penang_Semicon/jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Jobs endpoint, ready to POST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;totalJobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;37&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Empty when &lt;code&gt;verifyLive&lt;/code&gt; is off&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;siteSlug&lt;/code&gt;, &lt;code&gt;hostKind&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;slugSource&lt;/code&gt;, &lt;code&gt;companyName&lt;/code&gt;, and &lt;code&gt;discoveredAt&lt;/code&gt; ride along. Not included: job postings, applicant data, or companies on another hiring platform.&lt;/p&gt;

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

&lt;p&gt;HR-tech sales teams who want companies using Workday as a target list, with open-role counts as a buying signal; job-board and recruiting-data builders who need a company-to-career-site map; and anyone giving an AI agent live answers about who runs Workday and how hard they are hiring.&lt;/p&gt;

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

&lt;p&gt;You guess. Assume the tenant matches the company name (it often doesn't), then try &lt;code&gt;wd1&lt;/code&gt;, &lt;code&gt;wd5&lt;/code&gt;, &lt;code&gt;wd108&lt;/code&gt; and the rest until a hostname answers. Then you hunt for site slugs, because the main board is rarely the only one: KLA runs seven Workday career sites, Cadence eight. Repeat for two hundred companies, then again next month. Bulk is worse: no list to start from. I follow semiconductor hiring, and those seven KLA boards are what pushed me to build a discovery step instead of maintaining the spreadsheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Workday Career Sites 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/workday-career-sites-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Career Sites API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Put company names or domains in &lt;code&gt;companies&lt;/code&gt;, or switch on &lt;code&gt;discoverAll&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~workday-career-sites-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;'{ "companies": ["nvidia", "kla"], "verifyLive": true }'&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;
  
  
  Find companies using Workday in Python
&lt;/h2&gt;

&lt;p&gt;Call the Actor with &lt;code&gt;apify-client&lt;/code&gt; and keep the &lt;code&gt;career_site&lt;/code&gt; rows:&lt;br&gt;
&lt;/p&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/workday-career-sites-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;companies&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;nvidia&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;kla&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;cadence.com&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;verifyLive&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="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;site&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;site&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;resultType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;career_site&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&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;site&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;datacenter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;siteSlug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;totalJobs&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="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;site&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apiUrl&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;h2&gt;
  
  
  Build a list of companies using Workday
&lt;/h2&gt;

&lt;p&gt;Set &lt;code&gt;discoverAll&lt;/code&gt; to true and the Actor enumerates Workday career sites in bulk, with &lt;code&gt;maxResults&lt;/code&gt; capping how many companies it processes. It is a wide net, not a census: some smaller employers are missing from the public index, while a named company is resolved exactly. &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/build-a-list-of-companies-using-workday?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build a List of Companies Using Workday&lt;/a&gt; is that configuration, ready to start.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Workday customer list for sales prospecting
&lt;/h2&gt;

&lt;p&gt;Same bulk mode, different reader: to an HR-tech seller a Workday customer list is an account list, and &lt;code&gt;totalJobs&lt;/code&gt; shows which accounts are hiring this week. Start from &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/build-a-workday-customer-list?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build a Workday Customer List for Sales&lt;/a&gt; and join &lt;code&gt;tenant&lt;/code&gt; to your CRM.&lt;/p&gt;
&lt;h2&gt;
  
  
  Count open roles across Workday career sites
&lt;/h2&gt;

&lt;p&gt;One &lt;code&gt;totalJobs&lt;/code&gt; number is a snapshot; the same run weekly is a time series per site, and that trendline (a subsidiary board doubling, a regional board going quiet) is what people pay for. Start from &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/count-open-roles-across-workday-career-sites?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Count Open Roles Across Workday Career Sites&lt;/a&gt; and keep every dataset.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find a company's Workday careers URL
&lt;/h2&gt;

&lt;p&gt;Pass one name or domain and get back a &lt;code&gt;careersUrl&lt;/code&gt; you can open; a company that isn't on Workday produces no rows and no charge. See &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/find-a-company-workday-careers-url?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find a Company's Workday Careers URL&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accenture, Barclays, and Boeing: worked examples
&lt;/h2&gt;

&lt;p&gt;Three large tenants, each a one-click task: &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/find-accenture-workday-career-sites?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Accenture&lt;/a&gt;, &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/find-barclays-workday-career-sites?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Barclays&lt;/a&gt;, and &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/find-boeing-workday-career-sites?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Boeing&lt;/a&gt;. Each returns the company's career sites with a jobs API URL and open-role count per board.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find every Workday job board a company runs
&lt;/h2&gt;

&lt;p&gt;Tools that stop at the first board miss the regional and university sites, each with its own openings. &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/find-every-workday-career-site-a-company-runs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Every Workday Career Site a Company Runs&lt;/a&gt; returns all of them, one row each.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get the Workday jobs API URL for a company
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;apiUrl&lt;/code&gt; is what most developers are after: a direct jobs endpoint per site. &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/get-workday-jobs-api-url-for-a-company?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get the Workday Jobs API URL for a Company&lt;/a&gt; hands it over; the sibling &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; consumes it to pull the postings. Discovery here, extraction there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Resolve the Workday tenant name for a company
&lt;/h2&gt;

&lt;p&gt;For &lt;code&gt;nvidia.wd5.myworkdayjobs.com&lt;/code&gt; the tenant is &lt;code&gt;nvidia&lt;/code&gt;, the company's label inside Workday. &lt;a href="https://apify.com/johnvc/workday-career-sites-api/examples/get-workday-tenant-name-for-a-company?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get the Workday Tenant Name for a Company&lt;/a&gt; returns tenant and datacenter together, the pair you need to build any Workday URL.&lt;/p&gt;
&lt;h2&gt;
  
  
  Workday MCP: use it from Claude, Claude Code, and Cursor
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor through the Model Context Protocol, so Claude, Claude Code, and Cursor get a tool that takes company names and returns career sites; an agent can then answer "which of these ten companies run Workday, and how many roles does each have open" from live data. The server URL is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/workday-career-sites-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Claude Code that is &lt;code&gt;claude mcp add --transport http apify&lt;/code&gt; plus the URL; read more about 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Workday-Career-Sites-API" rel="noopener noreferrer"&gt;
        Apify-Workday-Career-Sites-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      companies using workday: Python + MCP quick-start for the Workday Career Sites API on Apify. Call it from Python (uv) or as an MCP tool in Claude and Cursor. Returns structured JSON for companies using Workday.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🏢 Workday Career Sites API: Find the Companies Using Workday&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the companies using Workday and every career site each one runs, as clean structured JSON: tenant, datacenter, careers URL, direct jobs API URL, and a live open-role count.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Actor page:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/workday-career-sites-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/workday-career-sites-api&lt;/a&gt;
&lt;strong&gt;Input schema:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/workday-career-sites-api/input-schema?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/workday-career-sites-api/input-schema&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Give this API a company name and it returns every Workday career site that company runs, each with the tenant, datacenter, public careers URL, the direct jobs API URL, and how many roles are open right now. Turn on discovery mode and it enumerates companies using Workday in bulk, so you can build a Workday customer list for sales or research. It returns every board a company runs, not just the main one: large employers keep separate sites for regions, subsidiaries, and university hiring.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Walkthrough&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8cf47ba7ea4f430827c72e9fb72707d7c32c2390c7e9f7018b411c2375009a34/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f6d617872657364656661756c742e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Text walkthrough&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;The primary use case is finding the &lt;strong&gt;companies using Workday&lt;/strong&gt; and resolving each to its career sites…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Workday-Career-Sites-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;A &lt;code&gt;uv&lt;/code&gt;-managed Python quick start with &lt;code&gt;companies_list&lt;/code&gt;, &lt;code&gt;every_site&lt;/code&gt;, and &lt;code&gt;jobs_api_url&lt;/code&gt; recipes, plus MCP install steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Workday career sites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the Workday career sites scraper cost, and is there a free tier?
&lt;/h3&gt;

&lt;p&gt;Pay per career site returned, plus a tiny actor-start and per-result event; no monthly minimum, and the current per-site price is on the Store page. Only verified live sites are billed unless you turn on &lt;code&gt;includeInactive&lt;/code&gt;, and new Apify accounts include free platform credit.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Workday tenant, and how does the scraper find it?
&lt;/h3&gt;

&lt;p&gt;The company's own label inside Workday, and the first part of its hostname on &lt;code&gt;myworkdayjobs.com&lt;/code&gt;, where Workday hosts customer career sites. The scraper resolves a name or domain to tenant, then datacenter, then every site slug, with &lt;code&gt;slugSource&lt;/code&gt; as a confidence signal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent call this scraper through MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. Point Claude, Claude Code, Cursor, or ChatGPT at the hosted Apify MCP server with this Actor attached (the URL above) and it shows up as a callable tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to track open-role counts over time?
&lt;/h3&gt;

&lt;p&gt;Yes. Save the input as a task, attach an Apify schedule (weekly, &lt;code&gt;0 7 * * 1&lt;/code&gt;, suits a customer list), and each run appends fresh &lt;code&gt;totalJobs&lt;/code&gt; and &lt;code&gt;discoveredAt&lt;/code&gt; values to chart. Start from the &lt;a href="https://apify.com/johnvc/workday-career-sites-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Career Sites API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper return the job postings themselves?
&lt;/h3&gt;

&lt;p&gt;No. It returns the career sites and an &lt;code&gt;apiUrl&lt;/code&gt; per site; the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; pulls the postings. It never returns applicant data, and a company on another hiring platform comes back with no rows.&lt;/p&gt;

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

&lt;p&gt;Related Actors: the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; for the postings behind each &lt;code&gt;apiUrl&lt;/code&gt;, the &lt;a href="https://apify.com/johnvc/oracle-taleo-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Oracle Fusion Recruiting and Taleo Jobs API&lt;/a&gt; for employers on Oracle instead of Workday, and 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 firmographics to enrich the list you just built.&lt;/p&gt;

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

&lt;p&gt;Workday will not hand you a customer list, but the career sites are public and this Actor reads them into JSON. Try the &lt;a href="https://apify.com/johnvc/workday-career-sites-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Career Sites API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Workday-Career-Sites-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at your watch list.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>Google Maps Photos API: Pull a Place's Whole Gallery in 2026 (Python, Street View, MCP)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Mon, 14 Sep 2026 19:09:55 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-maps-photos-api-pull-a-places-whole-gallery-in-2026-python-street-view-mcp-jm2</link>
      <guid>https://dev.to/trufflepig/google-maps-photos-api-pull-a-places-whole-gallery-in-2026-python-street-view-mcp-jm2</guid>
      <description>&lt;p&gt;Every business on &lt;a href="https://www.google.com/maps" rel="noopener noreferrer"&gt;Google Maps&lt;/a&gt; carries a gallery: the storefront, the interior, the dishes, the customer snapshots, the Street View panorama. Getting one photo out means right-clicking. Getting all of them, for a hundred places, means writing a scraper. I wanted the second thing and did not want to maintain the scraper, so I built the &lt;a href="https://apify.com/johnvc/google-maps-photos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Photos API&lt;/a&gt; on Apify, which turns a place name into one JSON row per photo.&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 Maps have a photos API?
&lt;/h2&gt;

&lt;p&gt;Sort of, and the gap is the interesting part. Google's Places API has a Photo endpoint, but it returns a rendered image for a reference you already hold, and that reference comes from a separate Place Details call you also pay for. There is no "give me this restaurant's whole gallery, sorted, with stable IDs" call. Street View Static is the same shape: a rendered tile at coordinates you supply, not a listing of what is attached to a place. So the thing people mean by a Google Maps photos API is not what the official product does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Maps Photos API returns
&lt;/h2&gt;

&lt;p&gt;The Google Maps Photos API returns one row per photo as structured JSON: full-size image URL, thumbnail, gallery position, and a stable ID you can de-duplicate on across runs.&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;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://lh3.googleusercontent.com/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full-size photo URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;thumbnail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://lh3.googleusercontent.com/...=w200&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Smaller preview of the same shot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;position&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Where it sits in the place's gallery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;photo_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AF1QipM...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stable across runs, so you can dedupe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;place_title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Mozart's Coffee Roasters&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Present when the place was found by search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CgIgARICCAI&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The gallery section filter that was applied&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each place also gets one summary row carrying &lt;code&gt;photos_returned&lt;/code&gt;, &lt;code&gt;pages_fetched&lt;/code&gt;, and &lt;code&gt;place_categories&lt;/code&gt;, the full list of gallery sections with the filter ID for each. That last field is how you discover a venue's own sections and then pull just one.&lt;/p&gt;

&lt;p&gt;It does not return captions, EXIF, contributor names, or upload dates. If you need provenance, this is not the tool.&lt;/p&gt;

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

&lt;p&gt;Listings sites that need real imagery instead of one hero thumbnail. Travel and hospitality apps pulling interiors and menus. Retail and real estate teams auditing what a location looks like online.&lt;/p&gt;

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

&lt;p&gt;Load the place page in a headless browser, click into the photo grid, scroll until it stops loading, pull &lt;code&gt;src&lt;/code&gt; off the tiles. It works the first afternoon. Then: the gallery lazy-loads in blocks, so you are scripting scroll-and-wait loops; image URLs are size-parameterized, so you must know which suffix gives the original; category tabs render client-side with opaque IDs; and the markup shifts often enough that selectors rot in weeks.&lt;/p&gt;

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

&lt;p&gt;Documented JSON in, documented JSON out, nothing to keep alive.&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-maps-photos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Photos API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Type a place into &lt;code&gt;searchTerm&lt;/code&gt;, or paste a Google Maps URL into &lt;code&gt;placeUrls&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-maps-photos-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;'{ "searchTerm": "Mozart'&lt;/span&gt;&lt;span class="s2"&gt;"'"&lt;/span&gt;&lt;span class="s1"&gt;'s Coffee Roasters, Austin TX", "maxPlacesPerSearch": 1, "maxPhotosPerPlace": 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;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get Google Maps photos in Python
&lt;/h2&gt;

&lt;p&gt;Photo rows and the per-place summary arrive in the same dataset, separated by &lt;code&gt;result_type&lt;/code&gt;:&lt;br&gt;
&lt;/p&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-maps-photos-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;searchTerm&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;Mozart&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s Coffee Roasters, Austin TX&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;maxPlacesPerSearch&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxPhotosPerPlace&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="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&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="n"&gt;default_dataset_id&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&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_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;photo&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;photo&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;photo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;photo_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;photo&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&lt;/span&gt;&lt;span class="sh"&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;place&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&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_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;place_summary&lt;/span&gt;&lt;span class="sh"&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;category&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;place&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_categories&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;category&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note &lt;code&gt;run.default_dataset_id&lt;/code&gt;: &lt;code&gt;apify-client&lt;/code&gt; 3.x returns a typed &lt;code&gt;Run&lt;/code&gt; object, not a dict, which trips up older snippets.&lt;/p&gt;
&lt;h2&gt;
  
  
  Street View and 360 panoramas without coordinates
&lt;/h2&gt;

&lt;p&gt;This is the capability I did not expect to be the most useful one. Set &lt;code&gt;photoCategory&lt;/code&gt; to &lt;code&gt;street_view&lt;/code&gt; and you get the panoramas attached to a place, addressed by name rather than by coordinates. Street View Static wants a latitude, longitude, and heading, and getting from "this restaurant" to "the right pano facing the right way" is its own problem. The worked example is &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/street-view-360-photos-for-a-place?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Street View and 360 Photos for Any Place&lt;/a&gt;. The &lt;code&gt;videos&lt;/code&gt; category works the same way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Bulk photo download across a list of places
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;maxPlacesPerSearch&lt;/code&gt; turns this from a one-place lookup into a sweep. A &lt;code&gt;searchTerm&lt;/code&gt; of &lt;code&gt;coffee shops in Austin, TX&lt;/code&gt; resolves to many places and pulls each gallery in one run. Two tasks cover the shapes: &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/bulk-download-place-photos?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Bulk Download Every Photo for a List of Places&lt;/a&gt; when you already have the list, and &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/photos-for-every-business-in-an-area?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Photos for Every Business in a Neighborhood&lt;/a&gt; when you want the search to find them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Menu photos, and telling owner uploads from customer snapshots
&lt;/h2&gt;

&lt;p&gt;Food and drink venues expose extra gallery sections, so &lt;code&gt;photoCategory: menu&lt;/code&gt; gets the menu boards and dish shots without the parking lot: &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/restaurant-menu-and-food-photos?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Menu and Food Photos for Any Restaurant&lt;/a&gt;, or the Chinese-language &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/restaurant-food-photos-zh?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;获取餐厅菜品照片和店内实拍图&lt;/a&gt;. And &lt;code&gt;by_owner&lt;/code&gt; separates what the business posted from what customers uploaded, which is the whole question in an imagery audit: &lt;a href="https://apify.com/johnvc/google-maps-photos-api/examples/owner-uploaded-business-photos?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Owner-Uploaded Photos for a Business&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor over the Model Context Protocol, so Claude, Claude Code, and Cursor can pull a gallery mid-conversation and answer "show me the interior shots for this hotel" with real URLs. More on 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Google-Maps-Photos-API" rel="noopener noreferrer"&gt;
        Apify-Google-Maps-Photos-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📸 Google Maps Photos API: every place photo as clean JSON&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Pull every photo Google Maps holds for a business or landmark, as structured JSON. Type a place name and get back full-size image URLs, thumbnails, gallery positions, and a stable photo ID for each one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/google-maps-photos-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;Google Maps Photos API on Apify Store&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;https://www.youtube.com/watch?v=jREWahDGhJM&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/johnisanerd/Apify-Google-Maps-Photos-API.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; Apify-Google-Maps-Photos-API
cp .env.example .env          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; paste your Apify token&lt;/span&gt;
uv sync
uv run google-maps-photos-api-example.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Get a free Apify API key at &lt;a href="https://apify.com?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why Use This Google Maps Photos API?&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;No place ID needed.&lt;/strong&gt; Search by name, or by category and city. Paste a Google Maps URL if you have one. Identifiers work too, and skip the search charge.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Filter to one gallery section.&lt;/strong&gt; Menu, food and drink, vibe, by owner, videos, or Street View and 360.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Stable photo IDs.&lt;/strong&gt; Every row carries one, so a re-run…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Google-Maps-Photos-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Python quick start, the category-filter variants, and MCP setup for Claude, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google Maps photos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Google Maps photos scraper free, and how much does it cost?
&lt;/h3&gt;

&lt;p&gt;Billing is per photo returned, plus a small run start fee, so cost scales with what you receive rather than with pages fetched. Searching by name adds a per-search charge; passing a Google Maps URL or a place identifier skips it, which is the cheapest way to run at volume. New Apify accounts come with free platform credit, so a first run usually costs nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  How many photos will this scraper return for one place?
&lt;/h3&gt;

&lt;p&gt;It varies, from a handful for a small office to several hundred for a busy restaurant. Photos arrive in blocks of twenty and &lt;code&gt;maxPhotosPerPlace&lt;/code&gt; is your cap. The summary row reports &lt;code&gt;photos_returned&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I run this scraper from Claude or another MCP client?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect the Apify MCP server and the Actor becomes a callable tool, so an agent pulls a gallery straight from your prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule this scraper to refresh galleries?
&lt;/h3&gt;

&lt;p&gt;Yes, and the stable &lt;code&gt;photo_id&lt;/code&gt; is what makes it worth doing: save a task, attach an Apify schedule, and dedupe on that ID to see only what is new. Start from the &lt;a href="https://apify.com/johnvc/google-maps-photos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Photos API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do the scraper's image URLs expire, and can it get historical photos?
&lt;/h3&gt;

&lt;p&gt;The URLs are Google-hosted and can rotate, so re-host anything you intend to display long term rather than hotlinking. And no, it cannot give you a place's photos from five years ago: it returns the current gallery with no upload dates. Historical imagery belongs to Street View's own timeline, a different product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent pay for this scraper in USDC with x402?
&lt;/h3&gt;

&lt;p&gt;Yes. The Google Maps Photos API supports agentic payments via the &lt;a href="https://docs.apify.com/platform/integrations/x402" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt;, so AI agents and MCP clients can pay for runs in USDC on Base with no Apify account or API token. Point your agent at the &lt;a href="https://mcp.apify.com/?tools=actors,docs,johnvc/google-maps-photos-api" rel="noopener noreferrer"&gt;Apify MCP server&lt;/a&gt; and it can discover, pay for, and run the scraper autonomously; the &lt;a href="https://apify.com/change-log/pay-for-apify-actors-with-x402?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apify x402 announcement&lt;/a&gt; has the details.&lt;/p&gt;

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

&lt;p&gt;Same shape of JSON: &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; to find the places whose photos you want, &lt;a href="https://apify.com/johnvc/google-maps-contributor-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Contributor Reviews API&lt;/a&gt; for what people said, and &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 a second source.&lt;/p&gt;

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

&lt;p&gt;A place's gallery is public, structured, and annoying to collect by hand, a good description of most things worth automating. Try the &lt;a href="https://apify.com/johnvc/google-maps-photos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Photos API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Google-Maps-Photos-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at your own list of places.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>geospatial</category>
    </item>
    <item>
      <title>iCIMS API: Pull Live Job Postings From Any Career Site in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sun, 13 Sep 2026 19:29:51 +0000</pubDate>
      <link>https://dev.to/trufflepig/icims-api-pull-live-job-postings-from-any-career-site-in-2026-2h5a</link>
      <guid>https://dev.to/trufflepig/icims-api-pull-live-job-postings-from-any-career-site-in-2026-2h5a</guid>
      <description>&lt;p&gt;About a quarter of the Fortune 500 runs hiring through &lt;a href="https://www.icims.com" rel="noopener noreferrer"&gt;iCIMS&lt;/a&gt;, which means a huge share of real, current job postings sit on employer career sites that no public API will hand you. I wanted those postings as JSON, from the source rather than from an aggregator's week-old copy. This post covers why iCIMS is awkward to read, what breaks when you script it yourself, and the shortcut: the &lt;a href="https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;iCIMS API&lt;/a&gt; on Apify, which turns a career-site address into one JSON row per open role.&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 iCIMS have a public jobs API?
&lt;/h2&gt;

&lt;p&gt;Not one you can sign up for. iCIMS sells API access to its own customers so they can read their own data, which is the right tool if you own the account. There is no public endpoint for reading an employer's live postings from outside. So the workable path is a scraper you call like an API: give it a career site, get that employer's open roles back as structured JSON. It is an unofficial tool, it is not affiliated with iCIMS, and it reads only pages that are already public.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the iCIMS API returns
&lt;/h2&gt;

&lt;p&gt;The iCIMS API returns every live job on a career site as a JSON row with title, employer, locations, requisition ID, salary, dates, the full description, and the apply 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;&lt;code&gt;url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://careers-rambus.icims.com/jobs/23006/job&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Canonical, stable across title edits, the key to dedupe on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-23006&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The employer's own requisition ID, not a number from the URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Design Verification Principal Engineer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;As published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;organization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Rambus&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hiring employer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;locations_derived&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;["Hillsboro, OR, United States"]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Readable City, Region, Country strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;date_posted&lt;/code&gt; / &lt;code&gt;date_updated&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-08-03T04:00:00+00:00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ISO-8601; &lt;code&gt;date_updated&lt;/code&gt; is the field to monitor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;salary_raw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pay range as published&lt;/td&gt;
&lt;td&gt;Never inferred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct application link&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Descriptions come back three ways: &lt;code&gt;description_text&lt;/code&gt;, &lt;code&gt;description_html&lt;/code&gt;, and &lt;code&gt;description_markdown&lt;/code&gt;. The Markdown one is the friendliest if you are piping a job description into a model.&lt;/p&gt;

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

&lt;p&gt;People tracking hiring at named accounts, who want a new requisition the day it appears rather than when a board syndicates it. Teams building or backfilling a job board, who need real posted dates and working apply links. And anyone doing recruitment market research across many employers on the same platform, where per-employer onboarding is the thing that kills the project.&lt;/p&gt;

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

&lt;p&gt;Reading one career site by hand is fine; the trouble starts at scale. There are two kinds of iCIMS site, classic portals on &lt;code&gt;icims.com&lt;/code&gt; and modern career sites on the employer's own domain, and they need different handling. iCIMS prints no posted date on the page, so a naive parser returns jobs with no usable date. Job URLs change when an employer edits a title, so dedupe quietly breaks and yesterday's role reappears as new. And some employers gate parts of the site to trusted networks, which looks like an empty result rather than an error. I lost an afternoon to that one before working out the site was fine and my code was being told to go away.&lt;/p&gt;

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

&lt;p&gt;In the Apify Console, open the &lt;a href="https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;iCIMS API&lt;/a&gt;, click Try for free, paste a career-site root into &lt;code&gt;startUrls&lt;/code&gt; or a bare company name into &lt;code&gt;companies&lt;/code&gt;, then run it and export as JSON, CSV, or Excel. Every common address form works and the right approach is picked automatically: a site root, a &lt;code&gt;sitemap.xml&lt;/code&gt;, a &lt;code&gt;/jobs/search&lt;/code&gt; page, a single job URL, or a modern career site on the employer's domain.&lt;/p&gt;

&lt;p&gt;From the command line it is one call:&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~icims-careers-api/runs?token=YOUR_APIFY_TOKEN"&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="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{ "startUrls": [{"url": "https://careers-rambus.icims.com"}], "maxJobsPerSite": 50, "descriptionFormat": "both" }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;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;
  
  
  Pull iCIMS jobs 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/icims-careers-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;companies&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;rambus&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;maxJobsPerSite&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;job&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;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;job&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;job&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;locations_derived&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;job&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;date_posted&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;companies&lt;/code&gt; for a list and you are reading several employers in the same run.&lt;/p&gt;
&lt;h2&gt;
  
  
  Track new postings without re-reading the whole site
&lt;/h2&gt;

&lt;p&gt;Turn &lt;code&gt;includeDetails&lt;/code&gt; off and you get list-only mode: job URL, requisition ID, and last-changed timestamp for every live job, in a single request per career site. Pair it with &lt;code&gt;newerThan&lt;/code&gt; and you have a cheap daily change feed. The pattern that works is a list-only run every morning, a comparison of &lt;code&gt;date_updated&lt;/code&gt; against what you stored yesterday, then a second run with details on only the jobs that moved.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use it as an ATS API for your own tools
&lt;/h2&gt;

&lt;p&gt;Most ATS API products are unification layers: you pay an integration vendor, connect an employer's account, and read their private data with permission. This is the other half of that problem. It reads what an employer has already published publicly, so there is no account to connect and no setup per employer, which is what makes "who is hiring in this market" a single run instead of a per-employer integration project. The &lt;code&gt;companies&lt;/code&gt; field takes bare names, so &lt;code&gt;["rambus", "sas"]&lt;/code&gt; resolves without hunting for URLs, and duplicates across inputs are removed for you. For storage, &lt;code&gt;url&lt;/code&gt; is a stable primary key and &lt;code&gt;date_updated&lt;/code&gt; is the column to upsert on.&lt;/p&gt;
&lt;h2&gt;
  
  
  Read iCIMS jobs from Claude via MCP
&lt;/h2&gt;

&lt;p&gt;Through the Model Context Protocol the Actor becomes a callable tool in Claude, Claude Code, and Cursor, so "what has Rambus posted in engineering this week" runs a live pull instead of guessing from training data. The input and output schema descriptions are written for a model to read, so an agent can work out which parameters it needs without much prompting. 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;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-iCIMS-Careers-API" rel="noopener noreferrer"&gt;
        Apify-iCIMS-Careers-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      iCIMS API example: pull live job postings from any iCIMS career site with Python or MCP. Covers both public iCIMS surfaces, with change detection so a daily poll only costs the jobs that moved.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;iCIMS API: Pull Live Job Postings From Any iCIMS Career Site&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;iCIMS does not hand out a public read API for job postings, so most teams end up writing a one-off parser per employer. This repo shows you the shortcut: a working Python example plus MCP install steps for the &lt;a href="https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;iCIMS Careers API&lt;/a&gt; on Apify.&lt;/p&gt;

&lt;p&gt;Point it at a career site, get back structured jobs: title, requisition ID, employer, locations, employment type, posted and updated dates, salary when the employer publishes it, and the apply link. It reads both public iCIMS surfaces, the classic &lt;code&gt;careers-{tenant}.icims.com&lt;/code&gt; portals and the modern iCIMS career sites that live on the employer's own domain, so you do not have to know which one an employer runs.&lt;/p&gt;

&lt;p&gt;Get a free Apify API key here: &lt;a href="https://apify.com?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;https://apify.com?fpr=9n7kx3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4b1abe664c6900307628c8040c8939dfe65363a971a6d17d7473aae258d70132/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f687164656661756c742e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Text walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;icims api&lt;/strong&gt; you are looking for is this Actor. You give it one thing, a career site, either…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-iCIMS-Careers-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  FAQ about scraping iCIMS job postings
&lt;/h2&gt;

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

&lt;p&gt;Billing is per job returned, with a small run-start charge and no subscription. There are three per-job rates: full postings at the standard rate, list-only jobs much cheaper because the whole site is read in one request, and proxied jobs higher because iCIMS serves job pages uncompressed. Error rows are not billed at any of the three, so a career site that cannot be reached does not charge you for jobs it never returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude or another agent drive this scraper over MCP?
&lt;/h3&gt;

&lt;p&gt;Yes. The Actor is MCP-server-compatible, so Claude, Claude Code, Cursor, and other MCP clients call it as a tool and pull live postings inside an agent workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to catch new jobs daily?
&lt;/h3&gt;

&lt;p&gt;That is the intended use. Save an input as a Task, attach a Schedule, and pair a nightly list-only run with &lt;code&gt;newerThan&lt;/code&gt; to get a change feed for a set of employers. Start from the &lt;a href="https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;iCIMS API&lt;/a&gt; and route the output through webhooks, n8n, Make, or Zapier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which career sites can this scraper not reach?
&lt;/h3&gt;

&lt;p&gt;Ones restricted to trusted networks. You get a labelled error row with &lt;code&gt;error_code&lt;/code&gt; set to &lt;code&gt;ip_gated&lt;/code&gt; rather than a silent gap. Residential proxies clear many of them, but employers who allow only their own corporate network cannot be reached from outside by anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this scraper affiliated with iCIMS, and is the data really public?
&lt;/h3&gt;

&lt;p&gt;No affiliation, and yes. It reads career-site pages that are already open to any browser, with no login and no API key. You are responsible for your own use, including local law and platform terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent pay for this scraper in USDC with x402?
&lt;/h3&gt;

&lt;p&gt;Yes. The iCIMS API supports agentic payments via the &lt;a href="https://docs.apify.com/platform/integrations/x402" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt;, so AI agents and MCP clients can pay for runs in USDC on Base with no Apify account or API token. Point your agent at the &lt;a href="https://mcp.apify.com/?tools=actors,docs,johnvc/icims-careers-api" rel="noopener noreferrer"&gt;Apify MCP server&lt;/a&gt; and it can discover, pay for, and run the scraper autonomously; the &lt;a href="https://apify.com/change-log/pay-for-apify-actors-with-x402?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apify x402 announcement&lt;/a&gt; has the details.&lt;/p&gt;

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

&lt;p&gt;The same job for the other big enterprise ATS: &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt;. From the destination side of the market rather than the employer side: &lt;a href="https://apify.com/johnvc/linkedin-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Jobs API&lt;/a&gt;. And for scoring the companies you turn up: &lt;a href="https://apify.com/johnvc/glassdoor-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Glassdoor Reviews API&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Employer career sites are the original source, ahead of every board that syndicates from them. Point the &lt;a href="https://apify.com/johnvc/icims-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;iCIMS API&lt;/a&gt; at one, or clone the &lt;a href="https://github.com/johnisanerd/Apify-iCIMS-Careers-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and start from working Python.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>Sold Property Prices by Suburb: Pull realestate.com.au Listings as JSON in 2026 (Python, MCP, No-Code)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Sat, 12 Sep 2026 19:09:19 +0000</pubDate>
      <link>https://dev.to/trufflepig/sold-property-prices-by-suburb-pull-realestatecomau-listings-as-json-in-2026-python-mcp-3l8j</link>
      <guid>https://dev.to/trufflepig/sold-property-prices-by-suburb-pull-realestatecomau-listings-as-json-in-2026-python-mcp-3l8j</guid>
      <description>&lt;p&gt;You can look up what one house sold for on &lt;a href="https://www.realestate.com.au/" rel="noopener noreferrer"&gt;realestate.com.au&lt;/a&gt;, but nothing there lets you pull a whole suburb's sales into a table. There is no public API, and the price on a sold listing is usually an estimate, not a disclosed figure. I'll show the manual route and where it breaks, then the shortcut: the &lt;a href="https://apify.com/johnvc/realestate-au-property-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Realestate.com.au Property API&lt;/a&gt; on Apify, which takes a suburb and returns sold, rental, or for-sale listings as 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 realestate.com.au have an API?
&lt;/h2&gt;

&lt;p&gt;Not a public one. There is no open developer API to sign up for and no key to request, so "realestate.com.au api" searches are mostly people asking for access that does not exist. In practice it means a scraper you consume like an API: suburb in, listing rows out as JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Realestate.com.au Property API returns
&lt;/h2&gt;

&lt;p&gt;The Realestate.com.au Property API returns one row per listing as structured JSON: address, property type, beds, baths, parking, land size, a price estimate, the confirmed sold date and selling agency on sold rows, the advertised rent on rental rows, agent details, and coordinates.&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;soldDate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2021-08-03T00:00:00.000Z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confirmed, on sold rows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;estimatedPrice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;$585,000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The source's estimate; &lt;code&gt;estimatedPriceValue&lt;/code&gt; is &lt;code&gt;585000&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lastSoldAgency&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Harcourts RG - Gold Coast&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Selling agency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bedrooms&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bathrooms&lt;/code&gt; and &lt;code&gt;parking&lt;/code&gt; too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;landSizeValue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;454&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parsed from &lt;code&gt;454m²&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rentPrice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;$650 per week&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rental rows, with &lt;code&gt;rentCurrency&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every row also carries a one-line &lt;code&gt;summary&lt;/code&gt; an AI agent can read as is.&lt;/p&gt;

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

&lt;p&gt;Buyer's agents and investors researching a suburb's sold market before they bid. Analysts benchmarking the Australian rental market by suburb. Agency principals who want to know which office holds a suburb's market share.&lt;/p&gt;

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

&lt;p&gt;The DIY version is to build the sold-listings URL for a suburb, fetch each results page, and parse the cards. Pagination has to be walked by hand. Prices arrive as text, often "Contact Agent" or "AUCTION" on for-sale listings, so your parser needs a null path from day one. Several Australian suburbs share a name, so a bare suburb quietly gives you the wrong market. The markup shifts and your selectors rot with it. Add blocking and retries, and you own infrastructure to get a table of sales.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Realestate.com.au Property API
&lt;/h2&gt;

&lt;p&gt;Documented input in, documented rows out, no listing URL to find first.&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/realestate-au-property-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Realestate.com.au Property API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Leave &lt;strong&gt;Mode&lt;/strong&gt; on &lt;code&gt;search&lt;/code&gt;, set &lt;strong&gt;Listing type&lt;/strong&gt; to &lt;code&gt;sold&lt;/code&gt;, and enter &lt;code&gt;Coomera, QLD, 4209&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run it. The &lt;strong&gt;Sold properties&lt;/strong&gt; view shows dates and agencies; export 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~realestate-au-property-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;'{ "mode": "search", "listingType": "sold", "locations": ["Coomera, QLD, 4209"], "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;
  
  
  Get sold property prices in Python
&lt;/h2&gt;

&lt;p&gt;Call the Actor with &lt;code&gt;apify-client&lt;/code&gt;:&lt;br&gt;
&lt;/p&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/realestate-au-property-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;mode&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;search&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;listingType&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;sold&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;locations&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;Coomera, QLD, 4209&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;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;item&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&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_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;listing&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no listings:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&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;error_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;continue&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;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streetAddress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&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;soldDate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;item&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;estimatedPrice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;item&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;lastSoldAgency&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;The &lt;code&gt;result_type&lt;/code&gt; check is the piece I'd keep even in a throwaway script. An empty search comes back as one row with &lt;code&gt;result_type: "error"&lt;/code&gt; and a plain-language &lt;code&gt;error_message&lt;/code&gt;, with no listing charged, so a zero for a suburb is verifiable rather than a guess.&lt;/p&gt;
&lt;h2&gt;
  
  
  Realestate.com.au property data as JSON, any listing type
&lt;/h2&gt;

&lt;p&gt;The general-purpose starting point is &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/realestate-com-au-property-data-api-listings-as-json?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Realestate.com.au Property Data API: Listings as JSON&lt;/a&gt;: any suburb, &lt;code&gt;buy&lt;/code&gt;, &lt;code&gt;rent&lt;/code&gt;, or &lt;code&gt;sold&lt;/code&gt;, one output shape for all three. Up to 20 locations fit in one run, and &lt;code&gt;maxResultsPerSearch&lt;/code&gt; (1 to 2000) is the cost dial.&lt;/p&gt;
&lt;h2&gt;
  
  
  Check sold property prices in any Australian suburb
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/check-sold-property-prices-in-any-australian-suburb?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Check Sold Property Prices in Any Australian Suburb&lt;/a&gt; is the flagship: every recent sale the source holds for a suburb, up to your cap, with date, agency, and estimate. Run it weekly and keep each dataset, and after a couple of months the weekly sold count and median estimate become a trendline. The trendline is the product; the one-off check is the demo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Track the Australian rental market by suburb
&lt;/h2&gt;

&lt;p&gt;Flip &lt;code&gt;listingType&lt;/code&gt; to &lt;code&gt;rent&lt;/code&gt; and the same suburb returns current rentals with &lt;code&gt;rentPrice&lt;/code&gt; and &lt;code&gt;rentCurrency&lt;/code&gt; beside beds, baths, and parking, which is what a yield calculation needs. &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/track-weekly-rent-prices-by-australian-suburb?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track Weekly Rent Prices by Australian Suburb&lt;/a&gt; is built to be scheduled. The sold and rental searches also exist as Chinese-language tasks: &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/chaxun-aozhou-yishou-fangyuan-chengjiao-jilu?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;sold listings and price estimates&lt;/a&gt; and &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/huoqu-aozhou-zaizu-fangyuan-zhoujin-shuju?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;rental listings and weekly rents&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find which agency sold each home in a suburb
&lt;/h2&gt;

&lt;p&gt;Sold rows carry &lt;code&gt;lastSoldAgency&lt;/code&gt;, so a &lt;code&gt;sold&lt;/code&gt; search grouped by that field is an agency market-share table, which is what &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/find-which-agency-sold-each-home-in-an-australian-suburb?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Which Agency Sold Each Home in an Australian Suburb&lt;/a&gt; does. The &lt;code&gt;agents&lt;/code&gt; block adds phone, rating, and review count; the individual agent's name is often missing, so group at agency level.&lt;/p&gt;
&lt;h2&gt;
  
  
  Export an Australian property dataset to CSV or Excel
&lt;/h2&gt;

&lt;p&gt;Not everything needs code. &lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/export-an-australian-property-dataset-to-csv-or-excel?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export an Australian Property Dataset to CSV or Excel&lt;/a&gt; pulls a suburb into a spreadsheet from the Console through the two built-in views; grab the full JSON export when you need land size, coordinates, or agents.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor through the Model Context Protocol, so Claude, Claude Code, and Cursor can run a suburb search mid-conversation and answer "which agency handled the most sales in Coomera QLD last year" with real rows. In Claude Code it is one command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http realestate-au &lt;span class="s2"&gt;"https://mcp.apify.com/?tools=actors,docs,johnvc/realestate-au-property-api"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://apify.com/johnvc/realestate-au-property-api/examples/get-australian-sold-property-data-in-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Australian Sold Property Data in Claude via MCP&lt;/a&gt; is the shortest path to trying it, and you can read more about 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Realestate-AU-Property-API" rel="noopener noreferrer"&gt;
        Apify-Realestate-AU-Property-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Realestate.com.au Property API on Apify: sold property prices, rentals, and for-sale listings by suburb as structured JSON. Python (uv) quick-start plus MCP install guides for Claude, Cursor, and ChatGPT.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🏡 Realestate.com.au Property API: sold property prices, rentals, and for-sale listings by suburb&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Give it an Australian suburb. Get back structured JSON: sold property prices with confirmed sale dates, rental listings with advertised rent, and for-sale stock, all from one API with no listing URL to find first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Actor page:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/realestate-au-property-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/realestate-au-property-api&lt;/a&gt;
&lt;strong&gt;Input schema:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/realestate-au-property-api/input-schema?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/realestate-au-property-api/input-schema&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This repo is a working Python client for the Realestate.com.au Property API on Apify. The API turns Australian property listings into clean rows: street address, suburb, state, postcode, property type, beds, baths, parking, land size, floor area, agent details, photo URLs, and latitude and longitude. Ask it for &lt;code&gt;sold&lt;/code&gt; and you get sold property prices with a confirmed &lt;code&gt;soldDate&lt;/code&gt; and the selling agency. Ask it for &lt;code&gt;rent&lt;/code&gt; and you get the advertised rent, which is how you track the australia rental market suburb by suburb. Ask it for &lt;code&gt;buy&lt;/code&gt; and you get current australian property listings.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Realestate-AU-Property-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;A working Python client with four example runs (&lt;code&gt;sold&lt;/code&gt;, &lt;code&gt;rent&lt;/code&gt;, &lt;code&gt;buy&lt;/code&gt;, and URL mode), each capped at 3 listings so a first run costs almost nothing, plus MCP install walkthroughs for Claude Cowork, Claude Code, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping realestate.com.au
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the realestate.com.au scraper cost, and is there a free tier?
&lt;/h3&gt;

&lt;p&gt;Billing is per event: one &lt;code&gt;listing-scraped&lt;/code&gt; event per listing pushed to the dataset, plus a tiny actor-start event. A search that returns nothing is not charged, and &lt;code&gt;maxResultsPerSearch&lt;/code&gt; caps a run's cost before it starts. Current rates are on the Store card, and new Apify accounts come with free platform credit.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I check what a property sold for with this scraper?
&lt;/h3&gt;

&lt;p&gt;Set &lt;code&gt;listingType&lt;/code&gt; to &lt;code&gt;sold&lt;/code&gt; and search the suburb with its state and postcode. Each row carries the confirmed &lt;code&gt;soldDate&lt;/code&gt;, the &lt;code&gt;lastSoldAgency&lt;/code&gt;, and the price estimate. For one address, switch &lt;code&gt;mode&lt;/code&gt; to &lt;code&gt;url&lt;/code&gt; and pass the listing page in &lt;code&gt;listingUrls&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper return the actual sale price or an estimate?
&lt;/h3&gt;

&lt;p&gt;An estimate. The sold date is confirmed; the price is the source's displayed estimate, because Australian sale prices are frequently not disclosed. Sold and rental rows almost always carry a number, for-sale rows often do not, so filter on a non-null &lt;code&gt;estimatedPriceValue&lt;/code&gt; before averaging a &lt;code&gt;buy&lt;/code&gt; search. There is no automated valuation in the output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will this scraper find commercial property sold prices?
&lt;/h3&gt;

&lt;p&gt;No. It covers the residential listings on realestate.com.au, where &lt;code&gt;buy&lt;/code&gt;, &lt;code&gt;rent&lt;/code&gt;, and &lt;code&gt;sold&lt;/code&gt; come from. Commercial stock in Australia lives on a separate site and is out of scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper work as an MCP tool in Claude or Cursor?
&lt;/h3&gt;

&lt;p&gt;Yes. Point any MCP client at the Apify MCP server with the URL above and the Actor appears as a callable tool in Claude, Claude Code, Claude Cowork, or Cursor; the example repo has the install steps for each.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I schedule the scraper to build a sold-price history?
&lt;/h3&gt;

&lt;p&gt;Save one task per suburb or listing type, open &lt;strong&gt;Actions&lt;/strong&gt;, choose &lt;strong&gt;Schedule&lt;/strong&gt;, and attach a cron string such as &lt;code&gt;0 9 * * 1&lt;/code&gt; for a Monday review; one schedule can trigger many tasks. Diff each run's dataset against the last on &lt;code&gt;propertyId&lt;/code&gt;: a property that moves from &lt;code&gt;buy&lt;/code&gt; to &lt;code&gt;sold&lt;/code&gt; is a sale. Start from the &lt;a href="https://apify.com/johnvc/realestate-au-property-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Realestate.com.au Property API&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Related Actors with the same kind of JSON output: the &lt;a href="https://apify.com/johnvc/zoopla-property-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Zoopla UK Property API&lt;/a&gt; for listings and sold house prices in Britain, 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 Scraper&lt;/a&gt; for the schools, cafes, and transport around a shortlisted address, 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 commute times from a shortlist.&lt;/p&gt;

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

&lt;p&gt;There is no public realestate.com.au API, but sold property prices, rentals, and for-sale stock for any suburb are one JSON call away. Try the &lt;a href="https://apify.com/johnvc/realestate-au-property-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Realestate.com.au Property API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Realestate-AU-Property-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at your own suburbs.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>realestate</category>
    </item>
    <item>
      <title>Greenhouse Job Board API: Track Who's Hiring Across 4,400+ Companies in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Fri, 11 Sep 2026 19:09:33 +0000</pubDate>
      <link>https://dev.to/trufflepig/greenhouse-job-board-api-track-whos-hiring-across-4400-companies-in-2026-2bid</link>
      <guid>https://dev.to/trufflepig/greenhouse-job-board-api-track-whos-hiring-across-4400-companies-in-2026-2bid</guid>
      <description>&lt;p&gt;Companies that hire through Greenhouse post their openings on a hosted board, like &lt;a href="https://boards.greenhouse.io/gitlab" rel="noopener noreferrer"&gt;GitLab's Greenhouse job board&lt;/a&gt;, and those postings are the closest thing to a live headcount signal you can get. Getting them out means one board at a time, HTML descriptions, pay buried in prose, and no list of who uses Greenhouse. I'll show the manual route and where it breaks, then the shortcut: the &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Job Board API&lt;/a&gt; on Apify, which returns live jobs from any Greenhouse board as JSON with no Harvest key, and finds the 4,400+ companies hiring there.&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 Greenhouse have an API for job postings?
&lt;/h2&gt;

&lt;p&gt;Yes, two. The Harvest API is Greenhouse's private one for employers; no key for a company you don't work at. The Job Board API is public and read-only, documented on Greenhouse's &lt;a href="https://developers.greenhouse.io/job-board.html" rel="noopener noreferrer"&gt;developer site&lt;/a&gt; for integrators building application flows, and for one company, once, just call it. It serves one board per call, though, you need the token first, and Greenhouse publishes no list of boards. The Actor fills those gaps: a directory of 4,400+ verified boards, parsed salaries, Markdown, timestamp filters, and rows filtered before you pay.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Greenhouse job board API returns
&lt;/h2&gt;

&lt;p&gt;The Greenhouse Job Board API returns one row per open job as structured JSON: title, company, departments, offices, location, remote flag, employer timestamps, raw and parsed salary, and a Markdown description.&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;Account Executive - Italy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Plus &lt;code&gt;companyName&lt;/code&gt;, &lt;code&gt;boardToken&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;location&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Remote, Italy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;With &lt;code&gt;isRemote&lt;/code&gt;, &lt;code&gt;departments&lt;/code&gt;, &lt;code&gt;offices&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dateUpdated&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-08-03T16:43:10-04:00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Employer's stamp; &lt;code&gt;datePublished&lt;/code&gt; too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;salaryDerived&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "min": 71400, "max": 126000, "currency": "EUR" }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parsed; &lt;code&gt;salaryRaw&lt;/code&gt; is verbatim&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Sales and GTM teams who read hiring as a buying signal; recruiters pulling every open role at target companies; talent analysts tracking posting velocity and pay transparency; and anyone handing live job data to an AI agent.&lt;/p&gt;

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

&lt;p&gt;The DIY route is a script that calls the public endpoint per board token and diffs the JSON against last night's file. It works for three companies. At thirty you learn a token is not the company's name and start reading page source. Descriptions come back as HTML, the salary is a sentence inside it, and your regex misses the EUR postings. Your diff needs a database, and "every company on Greenhouse" has no endpoint at all. None of this is hard. All of it is maintenance, and you wanted a dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Greenhouse Job Board 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/greenhouse-job-board-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Job Board API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Put board tokens or board URLs in &lt;code&gt;companies&lt;/code&gt;; add &lt;code&gt;titleKeywords&lt;/code&gt; or &lt;code&gt;updatedAfter&lt;/code&gt; for a subset.&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~greenhouse-job-board-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;'{ "companies": ["gitlab", "stripe"], "titleKeywords": ["engineer"], "maxJobs": 10 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;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;
  
  
  Scrape Greenhouse job postings in Python
&lt;/h2&gt;

&lt;p&gt;Call the Actor with &lt;code&gt;apify-client&lt;/code&gt; and keep the rows whose &lt;code&gt;resultType&lt;/code&gt; is &lt;code&gt;job&lt;/code&gt;:&lt;br&gt;
&lt;/p&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/greenhouse-job-board-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;companies&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;gitlab&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;stripe&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;titleKeywords&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;engineer&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;maxJobs&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;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="k"&gt;if&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;resultType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&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;salaryDerived&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="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;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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;companyName&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;location&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dateUpdated&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="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;salary&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;min&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;salary&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;max&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;salary&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;currency&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="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;h2&gt;
  
  
  Use the Greenhouse job board API without a key
&lt;/h2&gt;

&lt;p&gt;Nothing to sign up for. The default run reads Stripe's board with Markdown on and &lt;code&gt;maxJobs&lt;/code&gt; at 100; the task &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/greenhouse-job-board-api-no-key?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Use the Greenhouse Job Board API Without a Key&lt;/a&gt; is that configuration.&lt;/p&gt;
&lt;h2&gt;
  
  
  A job board scraper for Greenhouse career sites
&lt;/h2&gt;

&lt;p&gt;Paste whatever you have, board tokens, board URLs, embed URLs, or single job URLs, mixed freely across &lt;code&gt;companies&lt;/code&gt; and &lt;code&gt;startUrls&lt;/code&gt;. &lt;code&gt;outputMode: urlsOnly&lt;/code&gt; gives a cheap index: id, title, company, link, timestamps. The task is &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/job-board-scraper-greenhouse-sites?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Job Board Scraper for Greenhouse Career Sites&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Greenhouse job postings with salary data
&lt;/h2&gt;

&lt;p&gt;Published pay ranges pass through verbatim as &lt;code&gt;salaryRaw&lt;/code&gt;; a deterministic parser adds &lt;code&gt;salaryDerived&lt;/code&gt; (&lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;currency&lt;/code&gt;, &lt;code&gt;period&lt;/code&gt;) from the posting text. See &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/greenhouse-job-postings-salary-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Job Postings With Salary Data&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find companies using Greenhouse
&lt;/h2&gt;

&lt;p&gt;There is no page that lists all Greenhouse open jobs, so the Actor ships one. &lt;code&gt;outputMode: companiesOnly&lt;/code&gt; returns one row per company from the bundled directory, live-verified, with &lt;code&gt;boardToken&lt;/code&gt;, &lt;code&gt;boardUrl&lt;/code&gt;, and a current &lt;code&gt;jobCount&lt;/code&gt;; dead boards are never billed. &lt;code&gt;discoveryQuery&lt;/code&gt; text-matches company names and &lt;code&gt;maxCompanies&lt;/code&gt; caps a blind sweep. This is the run I do first when I want to know who is quietly staffing up in a niche. Task: &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/find-companies-using-greenhouse?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Companies Using Greenhouse ATS&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Track new Greenhouse jobs daily
&lt;/h2&gt;

&lt;p&gt;Every job carries the employer's own published and updated stamps, so &lt;code&gt;updatedAfter: "25h"&lt;/code&gt; on a daily schedule returns only what changed since yesterday, no seen-list needed; &lt;code&gt;publishedAfter&lt;/code&gt; narrows that to new roles. One run is a snapshot. A scheduled run is a time series, and that shows a company opening twelve engineering roles before any press release. Task: &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/track-new-greenhouse-jobs-daily?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track New Greenhouse Job Postings Daily&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Greenhouse jobs as Markdown for AI agents
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;includeDescriptionMarkdown&lt;/code&gt; is on by default, so every row carries a Markdown description an LLM can read without an HTML-stripping step, with stable field names. Task: &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/examples/greenhouse-jobs-markdown-ai-agents?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Jobs as Markdown for AI Agents&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Greenhouse MCP server for job data: Claude, Claude Code, and Cursor
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor over MCP, so Claude, Claude Code, Cursor, and ChatGPT get a &lt;code&gt;greenhouse-job-board-api&lt;/code&gt; tool that answers "which of these twenty companies posted sales roles this week" with live data. The server URL is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/greenhouse-job-board-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Claude Code that is &lt;code&gt;claude mcp add --transport http apify&lt;/code&gt; plus the URL; Claude Code has a free trial at &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;claude.ai&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Greenhouse-Job-Board-API" rel="noopener noreferrer"&gt;
        Apify-Greenhouse-Job-Board-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      greenhouse job board api: Python + MCP quick-start for the Greenhouse API on Apify. Call it from Python (uv) or as an MCP tool in Claude and Cursor. Returns structured JSON for greenhouse job board api.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌱 Greenhouse Job Board API: live jobs, companies, and new postings&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A Python and MCP quick-start for the &lt;strong&gt;Greenhouse job board API&lt;/strong&gt; on Apify. Pull live jobs from any Greenhouse-hosted career site, discover companies hiring through Greenhouse, and track new or changed postings, all without a Harvest key or a login.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actor: &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;Greenhouse Job Board API on Apify&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Input schema: &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api/input-schema?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;input parameters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Get a free API token: &lt;a href="https://apify.com?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Greenhouse is the applicant tracking system behind the career pages of thousands of companies, including Stripe, Airbnb, GitLab, and Anthropic. This Actor reads the public Greenhouse job board API live at run time, so every row reflects what the board says right now, not what an index remembered last week. Give it board tokens or URLs, or give it nothing and let it sweep a bundled directory of 4,400+ verified boards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8cf47ba7ea4f430827c72e9fb72707d7c32c2390c7e9f7018b411c2375009a34/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f6d617872657364656661756c742e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Text walkthrough&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;Greenhouse job board API&lt;/strong&gt; takes company board tokens…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Greenhouse-Job-Board-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;A &lt;code&gt;uv&lt;/code&gt; Python quick start with five &lt;code&gt;--example&lt;/code&gt; recipes and MCP install guides for five clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Greenhouse job boards
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Greenhouse scraper free, or what does it cost?
&lt;/h3&gt;

&lt;p&gt;Per delivered row: one event per job record, plus add-ons (description formats, application questions, run report) billed only on rows that carry them. No start fee, no minimum, and filtered rows are never charged; with add-ons off a job row costs a fraction of a cent. Prices are on the store's pricing card, and new Apify accounts include free platform credit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is job-boards.greenhouse.io legit, and is a scraper allowed to read it?
&lt;/h3&gt;

&lt;p&gt;Yes, &lt;code&gt;job-boards.greenhouse.io&lt;/code&gt; and &lt;code&gt;boards.greenhouse.io&lt;/code&gt; are both official Greenhouse domains. The scraper reads only the public job board layer behind them, never applicant or Harvest data; whether your use of public job data is fine where you live (California comes up a lot) is a question for your counsel, not me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude run this scraper over MCP, and is it Greenhouse's MCP?
&lt;/h3&gt;

&lt;p&gt;Claude, Claude Code, Cursor, and ChatGPT can, through the hosted Apify MCP server URL above. It is not Greenhouse's own MCP product, which is built for Greenhouse customers; this one is public job data for anyone building an agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I schedule this scraper for a daily new-jobs feed?
&lt;/h3&gt;

&lt;p&gt;Save your input as a task with &lt;code&gt;updatedAfter&lt;/code&gt; at &lt;code&gt;25h&lt;/code&gt;, attach an Apify schedule with a cron expression like &lt;code&gt;0 7 * * *&lt;/code&gt;, and each run returns only jobs that changed since the last one. Start from the &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Job Board API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where does the Greenhouse scraper stop?
&lt;/h3&gt;

&lt;p&gt;At the EU data silo: boards on &lt;code&gt;job-boards.eu.greenhouse.io&lt;/code&gt; are detected and reported but not yet scraped (EU support is planned). Nothing behind the Harvest API: no applicants, no internal requisitions. A bad token comes back as an in-band error row with &lt;code&gt;errorCode: board_not_found&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Hiring data rarely lives on one ATS, so three siblings: the &lt;a href="https://apify.com/johnvc/ashby-job-board-scraper?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Ashby Job Board API&lt;/a&gt; for Ashby-hosted boards, the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; for Workday career sites, and the &lt;a href="https://apify.com/johnvc/Google-Jobs-Scraper?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Jobs Scraper&lt;/a&gt; for Google Jobs.&lt;/p&gt;

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

&lt;p&gt;Greenhouse gives you one board at a time; the Actor gives you all of them, salaries parsed, yesterday's changes filtered. Try the &lt;a href="https://apify.com/johnvc/greenhouse-job-board-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Greenhouse Job Board API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Greenhouse-Job-Board-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and run &lt;code&gt;--example companies&lt;/code&gt; on your niche.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>Trustpilot Reputation Monitoring in 2026: Turn Public Reviews into a Dated JSON History</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Thu, 10 Sep 2026 19:09:55 +0000</pubDate>
      <link>https://dev.to/trufflepig/trustpilot-reputation-monitoring-in-2026-turn-public-reviews-into-a-dated-json-history-3k09</link>
      <guid>https://dev.to/trufflepig/trustpilot-reputation-monitoring-in-2026-turn-public-reviews-into-a-dated-json-history-3k09</guid>
      <description>&lt;p&gt;Getting &lt;a href="https://www.trustpilot.com/" rel="noopener noreferrer"&gt;Trustpilot company review pages&lt;/a&gt; into something you can query is a grind: reviews are paginated, replies are nested under each one, and the posting date is not the date the thing happened. I'll show the manual way and where it breaks, then a faster path in Python, REST, and MCP, plus a repo to clone. The faster path is the &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Trustpilot Reviews API&lt;/a&gt; on Apify: company URLs in, one JSON row per review out, built for reputation monitoring, a dated history of what changed.&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 Trustpilot have an API?
&lt;/h2&gt;

&lt;p&gt;Yes, and it's worth being straight about. Trustpilot's own developer API sits behind a business account and its plan limits, scoped to that account's data. If you're a business reading your own reviews, use it; it won't let you point at a competitor with no account relationship. That's the gap a scraper-as-API fills: public review pages in, a fixed JSON shape out, billed per review rather than per plan. This Actor isn't affiliated with Trustpilot and doesn't claim feature parity with their API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Trustpilot Reviews API returns
&lt;/h2&gt;

&lt;p&gt;The Trustpilot Reviews API returns one JSON row per public review: star rating, title and text, posting date and a separate date of experience, verified flag, reviewer country, and any company reply, plus the company's overall rating and star breakdown.&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;reviewRating&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1 to 5 stars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dateOfExperience&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-07-23T00:00:00.000Z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When it happened; &lt;code&gt;reviewDate&lt;/code&gt; is the posting date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reviewReplies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[{ "text": "Thanks for the kind words.", "date": "2026-07-15" }]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The business's reply, with date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;starBreakdown&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{ "star5": { "count": 4083, "percent": 93 } }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The 5-to-1 split, counts and percentages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;result_type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Or &lt;code&gt;error&lt;/code&gt; with an &lt;code&gt;error_message&lt;/code&gt;, so nothing fails silently&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Brand and CX teams who want the star breakdown as a time series. Competitive analysts who need a rival set in one export, replies included. Data scientists building a customer review dataset with labels attached.&lt;/p&gt;

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

&lt;p&gt;The DIY version is a headless browser that loads the review page, pages through, and parses each card. It works in a quick test. Then you hit a company with four thousand reviews, find that reply text and date of experience live in different parts of the markup, and watch your selectors rot when the layout shifts. At twenty competitors you're running proxies and retries and maintaining infrastructure instead of a rating history.&lt;/p&gt;

&lt;p&gt;The failure I care about most is the quiet one. When a script returns zero reviews, you can't tell whether the page moved, the company has no reviews, or you were blocked. An empty result is a claim, and claims need evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Trustpilot Reviews API
&lt;/h2&gt;

&lt;p&gt;You send a documented JSON input and get a documented JSON output, with nothing to keep alive.&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/trustpilot-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Trustpilot Reviews API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Paste company review-page URLs (or bare domains) into &lt;strong&gt;Company URLs&lt;/strong&gt; and set &lt;strong&gt;Max reviews per company&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Run it and export 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~trustpilot-reviews-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;'{ "companyUrls": ["https://www.trustpilot.com/review/www.dugood.org"], "maxReviewsPerCompany": 3 }'&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 customer review data in Python
&lt;/h2&gt;

&lt;p&gt;Call the Actor with &lt;code&gt;apify-client&lt;/code&gt; and handle the error rows:&lt;br&gt;
&lt;/p&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/trustpilot-reviews-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;companyUrls&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;https://www.trustpilot.com/review/www.dugood.org&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;maxReviewsPerCompany&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;item&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&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="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;companyUrl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;continue&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;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reviewRating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dateOfExperience&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reviewTitle&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;That &lt;code&gt;error&lt;/code&gt; branch answers the plausible zero: a URL that returns nothing produces an &lt;code&gt;error&lt;/code&gt; row with a plain-language &lt;code&gt;error_message&lt;/code&gt;, so a dead page, a company with no reviews, or a &lt;code&gt;datePosted&lt;/code&gt; window that excluded everything comes back with a reason. (I'd rather see an error row than a suspiciously clean zero.) The runnable version is the task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/trustpilot-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Trustpilot reviews by API from company URLs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reputation monitoring on a schedule, for any company
&lt;/h2&gt;

&lt;p&gt;A single run is a check. The value is the trendline: the same input on a schedule, each run appending a dated snapshot with &lt;code&gt;fetched_at&lt;/code&gt;, &lt;code&gt;companyOverallRating&lt;/code&gt;, and &lt;code&gt;starBreakdown&lt;/code&gt;. Because the breakdown carries counts per level, you see a one-star share climbing before the rounded average moves. Save the input as a task, schedule it with &lt;code&gt;0 7 * * *&lt;/code&gt;, and set &lt;code&gt;datePosted&lt;/code&gt; to &lt;code&gt;Last 30 days&lt;/code&gt; so recurring runs stay small. The task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/monitor-trustpilot-reputation-for-any-company?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Monitor Trustpilot reputation for any company&lt;/a&gt; is already wired this way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Audit Trustpilot reviews for fake review signals
&lt;/h2&gt;

&lt;p&gt;Every row carries &lt;code&gt;isVerifiedReview&lt;/code&gt; and &lt;code&gt;reviewerTotalReviews&lt;/code&gt;, so you can weight an established reviewer against a one-time account. The task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/audit-trustpilot-reviews-for-fake-review-signals?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Audit Trustpilot reviews for fake review signals&lt;/a&gt; sets that up. It gives you the signals; the judgement is still yours.&lt;/p&gt;
&lt;h2&gt;
  
  
  Build a customer review dataset for sentiment analysis
&lt;/h2&gt;

&lt;p&gt;Flat rows of &lt;code&gt;reviewContent&lt;/code&gt; with &lt;code&gt;reviewRating&lt;/code&gt; attached are already a labelled dataset, and &lt;code&gt;reviewerLocation&lt;/code&gt; splits it by market. The task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/customer-review-dataset-for-sentiment-analysis?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Build a customer review dataset for sentiment analysis&lt;/a&gt; exports exactly that shape.&lt;/p&gt;
&lt;h2&gt;
  
  
  Export Trustpilot reviews to CSV
&lt;/h2&gt;

&lt;p&gt;For spreadsheet people, the task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/export-trustpilot-reviews-to-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Trustpilot reviews to CSV for any company&lt;/a&gt; goes straight from company URLs to CSV, no code. Two recipes also exist as Chinese-language tasks: &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/bulk-collect-trustpilot-reviews-csv-zh?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;bulk collect Trustpilot reviews and export to CSV&lt;/a&gt; and &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/monitor-competitor-trustpilot-ratings-zh?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;monitor competitor Trustpilot ratings&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor through the Model Context Protocol, so Claude, Claude Code, and Cursor can pull reviews mid-conversation and answer "which competitor replies to complaints" with live data. In Claude Code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http trustpilot &lt;span class="s2"&gt;"https://mcp.apify.com/?tools=actors,docs,johnvc/trustpilot-reviews-api"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The task &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/examples/trustpilot-reviews-in-claude-via-mcp?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Read Trustpilot reviews in Claude via MCP&lt;/a&gt; has a working configuration; read more about 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Trustpilot-Reviews-API" rel="noopener noreferrer"&gt;
        Apify-Trustpilot-Reviews-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Reputation monitoring data from the Trustpilot Reviews API on Apify: a Python (uv) quick-start plus MCP install guides for Claude, Cursor, and ChatGPT. Returns structured JSON reviews, ratings, replies, and star breakdowns.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;⭐ Trustpilot Reviews API: Reputation Monitoring Data as Structured JSON&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The most efficient, reliable, and developer-friendly way to use the Trustpilot Reviews API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Actor page:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/trustpilot-reviews-api&lt;/a&gt;
&lt;strong&gt;Input schema:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api/input-schema?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com/johnvc/trustpilot-reviews-api/input-schema&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Give it one or more company review-page URLs and it returns one clean JSON row per review: the star rating, the review title and full text, the posting date, the separate date of experience, the verified flag, the reviewer's country, and any reply the business posted. Every row also carries company context, so the same pull gives you the overall rating, the total review count, and the full 5-to-1 star breakdown with counts and percentages. It is built API-first and MCP-ready, so you can call it from Python or drive it as a tool from an AI agent.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Walkthrough&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8cf47ba7ea4f430827c72e9fb72707d7c32c2390c7e9f7018b411c2375009a34/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f6d617872657364656661756c742e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Text walkthrough&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;Most people arrive here because dashboards priced for enterprise reputation monitoring do not expose the underlying rows, and the…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Trustpilot-Reviews-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;A Python quick start that asks for just three reviews, plus MCP walkthroughs for Claude, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Trustpilot reviews
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does the Trustpilot scraper cost?
&lt;/h3&gt;

&lt;p&gt;Per review returned, through one &lt;code&gt;review-scraped&lt;/code&gt; event, plus a tiny actor-start event per run. A company that returns no reviews costs nothing, and &lt;code&gt;maxReviewsPerCompany&lt;/code&gt; is enforced at the source, so your cap is the ceiling on a run's cost. Current rates are on the Store card.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I monitor a competitor's online reputation with this scraper?
&lt;/h3&gt;

&lt;p&gt;Put every competitor URL in one &lt;code&gt;companyUrls&lt;/code&gt; array, save it as a task, and attach a weekly schedule such as &lt;code&gt;0 9 * * 1&lt;/code&gt;. Each row carries &lt;code&gt;companyName&lt;/code&gt;, &lt;code&gt;companyOverallRating&lt;/code&gt;, and &lt;code&gt;starBreakdown&lt;/code&gt;, and &lt;code&gt;reviewReplies&lt;/code&gt; shows who answers complaints. Start from the &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Trustpilot Reviews API&lt;/a&gt; with &lt;code&gt;datePosted&lt;/code&gt; set to &lt;code&gt;Last 30 days&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can Claude Code or Cursor call this scraper directly?
&lt;/h3&gt;

&lt;p&gt;Yes. Add the hosted Apify MCP server with the Actor preloaded, as above, and it appears as a callable tool. Every row carries a one-line &lt;code&gt;summary&lt;/code&gt; an agent can read as is.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does media monitoring support reputation management alongside a review scraper?
&lt;/h3&gt;

&lt;p&gt;Media monitoring tells you what's being said about you; review data tells you what customers experienced and whether you replied. Run both on the same cadence and a rating dip lines up against that week's coverage; this scraper is the review half.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this scraper enough for crisis prevention?
&lt;/h3&gt;

&lt;p&gt;Early warning needs the full star distribution rather than the average, the date of experience separate from the posting date, and a history you keep. This scraper returns the first two and leaves storage and alerting to you. Its hard edges: no company search, so you build the URL list yourself; &lt;code&gt;datePosted&lt;/code&gt; accepts four fixed windows, not calendar dates; and no reviewer email addresses.&lt;/p&gt;

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

&lt;p&gt;Same Actor, another angle: the &lt;a href="https://www.linkedin.com/pulse/reputation-monitoring-trustpilot-reviews-api-track-ratings-uvgtf/" rel="noopener noreferrer"&gt;Trustpilot Reviews API write-up on LinkedIn&lt;/a&gt;. For B2B software, the &lt;a href="https://apify.com/johnvc/g2-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;G2 Reviews API&lt;/a&gt; returns the same kind of row.&lt;/p&gt;

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

&lt;p&gt;Trustpilot's API serves a business reading its own reviews; for any other company, this is the public data as dated JSON you keep. Try the &lt;a href="https://apify.com/johnvc/trustpilot-reviews-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Trustpilot Reviews API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Trustpilot-Reviews-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at your own company list.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Google Flights Deals API: Telling a Real Bargain From a Cheap Short-Haul</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Wed, 09 Sep 2026 19:09:12 +0000</pubDate>
      <link>https://dev.to/trufflepig/google-flights-deals-api-telling-a-real-bargain-from-a-cheap-short-haul-25b6</link>
      <guid>https://dev.to/trufflepig/google-flights-deals-api-telling-a-real-bargain-from-a-cheap-short-haul-25b6</guid>
      <description>&lt;p&gt;Here is a thing I got wrong for a long time: a cheap flight and a good deal are not the same thing. Pull the cheapest destinations from any airport and the top of the list is mostly short-haul, cheap because it is close, not because the fare is unusual. The ones worth chasing are priced below their own norm. The &lt;a href="https://apify.com/johnvc/google-flights-deals-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Flights Deals API&lt;/a&gt; on Apify answers that by attaching a typical-price baseline to every result, sourced from &lt;a href="https://www.google.com/travel/flights" rel="noopener noreferrer"&gt;Google Flights&lt;/a&gt;.&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 Google Flights deals?
&lt;/h2&gt;

&lt;p&gt;No. Google retired QPX Express in 2018 and has never shipped a public flights API, deals tab included. What exists is a scraper you consume like an API: send an airport code, get structured JSON back. The framing matters because the deals feed is not a search: you give it a departure point and it tells you where is cheap right now, a different query from the point-to-point search most flight APIs answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Google Flights Deals API returns
&lt;/h2&gt;

&lt;p&gt;The Google Flights Deals API returns the thirty cheapest destinations from an airport as structured JSON, each carrying its price, what that route typically costs, and a flag for whether it beats the baseline.&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;price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;312&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fare in the requested currency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;average_price&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;498&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What this route typically costs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;savings_percent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;37.3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The gap, as a percentage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;is_below_typical&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The one field that separates bargains from short-hauls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;outbound_date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-09-12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exact dates for the specific itinerary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;flight_link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://www.google.com/travel/flights/...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Booking link&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You also get &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;country&lt;/code&gt;, a &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;thumbnail&lt;/code&gt;, plus &lt;code&gt;route&lt;/code&gt;, &lt;code&gt;airline&lt;/code&gt;, &lt;code&gt;stops&lt;/code&gt;, and &lt;code&gt;flight_duration&lt;/code&gt; in minutes.&lt;/p&gt;

&lt;p&gt;Stated plainly: this returns a snapshot with a baseline. It does not track prices over time, keep history, or send alerts. It is the data layer you build those on, not the alerting product.&lt;/p&gt;

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

&lt;p&gt;Travel affiliates who need better than a list sorted by price. Fare newsletters picking five destinations a week and justifying each. Developers building a price-alert product on a source with a reference price attached. AI travel agents answering "where can I go cheaply from here".&lt;/p&gt;

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

&lt;p&gt;Google Flights encodes its whole query into an opaque URL blob you reverse-engineer per filter, and results render through JavaScript, so a plain HTTP request comes back nearly empty. Worse, the typical-price figure is not printed next to each card as a number. Getting a baseline out of the DOM means parsing a comparative phrase rendered differently across locales, the kind of thing that silently returns &lt;code&gt;None&lt;/code&gt; three weeks after it shipped.&lt;/p&gt;

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

&lt;p&gt;One airport code in, thirty scored destinations out.&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-flights-deals-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Flights Deals API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Put a 3-letter IATA code in &lt;code&gt;departureId&lt;/code&gt;. No arrival field, by design.&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-flights-deals-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": "JFK", "maxDealsPerAirport": 30, "currency": "USD" }'&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;
  
  
  Find flight bargains in Python
&lt;/h2&gt;

&lt;p&gt;Filter on the flag rather than sorting by price:&lt;br&gt;
&lt;/p&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-flights-deals-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;departureId&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;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;maxDealsPerAirport&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency&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;USD&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="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&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="n"&gt;default_dataset_id&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="n"&gt;deals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&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_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;bargains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;deals&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&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;is_below_typical&lt;/span&gt;&lt;span class="sh"&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;deal&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bargains&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&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;savings_percent&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="mi"&gt;0&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;deal&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;deal&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&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;vs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;average_price&lt;/span&gt;&lt;span class="sh"&gt;"&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="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;deal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;savings_percent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% below)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outbound_date&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;Measured across three hubs during the build, between 6 and 30 percent of the feed clears its own baseline on a given day. That is the honest yield, and why the flag earns its place: sorting by price and taking the top five hands you the wrong five. The runnable version is &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/genuine-flight-bargains-from-an-airport?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Genuine Flight Bargains From Your Airport&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Build your own fare history
&lt;/h2&gt;

&lt;p&gt;The Actor keeps no history, which sounds like a limitation and is really a design line: it hands you a fare and a reference price per row, and you decide what to keep. Save a task, attach a schedule, store rows keyed on departure, arrival, and date. After a few weeks you own a fare record nobody can revoke, every row carrying what that route normally cost that day. Start from &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/fare-data-with-typical-price-baseline?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Fare Data With a Typical-Price Baseline&lt;/a&gt;, which takes several airports at once.&lt;/p&gt;
&lt;h2&gt;
  
  
  Narrow it to the trip you would actually take
&lt;/h2&gt;

&lt;p&gt;The filters map to how people search: &lt;code&gt;maxStops: nonstop&lt;/code&gt; for direct routes, in &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/nonstop-flight-bargains?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Nonstop Flight Bargains From Any Airport&lt;/a&gt;; &lt;code&gt;travelDuration: weekend&lt;/code&gt; for short trips, in &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/cheap-weekend-trips-from-an-airport?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Cheap Weekend Trips From Your Airport&lt;/a&gt;; &lt;code&gt;travelClass: business&lt;/code&gt; for the premium cabin, in &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/business-class-flight-deals?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Cheap Business Class Deals From an Airport&lt;/a&gt;. Non-English locales work the same way: &lt;a href="https://apify.com/johnvc/google-flights-deals-api/examples/cheap-flights-from-shanghai-zh?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;查询从上海出发的低价机票目的地&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One filter behaves differently, and the Actor logs a warning when you set it: &lt;code&gt;maxDurationMinutes&lt;/code&gt; makes the source stop returning the baseline, switching off &lt;code&gt;savings&lt;/code&gt; and &lt;code&gt;is_below_typical&lt;/code&gt;. I found that the hard way by changing several inputs at once and blaming the wrong one. Isolate variables.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use it from Claude and other MCP clients
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor over the Model Context Protocol, so Claude, Claude Code, and Cursor can run a live lookup mid-conversation and answer "where can I fly cheaply from Chicago next month, and which are below normal" with current fares. More on 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Google-Flights-Deals-API" rel="noopener noreferrer"&gt;
        Apify-Google-Flights-Deals-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
✈️ Google Flights Deals API: cheap destinations as clean JSON&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Give it an airport and get back the thirty cheapest destinations you can fly to from there, as structured JSON. Each one comes with the price, the typical price for that route, exact dates, airline, stops, duration, a photo, and a booking link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The part nobody else gives you: which of them are actually bargains.&lt;/strong&gt; A cheap fare and a good deal are not the same thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/google-flights-deals-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;Google Flights Deals API on Apify Store&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;https://www.youtube.com/watch?v=jREWahDGhJM&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/johnisanerd/Apify-Google-Flights-Deals-API.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; Apify-Google-Flights-Deals-API
cp .env.example .env          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; paste your Apify token&lt;/span&gt;
uv sync
uv run google-flights-deals-api-example.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Get a free Apify API key at &lt;a href="https://apify.com?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why Use This Google Flights Deals API?&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;Bargain detection, not just cheap fares.&lt;/strong&gt; Every row carries &lt;code&gt;average_price&lt;/code&gt;, what that route typically costs, plus &lt;code&gt;savings&lt;/code&gt;, &lt;code&gt;savings_percent&lt;/code&gt;, and an &lt;code&gt;is_below_typical&lt;/code&gt; flag.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;One&lt;/strong&gt;…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Google-Flights-Deals-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Python quick start, filter variants, and MCP setup for Claude, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Google Flights deals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is this flight deals scraper free, and what does it cost?
&lt;/h3&gt;

&lt;p&gt;Billing is per deal returned, plus a small run start fee, so a thirty-destination sweep is thirty billed rows with nothing hidden behind it. &lt;code&gt;maxDealsPerAirport&lt;/code&gt; caps the count before a run starts. New Apify accounts come with free credit, so early runs usually cost nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do flight price alerts work, and can this scraper send them?
&lt;/h3&gt;

&lt;p&gt;It cannot, and any tool claiming otherwise on top of this feed is doing the alerting itself. An alert is two pieces: a repeated observation and a rule about when to notify. This scraper is the observation half, and a good one, because each row arrives with a reference price, so your rule can be "below typical" rather than a threshold you guessed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can this scraper find deals without me picking dates?
&lt;/h3&gt;

&lt;p&gt;Yes, and it is the default. Leave &lt;code&gt;outboundDate&lt;/code&gt; blank and the feed picks cheap dates, returning the exact &lt;code&gt;outbound_date&lt;/code&gt; and &lt;code&gt;return_date&lt;/code&gt; it found. That is the opposite of a normal flight search, and why this answers "when should I go" as well as "where".&lt;/p&gt;

&lt;h3&gt;
  
  
  What does the scraper mean by "below typical price"?
&lt;/h3&gt;

&lt;p&gt;It compares the fare to what that route usually costs, not to the other destinations in your results, so a $312 flight can be below typical while a $190 one is not. Negative savings mean a route is priced above its own norm, and those rows are useful too: they say what to skip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can this scraper run from Claude or another MCP client?
&lt;/h3&gt;

&lt;p&gt;Yes. Connect the Apify MCP server and it becomes a callable tool in Claude, Claude Code, or Cursor, so an agent pulls live deals from a prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can an AI agent pay for this scraper in USDC with x402?
&lt;/h3&gt;

&lt;p&gt;Yes. The Google Flights Deals API supports agentic payments via the &lt;a href="https://docs.apify.com/platform/integrations/x402" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt;, so AI agents and MCP clients can pay for runs in USDC on Base with no Apify account or API token. Point your agent at the &lt;a href="https://mcp.apify.com/?tools=actors,docs,johnvc/google-flights-deals-api" rel="noopener noreferrer"&gt;Apify MCP server&lt;/a&gt; and it can discover, pay for, and run the scraper autonomously; the &lt;a href="https://apify.com/change-log/pay-for-apify-actors-with-x402?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apify x402 announcement&lt;/a&gt; has the details.&lt;/p&gt;

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

&lt;p&gt;Same kind of JSON: &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; for ideas with hotel prices, &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 Data Scraper&lt;/a&gt; for point-to-point search, &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; for the nights, and &lt;a href="https://apify.com/johnvc/google-maps-photos-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Maps Photos API&lt;/a&gt; for where you land.&lt;/p&gt;

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

&lt;p&gt;Cheapest and best-value are different sorts, and only one belongs in front of a reader. Try the &lt;a href="https://apify.com/johnvc/google-flights-deals-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Google Flights Deals API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Google-Flights-Deals-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at your own home airport.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>traveltech</category>
    </item>
    <item>
      <title>Workday API Without a Tenant: Pull Every Job Posting as JSON in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Tue, 08 Sep 2026 19:09:35 +0000</pubDate>
      <link>https://dev.to/trufflepig/workday-api-without-a-tenant-pull-every-job-posting-as-json-in-2026-1i28</link>
      <guid>https://dev.to/trufflepig/workday-api-without-a-tenant-pull-every-job-posting-as-json-in-2026-1i28</guid>
      <description>&lt;p&gt;Every large employer on the Workday ATS posts its openings on a public careers site, like &lt;a href="https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" rel="noopener noreferrer"&gt;NVIDIA's Workday careers page&lt;/a&gt;, and none of them hand you that list as JSON. I'll show the manual route and where it breaks, then the shortcut: the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt;, which turns any careers URL into one row per job with no Workday tenant, recruiting license, or login.&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 Workday have an API for job postings?
&lt;/h2&gt;

&lt;p&gt;Yes, and that is what makes the search confusing. Workday's official REST and SOAP APIs serve enterprise HR integrations: they need tenant credentials and never expose public job listings. In practice a Workday API for job postings means a scraper you call like an API: send a careers URL, get every posting back as JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Workday API returns
&lt;/h2&gt;

&lt;p&gt;The Workday Careers API returns every live posting on a Workday careers site as structured JSON: title, locations, ISO posted date, full description, pay range, employment type, remote status, requisition ID, and apply URL.&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;Senior Software Engineer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;company&lt;/code&gt; and &lt;code&gt;jobReqId&lt;/code&gt; (&lt;code&gt;JR1990000&lt;/code&gt;) ride along&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;postedDate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2026-07-30&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exact ISO date; &lt;code&gt;postedOn&lt;/code&gt; keeps the relative label&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;locationsText&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;US, CA, Santa Clara&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;additionalLocations&lt;/code&gt; lists the rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;remoteType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Flex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remote, Flex, or Onsite when the site exposes it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;salaryMin&lt;/code&gt; / &lt;code&gt;salaryMax&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;148000&lt;/code&gt; / &lt;code&gt;230000&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Plus &lt;code&gt;salaryCurrency&lt;/code&gt;; null when no range is published&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Job boards refreshing Workday job listings with a stable &lt;code&gt;jobReqId&lt;/code&gt; to dedupe on; recruiting and sales intelligence teams tracking a competitor's open roles and hiring velocity; labor-market researchers comparing pay-range disclosure and remote share; and anyone feeding live hiring signals to an AI agent.&lt;/p&gt;

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

&lt;p&gt;The DIY route is a headless browser that pages through the list and opens every posting for its description. The list carries only relative dates, so a "new this week" filter means fetching every job's detail record. Pay ranges are prose you parse yourself. One employer runs several career sites across two URL families, and a big tenant lists thousands of postings, so you add pacing and retries or get rate limited. You end up maintaining a crawler for what is really a data feed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The faster way: run the Workday Careers 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/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Paste careers URLs into &lt;code&gt;startUrls&lt;/code&gt;; optionally add &lt;code&gt;searchText&lt;/code&gt;, &lt;code&gt;maxJobsPerSite&lt;/code&gt;, or &lt;code&gt;postedAfter&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~workday-careers-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;'{ "startUrls": [{ "url": "https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite" }], "searchText": "engineer", "maxJobsPerSite": 100, "includeDetails": true }'&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 Workday jobs in Python
&lt;/h2&gt;

&lt;p&gt;Call the Actor with &lt;code&gt;apify-client&lt;/code&gt;; an &lt;code&gt;error&lt;/code&gt; row means a bad URL, so keep the &lt;code&gt;job&lt;/code&gt; rows:&lt;br&gt;
&lt;/p&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/workday-careers-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;startUrls&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;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://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite&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;searchText&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;engineer&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;maxJobsPerSite&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;job&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;job&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;resultType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&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;job&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;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;locationsText&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postedDate&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="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;job&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;salaryMin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;job&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;salaryMax&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;job&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;salaryCurrency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;applyUrl&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;h2&gt;
  
  
  Export Workday job listings to JSON, CSV, or Excel
&lt;/h2&gt;

&lt;p&gt;Leave &lt;code&gt;searchText&lt;/code&gt; empty and &lt;code&gt;maxJobsPerSite&lt;/code&gt; at &lt;code&gt;0&lt;/code&gt; to get the whole site, one row per posting; feed several sites into one run and join on &lt;code&gt;tenant&lt;/code&gt; and &lt;code&gt;siteId&lt;/code&gt;. The task &lt;a href="https://apify.com/johnvc/workday-careers-api/examples/export-workday-job-listings?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Workday Job Listings to JSON, CSV or Excel&lt;/a&gt; is that configuration.&lt;/p&gt;
&lt;h2&gt;
  
  
  Monitor Workday job postings on a schedule
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;postedAfter&lt;/code&gt; set to a recent ISO date, the run stops paging once a whole page is older than your cutoff, since Workday sorts newest first; a 2,000 job site with a 3 day cutoff reads about 280 listings, and filtered rows are never billed. Schedule it, diff on &lt;code&gt;jobReqId&lt;/code&gt;, and new postings show up the day they appear. Start from &lt;a href="https://apify.com/johnvc/workday-careers-api/examples/monitor-workday-job-postings?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Monitor New Workday Job Postings for Any Company&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find remote Workday jobs
&lt;/h2&gt;

&lt;p&gt;Every row carries &lt;code&gt;remoteType&lt;/code&gt; (Remote, Flex, or Onsite, whenever the site exposes the label), and the &lt;code&gt;SITE_SUMMARY&lt;/code&gt; key-value record counts each type for the whole site. Filter after the run, or clone &lt;a href="https://apify.com/johnvc/workday-careers-api/examples/find-remote-workday-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Remote Jobs on Any Workday Careers Site&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pull Workday jobs with salary ranges
&lt;/h2&gt;

&lt;p&gt;When an employer publishes a pay range, the Actor extracts &lt;code&gt;salaryMin&lt;/code&gt;, &lt;code&gt;salaryMax&lt;/code&gt;, and &lt;code&gt;salaryCurrency&lt;/code&gt; and keeps the snippet in &lt;code&gt;salaryText&lt;/code&gt;; with no range stated, the fields are null rather than guessed. See &lt;a href="https://apify.com/johnvc/workday-careers-api/examples/workday-jobs-with-salaries?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Extract Jobs with Salary Ranges from Workday Sites&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  One company, every opening: the NVIDIA example
&lt;/h2&gt;

&lt;p&gt;Point the Actor at NVIDIA's careers URL with no filters and you get every live opening with locations and pay ranges, plus &lt;code&gt;totalJobsOnSite&lt;/code&gt; to confirm nothing was dropped. &lt;a href="https://apify.com/johnvc/workday-careers-api/examples/nvidia-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export All NVIDIA Jobs with Salaries and Locations&lt;/a&gt; is the one-click version; the example repo ships it as &lt;code&gt;--example nvidia_jobs&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  More ready-made task pages
&lt;/h2&gt;

&lt;p&gt;Same export for other employers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/intel-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Intel jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/micron-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Micron jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/salesforce-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Salesforce jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/disney-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Disney jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/capital-one-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Capital One jobs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/johnvc/workday-careers-api/examples/adobe-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Adobe jobs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list leans toward semiconductor companies because that is the industry I follow most closely.&lt;/p&gt;
&lt;h2&gt;
  
  
  Workday MCP server: use it from Claude, Claude Code, and Cursor
&lt;/h2&gt;

&lt;p&gt;Apify exposes the Actor through the Model Context Protocol, so Claude, Claude Code, and Cursor get a &lt;code&gt;workday-careers-api&lt;/code&gt; tool that takes a careers URL and returns structured jobs, so an agent can answer "which of these companies posted engineering roles this week" or track headcount across a watch list. The server URL is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/workday-careers-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Claude Code that is &lt;code&gt;claude mcp add --transport http apify&lt;/code&gt; plus the URL, and you can read more about 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;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Workday-Careers-API" rel="noopener noreferrer"&gt;
        Apify-Workday-Careers-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      workday api: Python + MCP quick-start for the Workday Careers API on Apify. Call it from Python (uv) or as an MCP tool in Claude and Cursor. Returns structured JSON for workday api.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Workday Jobs API: Scrape Any Workday Careers Site from Python or MCP&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This repo shows two ways to use the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;Workday Careers API&lt;/a&gt; on Apify: a Python quick start managed with &lt;code&gt;uv&lt;/code&gt;, and MCP install guides for five AI clients (Claude Cowork Desktop, Claude Code, Claude on the web, Cursor, and ChatGPT).&lt;/p&gt;

&lt;p&gt;Give the API any Workday careers URL, like &lt;code&gt;https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite&lt;/code&gt;, and it returns every live job posting as structured JSON: titles, locations, exact ISO posted dates, full descriptions, extracted pay ranges, employment type, remote status, requisition IDs, and direct apply URLs. Thousands of Fortune 500 employers run hiring on the Workday ATS, and this is the practical Workday API for their public job data: no login, no proxies, pay per result.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae9fc8cb316cea399ce612e41d29fce4742edcae31b27d5926b0909905d37e90/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f302e6a7067" alt="Apify MCP setup walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Text walkthrough&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Searching for a Workday API for job postings usually leads to Workday's enterprise SOAP and REST APIs, which need tenant credentials and…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Workday-Careers-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;A &lt;code&gt;uv&lt;/code&gt;-managed Python quick start with &lt;code&gt;nvidia_jobs&lt;/code&gt;, &lt;code&gt;remote_jobs&lt;/code&gt;, and &lt;code&gt;salary_ranges&lt;/code&gt; recipes, plus MCP install guides for five clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Workday job postings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does the Workday scraper cost, and is there a free tier?
&lt;/h3&gt;

&lt;p&gt;About $0.10 per 1,000 job postings returned, plus a small actor-start event per run. Error rows and rows removed by &lt;code&gt;postedAfter&lt;/code&gt; are never charged, and new Apify accounts include free platform credit. No subscription, no seat license: you pay for rows that reach your dataset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Workday an ATS, and which myworkdayjobs.com sites can the scraper read?
&lt;/h3&gt;

&lt;p&gt;Yes. Workday Recruiting is one of the most widely used enterprise applicant tracking systems, and every customer publishes jobs on a public careers site. &lt;code&gt;myworkdayjobs.com&lt;/code&gt; is the official domain Workday hosts those sites on, so pages there are legitimate, and any site there or on &lt;code&gt;myworkdaysite.com&lt;/code&gt; is readable with no login.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the best MCP server for Workday, and can Claude run this scraper?
&lt;/h3&gt;

&lt;p&gt;For job data, the hosted Apify MCP server with this Actor attached, using the URL above. Claude, Claude Code, Cursor, and ChatGPT then call the scraper as a tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule the scraper to catch new Workday job postings?
&lt;/h3&gt;

&lt;p&gt;Yes. Save the run as a task and attach an Apify schedule with a cron expression like &lt;code&gt;0 7 * * *&lt;/code&gt;, using &lt;code&gt;postedAfter&lt;/code&gt; for exact dates or list-only mode (&lt;code&gt;includeDetails: false&lt;/code&gt;) plus a &lt;code&gt;jobReqId&lt;/code&gt; diff when you only need what is new. Start from the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What will the scraper not give you?
&lt;/h3&gt;

&lt;p&gt;Anything behind a Workday login: employee records, internal requisitions, applicant data, the HR APIs. On the public side, salary fields are null when no range is published, &lt;code&gt;remoteType&lt;/code&gt; is filled only when the site shows the label, and &lt;code&gt;postedAfter&lt;/code&gt; needs &lt;code&gt;includeDetails&lt;/code&gt; on.&lt;/p&gt;

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

&lt;p&gt;Same Actor, other angles: &lt;a href="https://medium.com/@alpha-osint/workday-api-how-to-scrape-any-workday-careers-site-as-json-aea024bead5a" rel="noopener noreferrer"&gt;the Medium how-to&lt;/a&gt;, &lt;a href="https://www.linkedin.com/pulse/workday-api-how-scrape-any-careers-site-json-alpha-osint-rkuge/" rel="noopener noreferrer"&gt;the LinkedIn write-up&lt;/a&gt;, and &lt;a href="https://peerlist.io/johnvc/articles/workday-api-pull-every-job-from-any-workday-careers-site-as-json" rel="noopener noreferrer"&gt;the Peerlist article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have company names instead of URLs? The companion &lt;a href="https://apify.com/johnvc/workday-career-sites-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Career Sites API&lt;/a&gt; turns them into the tenant and site values this Actor consumes; the &lt;a href="https://apify.com/johnvc/oracle-taleo-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Oracle Fusion Recruiting and Taleo Jobs API&lt;/a&gt; does the same for employers on Oracle.&lt;/p&gt;

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

&lt;p&gt;Workday's own APIs will not give you a careers site, but you can still get every posting as clean JSON without a tenant. Try the &lt;a href="https://apify.com/johnvc/workday-careers-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Workday Careers API&lt;/a&gt;, or clone the &lt;a href="https://github.com/johnisanerd/Apify-Workday-Careers-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt; and point it at the employers you track.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>LinkedIn Learning API: How to Get Course Data, Reviews, and Syllabus in 2026</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Thu, 03 Sep 2026 14:11:58 +0000</pubDate>
      <link>https://dev.to/trufflepig/linkedin-learning-api-how-to-get-course-data-reviews-and-syllabus-in-2026-37l1</link>
      <guid>https://dev.to/trufflepig/linkedin-learning-api-how-to-get-course-data-reviews-and-syllabus-in-2026-37l1</guid>
      <description>&lt;p&gt;I keep hitting the same wall on learning-data projects: the catalog I want sits on &lt;a href="https://www.linkedin.com/learning/" rel="noopener noreferrer"&gt;LinkedIn Learning&lt;/a&gt;, and no open endpoint returns it. The official LinkedIn Learning API needs the Partner Program or a purchased site license with admin-provisioned OAuth. So I built a hosted &lt;a href="https://apify.com/johnvc/linkedin-learning-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning API&lt;/a&gt; that reads the public, logged-out course pages and returns each course as JSON: ratings, reviews, instructors, and syllabus.&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 LinkedIn Learning have a public API?
&lt;/h2&gt;

&lt;p&gt;Sort of, and the distinction matters. Both official APIs, the Learning API and the Learning Reporting API, sit behind the Partner Program or a paid site license and return learner activity for seats you own, not the public catalog most people want.&lt;/p&gt;

&lt;p&gt;Here, a LinkedIn Learning API means a service you call with a keyword or a course URL and get that public catalog metadata back as JSON, no login. It reads only public pages, not private learner activity; for that, use LinkedIn's Reporting API.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Official LinkedIn Learning API&lt;/th&gt;
&lt;th&gt;This route (public guest pages)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;td&gt;Partner Program or site license, admin OAuth&lt;/td&gt;
&lt;td&gt;None; reads public logged-out pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fields&lt;/td&gt;
&lt;td&gt;Learner activity, completions, admin reporting&lt;/td&gt;
&lt;td&gt;Catalog metadata: &lt;code&gt;ratingValue&lt;/code&gt;, &lt;code&gt;reviews&lt;/code&gt;, &lt;code&gt;tableOfContents&lt;/code&gt;, &lt;code&gt;instructors&lt;/code&gt;, &lt;code&gt;skills&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;Enterprise contract&lt;/td&gt;
&lt;td&gt;Pay per row: $0.10 per 1,000 search rows, $0.50 per 1,000 full records&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What the LinkedIn Learning API returns
&lt;/h2&gt;

&lt;p&gt;In one sentence: it reads LinkedIn Learning's public logged-out course pages as JSON, from ratings and written reviews to the full lesson-by-lesson syllabus, with no login. Search mode returns one row per course; details mode returns the full record for a course, lesson, or path URL. The fields worth pulling:&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;ratingValue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4.7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Average learner rating out of 5, with &lt;code&gt;ratingCount&lt;/code&gt; alongside.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reviews&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[{rating, body, authorName, authorJobTitle, authorProfileUrl, datePublished}]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Written review text plus reviewer identity, not just a star average.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tableOfContents&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[{section, items:[{title, description, durationSeconds, isFree}]}]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full syllabus: every lesson has a description and an &lt;code&gt;isFree&lt;/code&gt; flag, plus &lt;code&gt;freeLessonCount&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;instructors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[{name, jobTitle, profileUrl}]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Structured people with profile links. Full records add &lt;code&gt;hasCertificate&lt;/code&gt; and &lt;code&gt;skills&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;ul&gt;
&lt;li&gt;Learning and development teams benchmarking an internal library against ratings and learner counts.&lt;/li&gt;
&lt;li&gt;Course-recommender and AI-agent builders who need structured records, syllabus included.&lt;/li&gt;
&lt;li&gt;Analysts reading the written &lt;code&gt;reviews&lt;/code&gt; across a topic, or anyone wanting an online courses dataset without an enterprise contract.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;It works, up to a point. A guest page like &lt;code&gt;linkedin.com/learning/search?keywords=python&lt;/code&gt; loads courses without an account, and each course page embeds a schema.org &lt;code&gt;Course&lt;/code&gt; block as JSON-LD:&lt;br&gt;
&lt;/p&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.linkedin.com/learning/python-essential-training-18764650&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&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;User-Agent&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;Mozilla/5.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;script type=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/ld\+json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;(.*?)&amp;lt;/script&amp;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;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&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;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&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;@type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Course&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;data&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;data&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;aggregateRating&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="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;ratingValue&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;That gets a name and a star average, not the per-lesson &lt;code&gt;isFree&lt;/code&gt; flags, reviewer names, or the courses in a learning path. Those sit elsewhere and shift often, so selectors rot. Logged out, LinkedIn serves at most 50 results per query, so a real catalog means merging many queries.&lt;/p&gt;
&lt;h2&gt;
  
  
  The faster way: run the LinkedIn Learning API
&lt;/h2&gt;

&lt;p&gt;Three ways to call it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Apify Console
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://apify.com/johnvc/linkedin-learning-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning API&lt;/a&gt; and click Try for free.&lt;/li&gt;
&lt;li&gt;Leave Mode on Search, type a keyword such as &lt;code&gt;python&lt;/code&gt;, and narrow by level, length, or software.&lt;/li&gt;
&lt;li&gt;Click Start and export the dataset as JSON, CSV, or Excel.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  REST API
&lt;/h3&gt;

&lt;p&gt;One call runs the Actor and returns the dataset in the same response:&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~linkedin-learning-api/run-sync-get-dataset-items?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;'{ "mode": "search", "queries": ["project management"], "maxItems": 25 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Full run-endpoint documentation is 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;h3&gt;
  
  
  MCP
&lt;/h3&gt;

&lt;p&gt;Point any MCP client at the hosted Apify server and the Actor becomes a tool:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/linkedin-learning-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In &lt;a href="https://claude.ai/referral/uIlpa7nPLg" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, Claude Code, or Cursor, ask it to search the catalog mid-conversation, a LinkedIn Learning MCP server with no glue code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get LinkedIn Learning course data in Python
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;apify-client&lt;/code&gt; package mirrors the REST API. With &lt;code&gt;enrichDetails&lt;/code&gt; on, the run mixes row types, so filter to &lt;code&gt;course_detail&lt;/code&gt; before reading &lt;code&gt;ratingValue&lt;/code&gt;:&lt;br&gt;
&lt;/p&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/linkedin-learning-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;mode&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;search&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;queries&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;python&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;maxItems&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enrichDetails&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;maxConcurrency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&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="n"&gt;default_dataset_id&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="k"&gt;if&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;resultType&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;course_detail&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&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;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;ratingValue&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;ratingCount&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;courseUrl&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;h2&gt;
  
  
  Get the LinkedIn Learning course catalog as JSON
&lt;/h2&gt;

&lt;p&gt;Search mode with one query is the fastest way to a clean catalog. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-course-data-json?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning course data as JSON task&lt;/a&gt; returns one row per course with &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;courseUrl&lt;/code&gt;, &lt;code&gt;instructors&lt;/code&gt;, and &lt;code&gt;difficultyLevel&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"project management"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Pull a LinkedIn Learning course list with no login
&lt;/h2&gt;

&lt;p&gt;Same pattern, a different topic, no account or cookie. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-courses-no-login?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning course data without a login task&lt;/a&gt; reads the public catalog for a term like cybersecurity:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"cybersecurity"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Run a LinkedIn Learning course catalog download
&lt;/h2&gt;

&lt;p&gt;A single query caps at 50. &lt;code&gt;expandWithFilters&lt;/code&gt; re-runs it across filter combinations and merges unique courses, the only way past that ceiling; &lt;code&gt;enrichDetails&lt;/code&gt; adds rating and enrollment. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-course-ratings-dataset?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning course ratings dataset task&lt;/a&gt; shows the enriched shape:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enrichDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxConcurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Enriched rows bill at the detail rate, never both.&lt;/p&gt;
&lt;h2&gt;
  
  
  Extract LinkedIn Learning reviews and ratings
&lt;/h2&gt;

&lt;p&gt;The written review body with reviewer identity is the field no competing course scraper exposes. In details mode each row carries &lt;code&gt;ratingValue&lt;/code&gt;, &lt;code&gt;ratingCount&lt;/code&gt;, and a &lt;code&gt;reviews&lt;/code&gt; array. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/extract-linkedin-learning-course-reviews?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;extract LinkedIn Learning course reviews task&lt;/a&gt; reads three courses at once:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"courseUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/python-essential-training-18764650"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/agile-foundations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/sql-essential-training-3"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Find free preview lessons in a course
&lt;/h2&gt;

&lt;p&gt;Every lesson in &lt;code&gt;tableOfContents&lt;/code&gt; carries an &lt;code&gt;isFree&lt;/code&gt; flag and &lt;code&gt;freeLessonCount&lt;/code&gt; totals them, so you can rank courses by how much is watchable free and surface LinkedIn Learning free courses. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-free-preview-lessons?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;free preview lessons task&lt;/a&gt; returns the full syllabus with that flag on every lesson:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"courseUrls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/python-essential-training-18764650"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/excel-essential-training-microsoft-365"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.linkedin.com/learning/communication-foundations-2018"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Scrape LinkedIn Learning Excel course data
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;softwareNames&lt;/code&gt; filter keeps only courses that teach a specific tool, using LinkedIn's own label. LinkedIn applies only the first label per run, so run each tool separately. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-excel-course-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Excel course data task&lt;/a&gt; keeps courses that teach Microsoft Excel:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"excel"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"softwareNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Microsoft Excel"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Scrape LinkedIn Learning Figma course data
&lt;/h2&gt;

&lt;p&gt;The same &lt;code&gt;softwareNames&lt;/code&gt; pattern works for a design tool. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-figma-course-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Figma course data task&lt;/a&gt; keeps only courses that teach Figma:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"figma"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"softwareNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Figma"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Map skills taught across the LinkedIn Learning catalog
&lt;/h2&gt;

&lt;p&gt;An enriched search returns a &lt;code&gt;skills&lt;/code&gt; array on every course, each linked to its topic page. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-skills-coverage?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;skills coverage task&lt;/a&gt; shows which skills a topic teaches:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data analysis"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enrichDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxConcurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Get LinkedIn Learning instructors and profile links
&lt;/h2&gt;

&lt;p&gt;Enriched rows also return &lt;code&gt;instructors&lt;/code&gt; with name, job title, and profile link. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/linkedin-learning-instructor-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;instructor data task&lt;/a&gt; adds the course rating, level, and duration:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"leadership"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enrichDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxConcurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Track new course releases and learning paths
&lt;/h2&gt;

&lt;p&gt;Set &lt;code&gt;sortBy&lt;/code&gt; to &lt;code&gt;RECENCY&lt;/code&gt; and each run returns the newest courses first, so a scheduled run watches a subject for releases. The &lt;a href="https://apify.com/johnvc/linkedin-learning-api/examples/track-new-linkedin-learning-courses?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;track new courses task&lt;/a&gt; uses:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"artificial intelligence"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sortBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RECENCY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For learning paths, set &lt;code&gt;entityType&lt;/code&gt; to &lt;code&gt;LEARNING_PATH&lt;/code&gt; or pass a &lt;code&gt;/learning/paths/&lt;/code&gt; URL; each path row carries &lt;code&gt;pathUrl&lt;/code&gt; and its ordered member &lt;code&gt;courses&lt;/code&gt;, with &lt;code&gt;courseCount&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-LinkedIn-Learning-API" rel="noopener noreferrer"&gt;
        Apify-LinkedIn-Learning-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      LinkedIn Learning API: Python + MCP quick-start on Apify. Call it from Python (uv) or as an MCP tool in Claude and Cursor. Returns structured JSON for course data, learner reviews, syllabus and instructors, no login needed.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🎓 LinkedIn Learning API: Course Data, Reviews and Syllabus from Python and MCP&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A Python and MCP quick-start for the &lt;strong&gt;LinkedIn Learning API&lt;/strong&gt; on Apify. Search the public LinkedIn Learning course catalog by keyword, skill level, length or software, then pull the full record for any course: rating and rating count, written learner reviews, the complete syllabus with a description and a free-preview flag on every lesson, instructors with profile links, skills taught and certificate details. None of it needs a login, a cookie or a site license.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actor: &lt;a href="https://apify.com/johnvc/linkedin-learning-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;LinkedIn Learning API on Apify&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Input schema: &lt;a href="https://apify.com/johnvc/linkedin-learning-api/input-schema?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;input parameters&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Get a free API token: &lt;a href="https://apify.com?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;apify.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LinkedIn's own Learning API is available only through its Partner Program or a purchased site license, with OAuth keys an admin has to provision. This Actor reads the pages LinkedIn Learning already publishes to logged-out visitors and returns the same catalog metadata as JSON: course title…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-LinkedIn-Learning-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The repo has a runnable Python quick start, a &lt;code&gt;.env&lt;/code&gt; template, and the MCP server URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping LinkedIn Learning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does the LinkedIn Learning scraper show which courses give a certificate?
&lt;/h3&gt;

&lt;p&gt;Yes, through &lt;code&gt;hasCertificate&lt;/code&gt; and &lt;code&gt;certificateName&lt;/code&gt; on every full record. It is a certificate of completion, not an accredited qualification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are LinkedIn Learning courses free, and what does the scraper cost?
&lt;/h3&gt;

&lt;p&gt;Most need a subscription, but &lt;code&gt;freeLessonCount&lt;/code&gt; and the per-lesson &lt;code&gt;isFree&lt;/code&gt; flag show what is watchable free. Billing is pay per row: $0.10 per 1,000 courses found and $0.50 per 1,000 full records; the detail charge replaces the search charge.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you get a list of LinkedIn Learning courses with this scraper?
&lt;/h3&gt;

&lt;p&gt;Run search mode with keywords or topic pages, and turn on &lt;code&gt;expandWithFilters&lt;/code&gt; to pass the 50-per-query ceiling: it re-runs the query across filter combinations and merges unique courses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper tell me whether every course in a topic gives a certificate?
&lt;/h3&gt;

&lt;p&gt;Run an enriched search and read &lt;code&gt;hasCertificate&lt;/code&gt; across the rows. Not every course carries one, so the flag is per course, not per topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does the scraper return for a LinkedIn Learning learning path?
&lt;/h3&gt;

&lt;p&gt;Pass a &lt;code&gt;/learning/paths/&lt;/code&gt; URL in details mode, or set &lt;code&gt;entityType&lt;/code&gt; to &lt;code&gt;LEARNING_PATH&lt;/code&gt; in search. The row carries &lt;code&gt;pathUrl&lt;/code&gt; and the ordered member courses in &lt;code&gt;courses&lt;/code&gt;, with &lt;code&gt;courseCount&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the scraper tell a learning path apart from a course?
&lt;/h3&gt;

&lt;p&gt;By the &lt;code&gt;entityType&lt;/code&gt; value: COURSE is one multi-lesson unit, VIDEO is a single lesson, and LEARNING PATH is a curated sequence of courses.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I find the free preview lessons with the scraper?
&lt;/h3&gt;

&lt;p&gt;Every lesson in &lt;code&gt;tableOfContents&lt;/code&gt; carries an &lt;code&gt;isFree&lt;/code&gt; flag and &lt;code&gt;freeLessonCount&lt;/code&gt; totals them, so a result set sorts by how much is watchable without paying.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper download the LinkedIn Learning course catalogue?
&lt;/h3&gt;

&lt;p&gt;There is no official export. Run queries or topic pages with &lt;code&gt;expandWithFilters&lt;/code&gt;, then export as CSV, JSON, or Excel. LinkedIn caps a query at 50, so a broad catalogue comes from many queries; &lt;code&gt;approximateTotalResults&lt;/code&gt; is a size signal, not an exact count.&lt;/p&gt;

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

&lt;p&gt;The same public-page approach runs across the LinkedIn family:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://apify.com/johnvc/linkedin-profile-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Profile API&lt;/a&gt;: enrich instructor and reviewer profile URLs into full public profiles.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apify.com/johnvc/linkedin-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Jobs API&lt;/a&gt;: pair a skills-coverage map with jobs that ask for those skills.&lt;/li&gt;
&lt;li&gt;
&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;: benchmark a training catalog against firmographic data.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The official API is gated, but the public catalog is not: pull ratings, reviews, and the syllabus as JSON with no login. Start from the &lt;a href="https://apify.com/johnvc/linkedin-learning-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;LinkedIn Learning API&lt;/a&gt; and run your first search free, or clone the &lt;a href="https://github.com/johnisanerd/Apify-LinkedIn-Learning-API" rel="noopener noreferrer"&gt;example repo&lt;/a&gt;.&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;p&gt;Last Updated: 2026.09.02&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>api</category>
      <category>education</category>
    </item>
    <item>
      <title>How to find investors for a startup in 2026 (with the cheque sizes attached)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Mon, 24 Aug 2026 15:25:47 +0000</pubDate>
      <link>https://dev.to/trufflepig/how-to-find-investors-for-a-startup-in-2026-with-the-cheque-sizes-attached-5d7g</link>
      <guid>https://dev.to/trufflepig/how-to-find-investors-for-a-startup-in-2026-with-the-cheque-sizes-attached-5d7g</guid>
      <description>&lt;p&gt;Every founder I know hits the same wall on a raise. You can find investor &lt;em&gt;names&lt;/em&gt; in an afternoon. What you cannot find, without a lot of tab-switching, is which of them writes a cheque the size of your round.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://signal.nfx.com" rel="noopener noreferrer"&gt;Signal by NFX&lt;/a&gt; publishes that. It maintains public investor lists organised by sector and stage, and each investor carries a cheque-size range. The lists are public, no login, but they paginate eight at a time through a private endpoint, so copying one into a spreadsheet by hand is a genuinely bad afternoon.&lt;/p&gt;

&lt;p&gt;I did it by hand once. Then I stopped doing it by hand.&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;
  
  
  What the NFX Signal investor data actually contains
&lt;/h2&gt;

&lt;p&gt;The NFX Signal Investor API returns venture investors, VC firms, and the investor-list catalog as structured JSON, including the minimum, target, and maximum cheque each investor writes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you get&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Investor&lt;/td&gt;
&lt;td&gt;name, position, profile link, headshot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cheque size&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;minInvestment&lt;/code&gt;, &lt;code&gt;targetInvestment&lt;/code&gt;, &lt;code&gt;maxInvestment&lt;/code&gt; in USD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firm&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;firmName&lt;/code&gt;, &lt;code&gt;firmUrl&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;investment locations, other lists they appear on, source list stage and sector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catalog&lt;/td&gt;
&lt;td&gt;349 lists across 103 sectors, four stages, and 14 geographies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The largest single list, &lt;code&gt;fintech-seed&lt;/code&gt;, holds 8,775 investors. &lt;code&gt;san-francisco-bay-area&lt;/code&gt; holds 8,246.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Founders raising, who need a target list ordered by the cheque they actually need.&lt;/li&gt;
&lt;li&gt;Anyone selling to VCs, who needs a firm directory for a CRM rather than individual partners.&lt;/li&gt;
&lt;li&gt;Analysts mapping a market, who want to see which firms show up across AI, FinTech, and climate lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The DIY path, and where it breaks
&lt;/h2&gt;

&lt;p&gt;You can do this by hand. Open a list page, copy the eight visible investors, click load more, repeat. For a 300-investor list that is roughly 38 rounds of clicking.&lt;/p&gt;

&lt;p&gt;Scripting it is not much better at first pass. The page is server rendered, so the first batch is in the HTML, but everything after that comes from a cursor-paginated endpoint that the page calls as you scroll. You end up reverse engineering the pagination, then handling the fact that cheque sizes come back as strings, that geography is modelled as a sector rather than a location field, and that a "firm" on a list is only a name and a link until you enrich it.&lt;/p&gt;

&lt;p&gt;None of that is hard. It is just a day you did not plan to spend.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shortcut: run it as an API
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Console.&lt;/strong&gt; Open the &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;NFX Signal Investor API&lt;/a&gt;, pick a mode, hit Start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST.&lt;/strong&gt; One call, no login to the source needed:&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~nfx-signal-investor-api/run-sync-get-dataset-items"&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;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$APIFY_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&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;'{"mode":"investors","listSlugs":["saas-seed"],"maxItems":50}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


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

&lt;p&gt;&lt;strong&gt;MCP.&lt;/strong&gt; Point any MCP client at the server below and an agent can call it directly:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/nfx-signal-investor-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That last one matters more than it looks. "Which seed investors back developer tools, and what do they write?" is a question an agent can now answer from live data instead of memory.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to find investors for a startup, by stage and cheque size
&lt;/h2&gt;

&lt;p&gt;The one I use most. Pick the lists that match your round, then sort by &lt;code&gt;targetInvestment&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"investors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listSlugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"saas-seed"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"investor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brendan Wallace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"managing_partner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"minInvestment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targetInvestment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxInvestment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firmName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fifth Wall Ventures"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"personUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://signal.nfx.com/investors/brendan-wallace"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/find-investors-for-your-startup-by-stage-and-check-size?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Investors for Your Startup by Stage and Check Size&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting a list of VC firms in San Francisco
&lt;/h2&gt;

&lt;p&gt;Switch to &lt;code&gt;firms&lt;/code&gt; mode and you get the firm directory instead of individual partners, which is the shape you want for a CRM import.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"firms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listSlugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"san-francisco-bay-area"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/list-of-vc-firms-in-san-francisco-bay-area?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;List of VC Firms in San Francisco Bay Area&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pre seed investors, with the cheque sizes attached
&lt;/h2&gt;

&lt;p&gt;Pre-seed is the stage where cheque size matters most and is published least consistently. Three sector lists in one run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"investors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listSlugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"fintech-pre-seed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saas-pre-seed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ai-pre-seed"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/pre-seed-investors-list-with-check-sizes?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Pre Seed Investors List With Check Sizes&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using it as a Crunchbase alternative
&lt;/h2&gt;

&lt;p&gt;It complements those tools rather than replacing them, and the difference is worth being precise about. Crunchbase and PitchBook are company-centric: they tell you what a company raised. This is investor-centric: it tells you who invests, at what stage, and what they write. You can attach Crunchbase data per firm in the same run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"investors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"listSlugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ai-seed"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"enrichWithCrunchbase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/crunchbase-alternative-for-investor-and-vc-firm-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Crunchbase Alternative for Investor and VC Firm Data&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Browsing the whole VC database first
&lt;/h2&gt;

&lt;p&gt;Slugs are not guessable, so start here. &lt;code&gt;lists&lt;/code&gt; mode returns the catalog with a slug, stage, sector, and investor count for each of the 349 lists.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lists"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/vc-database-export-by-sector-and-stage?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;VC Database Export by Sector and Stage&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exporting a Signal NFX list to JSON or CSV
&lt;/h2&gt;

&lt;p&gt;If you just want one list out of the browser and into a file, this is the plain version, no enrichment, no filtering: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/export-signal-nfx-investor-lists-to-json-or-csv?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Export Signal NFX Investor Lists to JSON or CSV&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tracking new investors entering your sector
&lt;/h2&gt;

&lt;p&gt;An export is a snapshot. Save the input as a Task, attach a monthly Schedule, and diff the runs to see who entered your sector: &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/track-new-investors-joining-a-vc-list-each-month?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Track New Investors Joining a VC List Each Month&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-NFX-Signal-Investor-API" rel="noopener noreferrer"&gt;
        Apify-NFX-Signal-Investor-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      NFX Signal Investor API examples: find investors, check sizes, and a list of VC firms from Signal by NFX as JSON. Python + MCP quick start.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;NFX Signal Investor API: find investors, check sizes, and VC firms&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Python and MCP examples for the &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;NFX Signal Investor API&lt;/a&gt; on Apify. It turns &lt;a href="https://signal.nfx.com" rel="nofollow noopener noreferrer"&gt;Signal by NFX&lt;/a&gt; investor lists into structured JSON: venture investors, the VC firms behind them, and the check size each investor actually writes.&lt;/p&gt;

&lt;p&gt;Not affiliated with, endorsed by, or connected to NFX. It reads the same public investor lists any visitor can browse.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4b1abe664c6900307628c8040c8939dfe65363a971a6d17d7473aae258d70132/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f687164656661756c742e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Text walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;If you have ever searched for how to find investors for a startup, the hard part is not finding names, it is finding the right names with the right cheque size. This API starts from the public Signal NFX investor lists: 349 of them, spanning 103 sectors and four stages from pre-seed to Series B. Run &lt;code&gt;mode: "lists"&lt;/code&gt; first and you get the whole catalog with a slug, a stage, a sector, and an investor count for each one. Pick…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-NFX-Signal-Investor-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Python quick start with uv, five task-aligned helper functions, and MCP install walkthroughs for Claude Cowork, Claude Code, Claude on the web, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping NFX Signal investor data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Do I need an NFX account to use this scraper?
&lt;/h3&gt;

&lt;p&gt;No. It reads the public investor lists on signal.nfx.com, so no account, cookie, or token is needed for the source. You only need an Apify token to run the Actor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I build my own scraper for this instead?
&lt;/h3&gt;

&lt;p&gt;If you need one list once, scrape it yourself, it is a fair afternoon of work. The pagination, the stringified cheque amounts, and the firm enrichment chain are the parts that make it a maintenance job rather than a script.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use this scraper from Claude or another AI agent?
&lt;/h3&gt;

&lt;p&gt;Yes, over MCP. Point the client at the server URL above and the agent can discover the input schema and run it, which turns "who invests in my sector" into a live query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule this scraper to run every month?
&lt;/h3&gt;

&lt;p&gt;Yes. Save your input as a Task, attach a Schedule, and diff each run. The &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api/examples/track-new-investors-joining-a-vc-list-each-month?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;monthly tracking example&lt;/a&gt; is set up for exactly that.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does this scraper not give me?
&lt;/h3&gt;

&lt;p&gt;Two honest limits. Not every investor publishes a cheque range, and those fields come back empty rather than estimated. And firm enrichment resolves by company name, so a firm with an ambiguous name may come back without LinkedIn or Crunchbase fields attached; you are not charged for the ones that miss.&lt;/p&gt;

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

&lt;p&gt;This Actor is catalogued on &lt;a href="https://www.alphaosint.com/sources/nfx-signal-investor-api/" rel="noopener noreferrer"&gt;Alpha OSINT&lt;/a&gt; alongside the rest of the financial and company data sources.&lt;/p&gt;

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

&lt;p&gt;Run the &lt;a href="https://apify.com/johnvc/nfx-signal-investor-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;NFX Signal Investor API&lt;/a&gt; on a single list first, with &lt;code&gt;maxItems&lt;/code&gt; set low, and see whether the cheque sizes change how you build your list. That is the part I did not expect to matter as much as it does.&lt;/p&gt;

</description>
      <category>api</category>
      <category>python</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Pull Remote Startup Jobs With Salary and Equity in 2026 (Python + a jobs API)</title>
      <dc:creator>Truffle Pig Data</dc:creator>
      <pubDate>Thu, 20 Aug 2026 13:05:33 +0000</pubDate>
      <link>https://dev.to/trufflepig/how-to-pull-remote-startup-jobs-with-salary-and-equity-in-2026-python-a-jobs-api-53jn</link>
      <guid>https://dev.to/trufflepig/how-to-pull-remote-startup-jobs-with-salary-and-equity-in-2026-python-a-jobs-api-53jn</guid>
      <description>&lt;p&gt;Pulling remote startup jobs with real salary and equity numbers attached is harder than it should be. &lt;a href="https://wellfound.com" rel="noopener noreferrer"&gt;Wellfound&lt;/a&gt;, the site formerly known as AngelList Talent, is one of the few places where companies publish both right on the posting, which is why I went there to answer what sounded like a simple question: what does a seed-stage startup actually pay a backend engineer?&lt;/p&gt;

&lt;p&gt;Reading a few hundred postings by hand is not a research method. So here is the manual approach, where it falls over, and the jobs API I use instead.&lt;/p&gt;

&lt;blockquote&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;/blockquote&gt;

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

&lt;p&gt;The Wellfound Jobs API returns startup job listings as structured JSON, with the posted compensation parsed into separate salary and equity numbers.&lt;/p&gt;

&lt;p&gt;Most job feeds hand you a string like &lt;code&gt;$135k - $165k * 0.05% - 0.15%&lt;/code&gt; and wish you luck. This one gives you that string &lt;em&gt;and&lt;/em&gt; the parsed numbers next to it:&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;compensationRaw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;$135k – $165k • 0.05% – 0.15%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exactly as posted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;salaryMin&lt;/code&gt; / &lt;code&gt;salaryMax&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;135000&lt;/code&gt; / &lt;code&gt;165000&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;parsed, &lt;code&gt;null&lt;/code&gt; when unpublished&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;equityMin&lt;/code&gt; / &lt;code&gt;equityMax&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;0.05&lt;/code&gt; / &lt;code&gt;0.15&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;percent, &lt;code&gt;null&lt;/code&gt; when unpublished&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;company.ycFunded&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Y Combinator flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;company.stage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;early_stage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;funding stage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;remoteKind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;REMOTE_ONLY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;remote arrangement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;full markdown&lt;/td&gt;
&lt;td&gt;the whole posting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You also get &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;locationNames&lt;/code&gt;, &lt;code&gt;acceptedRemoteLocationNames&lt;/code&gt;, &lt;code&gt;jobType&lt;/code&gt;, &lt;code&gt;yearsExperienceMin&lt;/code&gt;/&lt;code&gt;Max&lt;/code&gt;, &lt;code&gt;postedAt&lt;/code&gt;, and a &lt;code&gt;company&lt;/code&gt; object with size, tagline, and the &lt;code&gt;topInvestors&lt;/code&gt; and &lt;code&gt;activelyHiring&lt;/code&gt; flags.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;You are building a job board or an aggregator and want early-stage roles that the big feeds miss.&lt;/li&gt;
&lt;li&gt;You are weighing an offer and want a defensible comp range instead of a vibe.&lt;/li&gt;
&lt;li&gt;You are a founder setting a band and have nothing to compare against.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The DIY path, and where it breaks
&lt;/h2&gt;

&lt;p&gt;Wellfound is a Next.js app, so the listing data is sitting in the &lt;code&gt;__NEXT_DATA__&lt;/code&gt; blob rather than the HTML. You can get surprisingly far with &lt;code&gt;requests&lt;/code&gt; and a JSON walk:&lt;br&gt;
&lt;/p&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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;https://wellfound.com/role/r/software-engineer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;span class="n"&gt;blob&lt;/span&gt; &lt;span class="o"&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;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__NEXT_DATA__[^&amp;gt;]*&amp;gt;(.*?)&amp;lt;/script&amp;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;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;group&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="n"&gt;apollo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;props&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;pageProps&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;apolloState&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;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&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;__typename&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JobListingSearchResult&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="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jobs on page 1&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;Three things break this, in the order you hit them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The compensation is one string.&lt;/strong&gt; &lt;code&gt;$135k – $165k • 0.05% – 0.15%&lt;/code&gt; has to be split into four numbers, and the format varies. Salary only, equity only, hourly, "competitive".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role slugs are not free text.&lt;/strong&gt; &lt;code&gt;/role/software&lt;/code&gt; is a 404. Only &lt;code&gt;/role/software-engineer&lt;/code&gt; exists. You need the real slug list before you can query anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The page shapes differ.&lt;/strong&gt; The role pages use &lt;code&gt;JobListingSearchResult&lt;/code&gt;, but the site-wide feed uses a completely different typename with a different nesting. Parse one and the other silently returns nothing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of that is unsolvable. It is just a parser you now own forever.&lt;/p&gt;
&lt;h2&gt;
  
  
  The shortcut: run it as an API
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Wellfound Jobs API&lt;/a&gt; handles the parsing, the slug mapping, and both page shapes. Three ways in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.&lt;/strong&gt; Open the &lt;a href="https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Actor page&lt;/a&gt;, click Try for free, set a role, and run it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST.&lt;/strong&gt; Any HTTP client, using the &lt;a href="https://docs.apify.com/api/v2#/reference/actors/run-actor-synchronously-and-get-dataset-items" rel="noopener noreferrer"&gt;Apify run-sync endpoint&lt;/a&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~wellfound-jobs-api/run-sync-get-dataset-items?token=&lt;/span&gt;&lt;span class="nv"&gt;$APIFY_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&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;'{"roles":["software-engineer"],"remoteOnly":true,"maxItems":25}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;MCP.&lt;/strong&gt; It runs as a tool for Claude and other MCP clients. Point your config at:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/wellfound-jobs-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then ask in plain language: "find remote startup jobs for a senior backend engineer paying over 160k, and tell me which companies are YC backed." Setup docs are in the &lt;a href="https://docs.apify.com/platform/integrations/mcp" rel="noopener noreferrer"&gt;Apify MCP guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find remote startup jobs
&lt;/h2&gt;

&lt;p&gt;The one I reach for most. &lt;code&gt;remoteOnly&lt;/code&gt; filters to listings that actually accept remote applicants, and &lt;code&gt;acceptedRemoteLocationNames&lt;/code&gt; on each row tells you &lt;em&gt;where&lt;/em&gt; they accept them from, which is the part that usually disqualifies you.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"software-engineer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"remoteOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"minSalary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;150000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/remote-startup-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Remote Startup Jobs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Find Y Combinator startup jobs
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ycOnly&lt;/code&gt; narrows to YC-backed companies, which is the filter I have not found anywhere else. Pair it with &lt;code&gt;companyStage&lt;/code&gt; so you are comparing seed against seed rather than seed against Series C.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"software-engineer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"ycOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"includeDescription"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/yc-startup-jobs?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Y Combinator Startup Jobs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Startup jobs in San Francisco
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;locations&lt;/code&gt; takes city slugs and pairs with any role. Each role and city combination becomes its own search, so three roles across four cities is twelve searches, not seven. Watch &lt;code&gt;maxItems&lt;/code&gt; accordingly.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"product-manager"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"san-francisco"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/startup-jobs-san-francisco?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Startup Jobs in San Francisco&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Startup jobs in New York
&lt;/h2&gt;

&lt;p&gt;Same shape, different slug. Worth running separately rather than together, because the comp distributions are genuinely different and averaging across cities hides that.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data-scientist"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"new-york"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"minSalary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;140000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/startup-jobs-new-york?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Startup Jobs in New York&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Startup jobs in London
&lt;/h2&gt;

&lt;p&gt;Non-US cities work the same way. Check &lt;code&gt;salaryCurrency&lt;/code&gt; on the rows before you compare anything, because a London posting quoting GBP next to a SF posting quoting USD is not a comparison.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"roles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"backend-engineer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"london"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/startup-jobs-london?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Find Startup Jobs in London&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get startup salary and equity data
&lt;/h2&gt;

&lt;p&gt;The comp use case, with descriptions off because nobody averages prose. Drop the rows where the field is &lt;code&gt;null&lt;/code&gt; before you compute anything, and report how many survived.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&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_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;job&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;with_salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&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;salaryMin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;with_equity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&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;equityMin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&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="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;with_salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&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;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; published salary, &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;with_equity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&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;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; published equity&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;On a 30-row YC sample I ran while writing this, 28 published a salary and only 5 published equity. Those are different sample sizes and deserve separate sentences.&lt;/p&gt;

&lt;p&gt;Ready to run: &lt;a href="https://apify.com/johnvc/wellfound-jobs-api/examples/startup-salary-equity-data?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Get Startup Salary and Equity Data&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The example repo
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnisanerd" rel="noopener noreferrer"&gt;
        johnisanerd
      &lt;/a&gt; / &lt;a href="https://github.com/johnisanerd/Apify-Wellfound-Jobs-API" rel="noopener noreferrer"&gt;
        Apify-Wellfound-Jobs-API
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Startup jobs API example: pull Wellfound (AngelList) jobs with parsed salary, equity, remote status and YC signals. Python + uv quick start and MCP setup.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;💼 Wellfound Jobs API: A Startup Jobs API for Salary and Equity Data&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;A startup jobs API for &lt;strong&gt;Wellfound&lt;/strong&gt; (formerly AngelList Talent). Search by role, location, and remote status, and get one clean JSON row per job: the full description, &lt;strong&gt;parsed salary and equity&lt;/strong&gt; ranges, and the hiring startup's signals including &lt;strong&gt;Y Combinator&lt;/strong&gt; backing, top investors, and funding stage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor:&lt;/strong&gt; &lt;a href="https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3" rel="nofollow noopener noreferrer"&gt;https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Video Walkthrough&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jREWahDGhJM" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ae9fc8cb316cea399ce612e41d29fce4742edcae31b27d5926b0909905d37e90/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f6a52455761684447684a4d2f302e6a7067" alt="Watch the walkthrough"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Text walkthrough&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;This jobs API turns Wellfound's public startup listings into structured data. You give it &lt;code&gt;roles&lt;/code&gt; (Wellfound slugs like &lt;code&gt;software-engineer&lt;/code&gt;, or plain words like "software" and "pm", which are mapped for you) and optionally &lt;code&gt;locations&lt;/code&gt; such as &lt;code&gt;san-francisco&lt;/code&gt;, &lt;code&gt;new-york&lt;/code&gt;, or &lt;code&gt;london&lt;/code&gt;. Each role and location pair becomes its own search, and the API walks the paginated results for you.&lt;/p&gt;

&lt;p&gt;Every row comes back with &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, the full markdown &lt;code&gt;description&lt;/code&gt;, and compensation parsed into real numbers: &lt;code&gt;salaryMin&lt;/code&gt;, &lt;code&gt;salaryMax&lt;/code&gt;…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnisanerd/Apify-Wellfound-Jobs-API" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Python quick start plus MCP setup walkthroughs for Claude Code, Cursor, and ChatGPT.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ about scraping Wellfound jobs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I build my own Wellfound scraper or use an API?
&lt;/h3&gt;

&lt;p&gt;Build it if the parser is the interesting part of your problem. Use the API if the data is. The three breakages above are the ones you will spend your time on, and they change without warning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use this jobs scraper from Claude or another AI agent?
&lt;/h3&gt;

&lt;p&gt;Yes. It runs as an MCP tool at &lt;code&gt;https://mcp.apify.com/?tools=actors,docs,johnvc/wellfound-jobs-api&lt;/code&gt;. There are also two open agent skills built on it, linked below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I schedule this scraper to run automatically?
&lt;/h3&gt;

&lt;p&gt;Yes, through &lt;a href="https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Apify Schedules&lt;/a&gt;, on any cron you like. Dedupe on &lt;code&gt;url&lt;/code&gt;, which is canonical and survives a company editing the job title.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the scraper return salary and equity for every job?
&lt;/h3&gt;

&lt;p&gt;No, and this is the honest limitation that matters most. It returns what the company published. Plenty of postings carry neither. Always report your coverage count alongside any figure you quote.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the scraper search Wellfound by keyword?
&lt;/h3&gt;

&lt;p&gt;Not site-wide, because Wellfound does not serve a site-wide free-text search. &lt;code&gt;keyword&lt;/code&gt; filters the jobs on the pages a run already fetched. Drive the search with &lt;code&gt;roles&lt;/code&gt; and &lt;code&gt;locations&lt;/code&gt; and use &lt;code&gt;keyword&lt;/code&gt; to narrow further.&lt;/p&gt;

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

&lt;p&gt;Two open agent skills wrap this API around ready-made workflows, both installable with &lt;code&gt;npx skills add&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/johnisanerd/claude-skill-remote-startup-jobs" rel="noopener noreferrer"&gt;claude-skill-remote-startup-jobs&lt;/a&gt; for the listings.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/johnisanerd/claude-skill-yc-startup-jobs" rel="noopener noreferrer"&gt;claude-skill-yc-startup-jobs&lt;/a&gt; for the comp benchmarking.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;If you want the parser, the code above is a fine starting point. If you want the data, the &lt;a href="https://apify.com/johnvc/wellfound-jobs-api?fpr=9n7kx3&amp;amp;fp_sid=devto" rel="noopener noreferrer"&gt;Wellfound Jobs API&lt;/a&gt; bills per job returned with no start fee, so a run that matches nothing costs essentially nothing.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>python</category>
      <category>tutorial</category>
      <category>career</category>
    </item>
  </channel>
</rss>
