<?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: Radar Labs</title>
    <description>The latest articles on DEV Community by Radar Labs (@sdijjxcfs).</description>
    <link>https://dev.to/sdijjxcfs</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%2F4199040%2Ff204050b-fbb3-43b3-8579-1f23c8a9a262.png</url>
      <title>DEV Community: Radar Labs</title>
      <link>https://dev.to/sdijjxcfs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sdijjxcfs"/>
    <language>en</language>
    <item>
      <title>Six APIs, zero keys: what 18,825 real job postings contain</title>
      <dc:creator>Radar Labs</dc:creator>
      <pubDate>Thu, 22 Oct 2026 21:27:25 +0000</pubDate>
      <link>https://dev.to/sdijjxcfs/six-apis-zero-keys-what-18825-real-job-postings-contain-4a7a</link>
      <guid>https://dev.to/sdijjxcfs/six-apis-zero-keys-what-18825-real-job-postings-contain-4a7a</guid>
      <description>&lt;p&gt;I wanted a job feed I could filter myself, so I tried to fetch one from the source instead of the aggregators. It turns out that most company career pages are thin wrappers around a handful of applicant tracking systems (ATS), and those systems expose JSON endpoints without keys or login.&lt;/p&gt;

&lt;p&gt;Six of them answered. I guessed 527 plausible company slugs, &lt;strong&gt;259 responded&lt;/strong&gt;, and that produced &lt;strong&gt;18,825 real job postings&lt;/strong&gt;. Here is what I found in them — including two bugs that silently published numbers that were off by two orders of magnitude.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six endpoints
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ATS&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Auth&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boards-api.greenhouse.io/v1/boards/{slug}/jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lever&lt;/td&gt;
&lt;td&gt;&lt;code&gt;api.lever.co/v0/postings/{slug}?mode=json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashby&lt;/td&gt;
&lt;td&gt;&lt;code&gt;api.ashbyhq.com/posting-api/job-board/{slug}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none (add &lt;code&gt;?includeCompensation=true&lt;/code&gt; for pay)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;apply.workable.com/api/v1/widget/accounts/{slug}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personio&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{slug}.jobs.personio.de/xml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workday&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST {tenant}.wd{N}.myworkdayjobs.com/wday/cxs/{tenant}/{site}/jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All public, all read-only, none of them need an account. Some have changed shape or disappeared: SmartRecruiters returned 404 on both endpoints I tried, and Teamtailor customers usually sit behind their own domain so the documented JSON path just 404s.&lt;/p&gt;

&lt;p&gt;Workday is the awkward one. It needs a tenant, a cluster number and a site name before you can address a board at all, and guessing is close to hopeless: 24 well-known companies × 2 clusters × 4 site names = 192 probes, &lt;strong&gt;exactly one&lt;/strong&gt; hit. Everything else had to be supplied by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a sweep returns
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;18,825&lt;/strong&gt; postings from 259 companies (49% of guessed slugs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8,071 with a published salary (43%)&lt;/strong&gt; — but that number only exists because of the mistake below, which is the most interesting thing I learned&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Finding 1: I was wrong about Greenhouse
&lt;/h2&gt;

&lt;p&gt;My first sweep looked like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ATS&lt;/th&gt;
&lt;th&gt;Companies&lt;/th&gt;
&lt;th&gt;Postings&lt;/th&gt;
&lt;th&gt;With salary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;135&lt;/td&gt;
&lt;td&gt;11,608&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashby&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;5,274&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,734&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lever&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;1,810&lt;/td&gt;
&lt;td&gt;160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workable&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;121&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;93% of every salary-bearing row came from Ashby. Greenhouse had the volume and essentially no pay, so the obvious conclusion was "Greenhouse doesn't publish salaries".&lt;/p&gt;

&lt;p&gt;That conclusion was wrong, and the reason is that I was asking for the wrong payload. &lt;code&gt;?content=false&lt;/code&gt; returns postings with the &lt;code&gt;metadata&lt;/code&gt; array set to &lt;code&gt;null&lt;/code&gt; for all of them. Ask for &lt;code&gt;?content=true&lt;/code&gt; and the pay range is sitting right there in the description text — &lt;strong&gt;44% of Greenhouse postings have one&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ATS&lt;/th&gt;
&lt;th&gt;Companies&lt;/th&gt;
&lt;th&gt;Postings&lt;/th&gt;
&lt;th&gt;With salary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;134&lt;/td&gt;
&lt;td&gt;11,619&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5,164 (44%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashby&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;td&gt;5,283&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,739 (52%)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lever&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;1,802&lt;/td&gt;
&lt;td&gt;168 (9%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workable&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;121&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The trap is that Greenhouse's &lt;code&gt;content&lt;/code&gt; field is &lt;strong&gt;double-escaped HTML&lt;/strong&gt;: the description literally contains &lt;code&gt;&amp;amp;lt;div class="content-intro"&amp;amp;gt;&lt;/code&gt;. One &lt;code&gt;html.unescape&lt;/code&gt; is not enough. If you unescape once and search for &lt;code&gt;$&lt;/code&gt;, you find nothing and conclude there is no salary. You need to unescape until the string stops changing (I cap it at three rounds).&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 2: Ashby hides its compensation behind one flag
&lt;/h2&gt;

&lt;p&gt;Ashby returns beautiful structured compensation — &lt;code&gt;compensationTiers&lt;/code&gt;, &lt;code&gt;summaryComponents&lt;/code&gt; with &lt;code&gt;minValue&lt;/code&gt;, &lt;code&gt;maxValue&lt;/code&gt;, &lt;code&gt;currencyCode&lt;/code&gt;, &lt;code&gt;interval&lt;/code&gt; — but &lt;strong&gt;only when you pass &lt;code&gt;?includeCompensation=true&lt;/code&gt;&lt;/strong&gt;. Without the flag you get a gorgeous list of jobs and zero numbers. Same failure mode as Greenhouse, different cause: the API is right, the request is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 3: the $1,536,000 ghost
&lt;/h2&gt;

&lt;p&gt;Lever returns structured ranges:&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;"min"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;128000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"max"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;176000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"per-month-salary"&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;That is a monthly salary — in a Latin American band — labeled &lt;code&gt;USD&lt;/code&gt;. Annualise it and you get &lt;strong&gt;$1,536,000&lt;/strong&gt; for a DevOps engineer. It briefly topped the entire scan and looked completely legitimate, because it was a well-formed number in a well-formed field.&lt;/p&gt;

&lt;p&gt;Then this one, from a long Greenhouse description:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The base salary range is 210,000 USD - 310,000 USD. Some hourly employees exist.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The word "hourly" appears somewhere in the text, so my annualiser multiplied an annual range by 2,080 and produced &lt;strong&gt;$436,800,000&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Both bugs share a shape: &lt;strong&gt;the output was plausible&lt;/strong&gt;. A range that is off by 12× or 2,080× does not look broken; it looks like a senior role at a rich company.&lt;/p&gt;

&lt;p&gt;I stopped trying to repair these and started deleting them. Anything that annualises below $5,000, above $5,000,000, or above $1,500,000 in USD loses its salary fields entirely while the posting stays. And the unit words are only read from the ~40 characters &lt;strong&gt;after the last number&lt;/strong&gt; in the sentence, not from the whole description:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_unit_tail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# "…210,000 USD - 310,000 USD. Some hourly employees exist."
&lt;/span&gt;    &lt;span class="c1"&gt;# -&amp;gt; only look at " USD." , so "hourly" later in the text cannot fire
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since then the maximum salary in a full sweep is $850,000, which belongs to the posting it is attached to.&lt;/p&gt;

&lt;p&gt;Lesson: in a data product, one wrong order of magnitude is worse than one missing field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 4: the pay range is not always a number
&lt;/h2&gt;

&lt;p&gt;American postings often write the currency after &lt;em&gt;each&lt;/em&gt; number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The base salary range is 196,000 USD - 310,500 USD.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My regex was built for &lt;code&gt;$196,000 - $310,500&lt;/code&gt;, so it matched the first number plus "USD", stopped, and produced &lt;code&gt;196000 - 196000&lt;/code&gt;. The output looked perfect — a single plausible number — which is exactly the kind of bug that ships. You need a separate pattern for &lt;code&gt;number currency - number currency&lt;/code&gt;, and you need to decide what to do about postings that list several bands (&lt;code&gt;… for Level 4, and … for Level 5&lt;/code&gt;); I take the first band and say so in the docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 5: dedupe and "only new" are the real features
&lt;/h2&gt;

&lt;p&gt;Large companies post the same role on several boards, so a raw sweep duplicates heavily: &lt;strong&gt;18,825 rows collapsed to 15,528&lt;/strong&gt;. And if you (or your users) pay per row, the feature everyone actually wants is "only the postings I have not seen yet" — which needs a stable fingerprint per posting plus somewhere to persist the seen set. Mine is &lt;code&gt;company + normalised title + url&lt;/code&gt;, hashed, stored in a key-value store, capped at 50k entries, FIFO.&lt;/p&gt;

&lt;p&gt;The normalisation detail that matters: strip punctuation and case, but &lt;strong&gt;do not&lt;/strong&gt; strip location qualifiers. &lt;code&gt;Engineer (Remote)&lt;/code&gt; and &lt;code&gt;Engineer (Berlin)&lt;/code&gt; are different jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to try this yourself
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Do not trust labels, tags or category counts — measure the payload.&lt;/li&gt;
&lt;li&gt;Ask for compensation explicitly (Ashby), and fall back to reading the description (Greenhouse, Workday).&lt;/li&gt;
&lt;li&gt;Guard every annualisation with a plausibility bound, and &lt;strong&gt;drop rather than repair&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Deduplicate on &lt;code&gt;company + normalised title + url&lt;/code&gt;, never on title alone.&lt;/li&gt;
&lt;li&gt;Store a fingerprint per posting if you want incremental results.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Honest limits
&lt;/h2&gt;

&lt;p&gt;Slug guessing worked 49% of the time. Workable boards often answer with an empty shell. Some postings are evergreen and never close, so "new" is fuzzy at the edges. Salary only exists when a company chooses to publish it — 43% of rows here, not 100%. And a wrong number is worse than a missing one, so I drop aggressively and tell users when a company returned nothing.&lt;/p&gt;

&lt;p&gt;I packaged this as a small tool that scans the six APIs, normalises salaries to annual USD, dedupes across boards and can return only new postings: &lt;a href="https://apify.com/contributory_garnet_hyz/ats-job-feed" rel="noopener noreferrer"&gt;ATS Job Feed&lt;/a&gt;. It ships the list of 259 companies that were verified live, so you do not have to guess slugs, and it can return only postings that actually state a salary.&lt;/p&gt;

&lt;p&gt;If you pull job data for a living: which of these six APIs has bitten you the hardest? I would like to know which shape I should handle next.&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>data</category>
      <category>career</category>
    </item>
    <item>
      <title>I built a job-lead radar because the job boards I tried returned garbage</title>
      <dc:creator>Radar Labs</dc:creator>
      <pubDate>Wed, 21 Oct 2026 19:29:02 +0000</pubDate>
      <link>https://dev.to/sdijjxcfs/i-built-a-job-lead-radar-because-the-job-boards-i-tried-returned-garbage-1bcc</link>
      <guid>https://dev.to/sdijjxcfs/i-built-a-job-lead-radar-because-the-job-boards-i-tried-returned-garbage-1bcc</guid>
      <description>&lt;p&gt;Solo developers don't have a finding-work problem. They have a filtering problem. I spent a week measuring exactly how bad the filtering is, then built a small tool around the answer. Every number below comes from my own runs in October 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  The noise, measured
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub bounties.&lt;/strong&gt; I pulled open issues labelled bounty: 4,640 of them. In the 200 most recently created, exactly 4 carried a dollar figure, and 191 came from a single repository that opens issues in bulk. Sampling 298 issues from the bigger bounty label pool, 208 had a price and the median was 5 dollars (p25 3, p75 7, max 750). Roughly two thirds of that sample came from one account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hacker News.&lt;/strong&gt; The monthly Freelancer? Seeking freelancer? thread is half people looking for work, not posting it. In the October 2026 thread, 21 of the top-level comments were resumes. Salaried postings are a separate problem: if you rank them together, a 200k-a-year role crowds out every contract gig, because no single project will ever outbid an annual salary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freelancer.com.&lt;/strong&gt; Wide open API and a trap: most listings are priced in rupees. My first version ranked a 1,500 INR project as if it were 1,500 USD. It sat at the top of the list for an hour before I noticed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three mistakes I made, and the fix
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. A 248,400 dollar lead that was not a lead.&lt;/strong&gt; Top of my ranking one morning was a GitHub pull request titled Add researched paid bug bounty target list, whose body said: total advertised value 230,000 EUR across 214 programs. My parser saw a currency symbol and a number. Now a price only counts if a bounty-ish word (bounty, reward, budget, payout, prize) sits within 60 characters of it, and aggregate words (total, across, combined, median, pool) disqualify the match outright. Both rules came from that one failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Treating a bounty range as a price.&lt;/strong&gt; Programs publish a range, for example 500 to 30,000. Taking the top put a 248,000 dollar project at number one; taking the bottom pushed good programs under 20 dollar bounties. The geometric mean of the two ends is a much better estimate of what a program actually pays, so that is what I use, and the output marks it as an estimate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Filtering by date on things that never expire.&lt;/strong&gt; Bounty programs stay open for months. A 21-day recency window deleted almost all of them. Recency now only applies to sources where it means something.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules that survived
&lt;/h2&gt;

&lt;p&gt;Effort matters more than payout. A 5,000 dollar project that needs a 40-hour full-stack build is not better than a 400 dollar one that takes four hours, so every lead gets an effort estimate from its text and the ranking is dollars per hour, not dollars.&lt;/p&gt;

&lt;p&gt;Deduplication matters. The same job gets reposted across sources, so titles are normalized before ranking and the most valuable copy survives.&lt;/p&gt;

&lt;p&gt;And the output says what it threw away. The run summary is always three numbers: how many items were scraped, how many survived filtering, how many were returned. When a source starts returning junk, the middle number tells you before the list does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does not do
&lt;/h2&gt;

&lt;p&gt;It does not bid on anything. Every platform's terms forbid automated bidding, and a bot-written proposal loses to a human one. It does not send messages and it does not guarantee a lead is still open, so check before you quote.&lt;/p&gt;

&lt;p&gt;Coverage is five sources: GitHub bounties, two Hacker News monthly threads, Freelancer.com, YesWeHack programs, and Remotive for remote roles. No Chinese platforms yet. The Freelancer.com endpoint rate-limits after a couple of minutes of hammering, so that one source alone takes about 90 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it lives
&lt;/h2&gt;

&lt;p&gt;It runs as a hosted Actor on Apify, so there is nothing to install and nothing to keep alive:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/contributory_garnet_hyz/freelance-lead-radar" rel="noopener noreferrer"&gt;https://apify.com/contributory_garnet_hyz/freelance-lead-radar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pricing is per lead returned plus a small per-run start charge. Filtered-out noise is not billed. A default run returns 25 leads, which comes to about 38 cents.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would like to know
&lt;/h2&gt;

&lt;p&gt;The scoring weights are the part I am least sure about: payout 42 percent, ease 22 percent, skill fit 21 percent, freshness 9 percent, competition 6 percent. If you have built a similar filter for your own work search, what would you weight differently? I would rather change the weights than keep guessing.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow-up:&lt;/strong&gt; I later went to the source of these postings — 527 company career pages, six public ATS APIs, 18,825 real postings — and found that two of my salary numbers were off by 12× and 2,080×. That write-up is here: &lt;a href="https://dev.to/sdijjxcfs/six-apis-zero-keys-what-18825-real-job-postings-contain-4a7a"&gt;Six APIs, zero keys: what 18,825 real job postings contain&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>career</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
