<?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: Amit Aviv</title>
    <description>The latest articles on DEV Community by Amit Aviv (@amitaviv).</description>
    <link>https://dev.to/amitaviv</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%2F4191940%2F67da7695-cead-4986-9f3e-570bad2fc601.jpg</url>
      <title>DEV Community: Amit Aviv</title>
      <link>https://dev.to/amitaviv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amitaviv"/>
    <language>en</language>
    <item>
      <title>Rental yield by neighbourhood in Madrid, Lisbon and Milan, from live idealista listings</title>
      <dc:creator>Amit Aviv</dc:creator>
      <pubDate>Tue, 20 Oct 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/amitaviv/rental-yield-by-neighbourhood-in-madrid-lisbon-and-milan-from-live-idealista-listings-14d</link>
      <guid>https://dev.to/amitaviv/rental-yield-by-neighbourhood-in-madrid-lisbon-and-milan-from-live-idealista-listings-14d</guid>
      <description>&lt;p&gt;If you are deciding where to buy to let, an early question is how much rent each euro of purchase price buys in each neighbourhood. A city-wide average hides most of the answer: on the morning of 18 October 2026, gross yield across Madrid's districts ranged from 2.91% to 7.23%.&lt;/p&gt;

&lt;p&gt;This post gives district-level figures for Madrid, Lisbon and Milan. All three cities were read from the same source (idealista's live sale and long-term rent listings) on the same morning with the same method, so the figures can be compared with each other. It covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The comparison tables: median sale price per m², median rent per m², gross yield and the sample behind every row.&lt;/li&gt;
&lt;li&gt;What the numbers show, and what they don't.&lt;/li&gt;
&lt;li&gt;How to compute the same figures yourself in a spreadsheet.&lt;/li&gt;
&lt;li&gt;How to rerun it for any area of idealista Spain, Portugal or Italy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I maintain the &lt;a href="https://apify.com/amitaviv/idealista-rental-yield-finder" rel="noopener noreferrer"&gt;Idealista Rental Yield Finder&lt;/a&gt; actor on Apify, which produced the figures below. The do-it-yourself section works without it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The short version
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Whole city, gross yield from asking prices:&lt;/strong&gt; Milan 5.50%, Madrid 4.65%, Lisbon 4.04%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Within each city, the cheaper districts tended to have the higher yields.&lt;/strong&gt; Madrid ranged from 2.91% (Barrio de Salamanca) to 7.23% (Villaverde), Milan from 3.82% (Centro Storico) to 7.78% (Quarto Oggiaro - Vialba - Cascina Merlata), and Lisbon from 2.88% (Lumiar) to 5.04% (Santa Clara). Lisbon's range was the narrowest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sale prices vary much more than rents.&lt;/strong&gt; Across Madrid's districts the median sale price per m² ranged from €3,241 to €11,821, a factor of 3.6. The median rent per m² ranged from €16.67 to €28.69, a factor of 1.7. Because rents move less than prices, yields tend to be highest where prices are lowest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seasonal lets matter.&lt;/strong&gt; Of the 8,387 rental listings idealista showed for Madrid city, 3,384 (40%) were seasonal or temporary lets. For Lisbon the share was 27%, and for Milan 15%. They are left out of everything below; mixing them in would change the rent side.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Whole cities
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;City&lt;/th&gt;
&lt;th&gt;Sale €/m²&lt;/th&gt;
&lt;th&gt;Rent €/m²/month&lt;/th&gt;
&lt;th&gt;Gross yield&lt;/th&gt;
&lt;th&gt;Years of rent&lt;/th&gt;
&lt;th&gt;Sale listings used&lt;/th&gt;
&lt;th&gt;Rent listings used&lt;/th&gt;
&lt;th&gt;Seasonal share of all rentals&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Milan&lt;/td&gt;
&lt;td&gt;5,338&lt;/td&gt;
&lt;td&gt;24.47&lt;/td&gt;
&lt;td&gt;5.50%&lt;/td&gt;
&lt;td&gt;18.2&lt;/td&gt;
&lt;td&gt;402 of 15,860*&lt;/td&gt;
&lt;td&gt;270 of 12,690*&lt;/td&gt;
&lt;td&gt;15.4% (2,310 of 15,000)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Madrid&lt;/td&gt;
&lt;td&gt;6,557&lt;/td&gt;
&lt;td&gt;25.42&lt;/td&gt;
&lt;td&gt;4.65%&lt;/td&gt;
&lt;td&gt;21.5&lt;/td&gt;
&lt;td&gt;399 of 19,362*&lt;/td&gt;
&lt;td&gt;240 of 5,003*&lt;/td&gt;
&lt;td&gt;40.3% (3,384 of 8,387)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lisbon&lt;/td&gt;
&lt;td&gt;6,438&lt;/td&gt;
&lt;td&gt;21.68&lt;/td&gt;
&lt;td&gt;4.04%&lt;/td&gt;
&lt;td&gt;24.7&lt;/td&gt;
&lt;td&gt;230 of 10,683*&lt;/td&gt;
&lt;td&gt;240 of 3,956*&lt;/td&gt;
&lt;td&gt;26.9% (1,457 of 5,413)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;How to read the columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sale €/m²&lt;/strong&gt; and &lt;strong&gt;Rent €/m²/month&lt;/strong&gt; are medians of asking price divided by floor area.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gross yield&lt;/strong&gt; = 12 × median rent per m² ÷ median sale price per m².&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Years of rent&lt;/strong&gt; is the price-to-rent ratio, the inverse of the yield.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listings used&lt;/strong&gt; shows how many listings went into the medians out of how many idealista listed. &lt;code&gt;*&lt;/code&gt; means the side was sampled across the whole price range rather than read in full (see the method section). Listings without a size, auctions, bare-ownership sales and homes sold with a tenant in place are left out of the "used" count.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The city figure is computed from its own sample. It is not an average of the district rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Madrid, 21 districts
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;District&lt;/th&gt;
&lt;th&gt;Sale €/m²&lt;/th&gt;
&lt;th&gt;Rent €/m²/month&lt;/th&gt;
&lt;th&gt;Gross yield&lt;/th&gt;
&lt;th&gt;Years of rent&lt;/th&gt;
&lt;th&gt;Sale listings used&lt;/th&gt;
&lt;th&gt;Rent listings used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Villaverde&lt;/td&gt;
&lt;td&gt;3,241&lt;/td&gt;
&lt;td&gt;19.52&lt;/td&gt;
&lt;td&gt;7.23%&lt;/td&gt;
&lt;td&gt;13.8&lt;/td&gt;
&lt;td&gt;183 of 734*&lt;/td&gt;
&lt;td&gt;30 of 30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Villa de Vallecas&lt;/td&gt;
&lt;td&gt;3,889&lt;/td&gt;
&lt;td&gt;23.33&lt;/td&gt;
&lt;td&gt;7.20%&lt;/td&gt;
&lt;td&gt;13.9&lt;/td&gt;
&lt;td&gt;213 of 446*&lt;/td&gt;
&lt;td&gt;69 of 69&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Puente de Vallecas&lt;/td&gt;
&lt;td&gt;3,587&lt;/td&gt;
&lt;td&gt;20.56&lt;/td&gt;
&lt;td&gt;6.88%&lt;/td&gt;
&lt;td&gt;14.5&lt;/td&gt;
&lt;td&gt;184 of 999*&lt;/td&gt;
&lt;td&gt;54 of 54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carabanchel&lt;/td&gt;
&lt;td&gt;3,684&lt;/td&gt;
&lt;td&gt;20.15&lt;/td&gt;
&lt;td&gt;6.56%&lt;/td&gt;
&lt;td&gt;15.2&lt;/td&gt;
&lt;td&gt;197 of 1,136*&lt;/td&gt;
&lt;td&gt;91 of 91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Usera&lt;/td&gt;
&lt;td&gt;3,781&lt;/td&gt;
&lt;td&gt;19.28&lt;/td&gt;
&lt;td&gt;6.12%&lt;/td&gt;
&lt;td&gt;16.3&lt;/td&gt;
&lt;td&gt;205 of 579*&lt;/td&gt;
&lt;td&gt;50 of 50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latina&lt;/td&gt;
&lt;td&gt;4,133&lt;/td&gt;
&lt;td&gt;20.00&lt;/td&gt;
&lt;td&gt;5.81%&lt;/td&gt;
&lt;td&gt;17.2&lt;/td&gt;
&lt;td&gt;180 of 689*&lt;/td&gt;
&lt;td&gt;92 of 92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;San Blas&lt;/td&gt;
&lt;td&gt;4,177&lt;/td&gt;
&lt;td&gt;17.95&lt;/td&gt;
&lt;td&gt;5.16%&lt;/td&gt;
&lt;td&gt;19.4&lt;/td&gt;
&lt;td&gt;196 of 651*&lt;/td&gt;
&lt;td&gt;89 of 89&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ciudad Lineal&lt;/td&gt;
&lt;td&gt;5,150&lt;/td&gt;
&lt;td&gt;20.93&lt;/td&gt;
&lt;td&gt;4.88%&lt;/td&gt;
&lt;td&gt;20.5&lt;/td&gt;
&lt;td&gt;213 of 1,037*&lt;/td&gt;
&lt;td&gt;205 of 205&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vicálvaro&lt;/td&gt;
&lt;td&gt;4,282&lt;/td&gt;
&lt;td&gt;16.67&lt;/td&gt;
&lt;td&gt;4.67%&lt;/td&gt;
&lt;td&gt;21.4&lt;/td&gt;
&lt;td&gt;228 of 476*&lt;/td&gt;
&lt;td&gt;33 of 33&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tetuán&lt;/td&gt;
&lt;td&gt;6,385&lt;/td&gt;
&lt;td&gt;23.53&lt;/td&gt;
&lt;td&gt;4.42%&lt;/td&gt;
&lt;td&gt;22.6&lt;/td&gt;
&lt;td&gt;218 of 1,058*&lt;/td&gt;
&lt;td&gt;239 of 419*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arganzuela&lt;/td&gt;
&lt;td&gt;6,310&lt;/td&gt;
&lt;td&gt;23.12&lt;/td&gt;
&lt;td&gt;4.40%&lt;/td&gt;
&lt;td&gt;22.7&lt;/td&gt;
&lt;td&gt;217 of 714*&lt;/td&gt;
&lt;td&gt;204 of 204&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hortaleza&lt;/td&gt;
&lt;td&gt;5,720&lt;/td&gt;
&lt;td&gt;20.55&lt;/td&gt;
&lt;td&gt;4.31%&lt;/td&gt;
&lt;td&gt;23.2&lt;/td&gt;
&lt;td&gt;223 of 717*&lt;/td&gt;
&lt;td&gt;252 of 252&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centro&lt;/td&gt;
&lt;td&gt;7,640&lt;/td&gt;
&lt;td&gt;26.84&lt;/td&gt;
&lt;td&gt;4.21%&lt;/td&gt;
&lt;td&gt;23.7&lt;/td&gt;
&lt;td&gt;231 of 2,334*&lt;/td&gt;
&lt;td&gt;240 of 880*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moncloa&lt;/td&gt;
&lt;td&gt;6,448&lt;/td&gt;
&lt;td&gt;21.78&lt;/td&gt;
&lt;td&gt;4.05%&lt;/td&gt;
&lt;td&gt;24.7&lt;/td&gt;
&lt;td&gt;225 of 836*&lt;/td&gt;
&lt;td&gt;272 of 272&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fuencarral&lt;/td&gt;
&lt;td&gt;5,664&lt;/td&gt;
&lt;td&gt;19.01&lt;/td&gt;
&lt;td&gt;4.03%&lt;/td&gt;
&lt;td&gt;24.8&lt;/td&gt;
&lt;td&gt;222 of 757*&lt;/td&gt;
&lt;td&gt;185 of 185&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chamartín&lt;/td&gt;
&lt;td&gt;8,296&lt;/td&gt;
&lt;td&gt;24.17&lt;/td&gt;
&lt;td&gt;3.50%&lt;/td&gt;
&lt;td&gt;28.6&lt;/td&gt;
&lt;td&gt;228 of 963*&lt;/td&gt;
&lt;td&gt;239 of 408*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retiro&lt;/td&gt;
&lt;td&gt;8,413&lt;/td&gt;
&lt;td&gt;23.85&lt;/td&gt;
&lt;td&gt;3.40%&lt;/td&gt;
&lt;td&gt;29.4&lt;/td&gt;
&lt;td&gt;233 of 876*&lt;/td&gt;
&lt;td&gt;334 of 334&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chamberí&lt;/td&gt;
&lt;td&gt;9,277&lt;/td&gt;
&lt;td&gt;26.13&lt;/td&gt;
&lt;td&gt;3.38%&lt;/td&gt;
&lt;td&gt;29.6&lt;/td&gt;
&lt;td&gt;233 of 1,472*&lt;/td&gt;
&lt;td&gt;240 of 573*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barrio de Salamanca&lt;/td&gt;
&lt;td&gt;11,821&lt;/td&gt;
&lt;td&gt;28.69&lt;/td&gt;
&lt;td&gt;2.91%&lt;/td&gt;
&lt;td&gt;34.3&lt;/td&gt;
&lt;td&gt;234 of 2,501*&lt;/td&gt;
&lt;td&gt;240 of 725*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barajas (low sample)&lt;/td&gt;
&lt;td&gt;5,277&lt;/td&gt;
&lt;td&gt;20.46&lt;/td&gt;
&lt;td&gt;4.65%&lt;/td&gt;
&lt;td&gt;21.5&lt;/td&gt;
&lt;td&gt;148 of 154&lt;/td&gt;
&lt;td&gt;26 of 26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moratalaz (low sample)&lt;/td&gt;
&lt;td&gt;4,667&lt;/td&gt;
&lt;td&gt;16.94&lt;/td&gt;
&lt;td&gt;4.35%&lt;/td&gt;
&lt;td&gt;23.0&lt;/td&gt;
&lt;td&gt;204 of 233&lt;/td&gt;
&lt;td&gt;12 of 12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The five districts with yields above 6% are all in the south of the city, and all have few long-term rentals listed: between 30 and 91 each, against 446 to 1,136 homes for sale. Villaverde's 7.23% rests on 30 rentals, the minimum before a row is flagged.&lt;/li&gt;
&lt;li&gt;Barajas and Moratalaz are flagged as low sample (fewer than 30 rentals) and ranked last. Treat their yields as indicative only.&lt;/li&gt;
&lt;li&gt;Centro had the highest seasonal share of any area in the three cities: 54.5% of its rental listings were seasonal or temporary lets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lisbon, 24 parishes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parish&lt;/th&gt;
&lt;th&gt;Sale €/m²&lt;/th&gt;
&lt;th&gt;Rent €/m²/month&lt;/th&gt;
&lt;th&gt;Gross yield&lt;/th&gt;
&lt;th&gt;Years of rent&lt;/th&gt;
&lt;th&gt;Sale listings used&lt;/th&gt;
&lt;th&gt;Rent listings used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Santa Clara&lt;/td&gt;
&lt;td&gt;3,966&lt;/td&gt;
&lt;td&gt;16.67&lt;/td&gt;
&lt;td&gt;5.04%&lt;/td&gt;
&lt;td&gt;19.8&lt;/td&gt;
&lt;td&gt;114 of 116&lt;/td&gt;
&lt;td&gt;42 of 42&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;São Vicente&lt;/td&gt;
&lt;td&gt;5,707&lt;/td&gt;
&lt;td&gt;22.80&lt;/td&gt;
&lt;td&gt;4.79%&lt;/td&gt;
&lt;td&gt;20.9&lt;/td&gt;
&lt;td&gt;235 of 615*&lt;/td&gt;
&lt;td&gt;162 of 162&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ajuda&lt;/td&gt;
&lt;td&gt;5,536&lt;/td&gt;
&lt;td&gt;21.21&lt;/td&gt;
&lt;td&gt;4.60%&lt;/td&gt;
&lt;td&gt;21.8&lt;/td&gt;
&lt;td&gt;162 of 174&lt;/td&gt;
&lt;td&gt;72 of 72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Olivais&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;td&gt;18.53&lt;/td&gt;
&lt;td&gt;4.45%&lt;/td&gt;
&lt;td&gt;22.5&lt;/td&gt;
&lt;td&gt;229 of 237&lt;/td&gt;
&lt;td&gt;74 of 74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Penha de França&lt;/td&gt;
&lt;td&gt;5,741&lt;/td&gt;
&lt;td&gt;20.47&lt;/td&gt;
&lt;td&gt;4.28%&lt;/td&gt;
&lt;td&gt;23.4&lt;/td&gt;
&lt;td&gt;227 of 490*&lt;/td&gt;
&lt;td&gt;160 of 160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Beato&lt;/td&gt;
&lt;td&gt;5,946&lt;/td&gt;
&lt;td&gt;20.49&lt;/td&gt;
&lt;td&gt;4.14%&lt;/td&gt;
&lt;td&gt;24.2&lt;/td&gt;
&lt;td&gt;200 of 203&lt;/td&gt;
&lt;td&gt;41 of 41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Misericórdia&lt;/td&gt;
&lt;td&gt;7,143&lt;/td&gt;
&lt;td&gt;24.62&lt;/td&gt;
&lt;td&gt;4.14%&lt;/td&gt;
&lt;td&gt;24.2&lt;/td&gt;
&lt;td&gt;234 of 653*&lt;/td&gt;
&lt;td&gt;237 of 237&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Santa Maria Maior&lt;/td&gt;
&lt;td&gt;6,655&lt;/td&gt;
&lt;td&gt;22.77&lt;/td&gt;
&lt;td&gt;4.11%&lt;/td&gt;
&lt;td&gt;24.4&lt;/td&gt;
&lt;td&gt;235 of 702*&lt;/td&gt;
&lt;td&gt;203 of 203&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marvila&lt;/td&gt;
&lt;td&gt;6,335&lt;/td&gt;
&lt;td&gt;21.38&lt;/td&gt;
&lt;td&gt;4.05%&lt;/td&gt;
&lt;td&gt;24.7&lt;/td&gt;
&lt;td&gt;228 of 233&lt;/td&gt;
&lt;td&gt;68 of 68&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Santo António&lt;/td&gt;
&lt;td&gt;8,618&lt;/td&gt;
&lt;td&gt;28.47&lt;/td&gt;
&lt;td&gt;3.97%&lt;/td&gt;
&lt;td&gt;25.2&lt;/td&gt;
&lt;td&gt;236 of 702*&lt;/td&gt;
&lt;td&gt;354 of 354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Campo de Ourique&lt;/td&gt;
&lt;td&gt;6,795&lt;/td&gt;
&lt;td&gt;22.26&lt;/td&gt;
&lt;td&gt;3.93%&lt;/td&gt;
&lt;td&gt;25.4&lt;/td&gt;
&lt;td&gt;287 of 295&lt;/td&gt;
&lt;td&gt;166 of 166&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Campolide&lt;/td&gt;
&lt;td&gt;6,638&lt;/td&gt;
&lt;td&gt;21.74&lt;/td&gt;
&lt;td&gt;3.93%&lt;/td&gt;
&lt;td&gt;25.4&lt;/td&gt;
&lt;td&gt;331 of 333&lt;/td&gt;
&lt;td&gt;156 of 156&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arroios&lt;/td&gt;
&lt;td&gt;6,716&lt;/td&gt;
&lt;td&gt;21.72&lt;/td&gt;
&lt;td&gt;3.88%&lt;/td&gt;
&lt;td&gt;25.8&lt;/td&gt;
&lt;td&gt;239 of 929*&lt;/td&gt;
&lt;td&gt;331 of 331&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alcântara&lt;/td&gt;
&lt;td&gt;6,560&lt;/td&gt;
&lt;td&gt;20.74&lt;/td&gt;
&lt;td&gt;3.79%&lt;/td&gt;
&lt;td&gt;26.4&lt;/td&gt;
&lt;td&gt;254 of 256&lt;/td&gt;
&lt;td&gt;94 of 94&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Areeiro&lt;/td&gt;
&lt;td&gt;6,019&lt;/td&gt;
&lt;td&gt;18.82&lt;/td&gt;
&lt;td&gt;3.75%&lt;/td&gt;
&lt;td&gt;26.6&lt;/td&gt;
&lt;td&gt;267 of 269&lt;/td&gt;
&lt;td&gt;141 of 141&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;São Domingos de Benfica&lt;/td&gt;
&lt;td&gt;5,755&lt;/td&gt;
&lt;td&gt;17.76&lt;/td&gt;
&lt;td&gt;3.70%&lt;/td&gt;
&lt;td&gt;27.0&lt;/td&gt;
&lt;td&gt;228 of 364*&lt;/td&gt;
&lt;td&gt;185 of 185&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Estrela&lt;/td&gt;
&lt;td&gt;7,628&lt;/td&gt;
&lt;td&gt;23.33&lt;/td&gt;
&lt;td&gt;3.67%&lt;/td&gt;
&lt;td&gt;27.2&lt;/td&gt;
&lt;td&gt;235 of 817*&lt;/td&gt;
&lt;td&gt;281 of 281&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carnide&lt;/td&gt;
&lt;td&gt;5,548&lt;/td&gt;
&lt;td&gt;16.87&lt;/td&gt;
&lt;td&gt;3.65%&lt;/td&gt;
&lt;td&gt;27.4&lt;/td&gt;
&lt;td&gt;67 of 68&lt;/td&gt;
&lt;td&gt;45 of 45&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alvalade&lt;/td&gt;
&lt;td&gt;6,295&lt;/td&gt;
&lt;td&gt;18.89&lt;/td&gt;
&lt;td&gt;3.60%&lt;/td&gt;
&lt;td&gt;27.8&lt;/td&gt;
&lt;td&gt;275 of 275&lt;/td&gt;
&lt;td&gt;227 of 227&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avenidas Novas&lt;/td&gt;
&lt;td&gt;7,219&lt;/td&gt;
&lt;td&gt;21.19&lt;/td&gt;
&lt;td&gt;3.52%&lt;/td&gt;
&lt;td&gt;28.4&lt;/td&gt;
&lt;td&gt;233 of 584*&lt;/td&gt;
&lt;td&gt;302 of 302&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benfica&lt;/td&gt;
&lt;td&gt;6,029&lt;/td&gt;
&lt;td&gt;17.33&lt;/td&gt;
&lt;td&gt;3.45%&lt;/td&gt;
&lt;td&gt;29.0&lt;/td&gt;
&lt;td&gt;214 of 916*&lt;/td&gt;
&lt;td&gt;134 of 134&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Belém&lt;/td&gt;
&lt;td&gt;7,310&lt;/td&gt;
&lt;td&gt;20.15&lt;/td&gt;
&lt;td&gt;3.31%&lt;/td&gt;
&lt;td&gt;30.2&lt;/td&gt;
&lt;td&gt;342 of 345&lt;/td&gt;
&lt;td&gt;132 of 132&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parque das Nações&lt;/td&gt;
&lt;td&gt;6,655&lt;/td&gt;
&lt;td&gt;18.17&lt;/td&gt;
&lt;td&gt;3.28%&lt;/td&gt;
&lt;td&gt;30.5&lt;/td&gt;
&lt;td&gt;321 of 328&lt;/td&gt;
&lt;td&gt;154 of 154&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lumiar&lt;/td&gt;
&lt;td&gt;6,749&lt;/td&gt;
&lt;td&gt;16.22&lt;/td&gt;
&lt;td&gt;2.88%&lt;/td&gt;
&lt;td&gt;34.7&lt;/td&gt;
&lt;td&gt;239 of 779*&lt;/td&gt;
&lt;td&gt;195 of 195&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lisbon is the flattest of the three cities. 21 of its 24 parishes fall between 3.3% and 4.8%.&lt;/li&gt;
&lt;li&gt;13 of the 24 parishes were small enough for both sides to be read in full. A cell without &lt;code&gt;*&lt;/code&gt; is based on every listing idealista showed that morning, not on a sample.&lt;/li&gt;
&lt;li&gt;Santa Maria Maior (the old centre) had 46.2% of its rentals listed as seasonal or temporary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Milan, 18 zones
&lt;/h2&gt;

&lt;p&gt;idealista.it lists 18 zones for Milan.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Zone&lt;/th&gt;
&lt;th&gt;Sale €/m²&lt;/th&gt;
&lt;th&gt;Rent €/m²/month&lt;/th&gt;
&lt;th&gt;Gross yield&lt;/th&gt;
&lt;th&gt;Years of rent&lt;/th&gt;
&lt;th&gt;Sale listings used&lt;/th&gt;
&lt;th&gt;Rent listings used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Quarto Oggiaro - Vialba - Cascina Merlata&lt;/td&gt;
&lt;td&gt;3,384&lt;/td&gt;
&lt;td&gt;21.95&lt;/td&gt;
&lt;td&gt;7.78%&lt;/td&gt;
&lt;td&gt;12.8&lt;/td&gt;
&lt;td&gt;306 of 344&lt;/td&gt;
&lt;td&gt;54 of 54&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Famagosta - Naviglio Grande&lt;/td&gt;
&lt;td&gt;4,339&lt;/td&gt;
&lt;td&gt;20.00&lt;/td&gt;
&lt;td&gt;5.53%&lt;/td&gt;
&lt;td&gt;18.1&lt;/td&gt;
&lt;td&gt;224 of 521*&lt;/td&gt;
&lt;td&gt;285 of 285&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baggio&lt;/td&gt;
&lt;td&gt;3,313&lt;/td&gt;
&lt;td&gt;15.24&lt;/td&gt;
&lt;td&gt;5.52%&lt;/td&gt;
&lt;td&gt;18.1&lt;/td&gt;
&lt;td&gt;272 of 335&lt;/td&gt;
&lt;td&gt;43 of 43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comasina - Bicocca&lt;/td&gt;
&lt;td&gt;4,299&lt;/td&gt;
&lt;td&gt;19.76&lt;/td&gt;
&lt;td&gt;5.52%&lt;/td&gt;
&lt;td&gt;18.1&lt;/td&gt;
&lt;td&gt;208 of 1,523*&lt;/td&gt;
&lt;td&gt;240 of 799*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forlanini&lt;/td&gt;
&lt;td&gt;3,646&lt;/td&gt;
&lt;td&gt;16.67&lt;/td&gt;
&lt;td&gt;5.48%&lt;/td&gt;
&lt;td&gt;18.2&lt;/td&gt;
&lt;td&gt;260 of 287&lt;/td&gt;
&lt;td&gt;101 of 101&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;San Siro - Trenno&lt;/td&gt;
&lt;td&gt;4,223&lt;/td&gt;
&lt;td&gt;19.07&lt;/td&gt;
&lt;td&gt;5.42%&lt;/td&gt;
&lt;td&gt;18.5&lt;/td&gt;
&lt;td&gt;181 of 902*&lt;/td&gt;
&lt;td&gt;324 of 324&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abbiategrasso - Chiesa Rossa&lt;/td&gt;
&lt;td&gt;4,446&lt;/td&gt;
&lt;td&gt;19.71&lt;/td&gt;
&lt;td&gt;5.32%&lt;/td&gt;
&lt;td&gt;18.8&lt;/td&gt;
&lt;td&gt;220 of 550*&lt;/td&gt;
&lt;td&gt;319 of 319&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vigentino - Ripamonti&lt;/td&gt;
&lt;td&gt;4,718&lt;/td&gt;
&lt;td&gt;20.76&lt;/td&gt;
&lt;td&gt;5.28%&lt;/td&gt;
&lt;td&gt;18.9&lt;/td&gt;
&lt;td&gt;221 of 573*&lt;/td&gt;
&lt;td&gt;354 of 354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greco - Turro&lt;/td&gt;
&lt;td&gt;4,546&lt;/td&gt;
&lt;td&gt;19.79&lt;/td&gt;
&lt;td&gt;5.22%&lt;/td&gt;
&lt;td&gt;19.1&lt;/td&gt;
&lt;td&gt;208 of 2,005*&lt;/td&gt;
&lt;td&gt;240 of 936*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certosa&lt;/td&gt;
&lt;td&gt;4,382&lt;/td&gt;
&lt;td&gt;19.00&lt;/td&gt;
&lt;td&gt;5.20%&lt;/td&gt;
&lt;td&gt;19.2&lt;/td&gt;
&lt;td&gt;198 of 659*&lt;/td&gt;
&lt;td&gt;240 of 240&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corvetto - Rogoredo&lt;/td&gt;
&lt;td&gt;4,164&lt;/td&gt;
&lt;td&gt;17.27&lt;/td&gt;
&lt;td&gt;4.98%&lt;/td&gt;
&lt;td&gt;20.1&lt;/td&gt;
&lt;td&gt;222 of 408*&lt;/td&gt;
&lt;td&gt;203 of 203&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lorenteggio - Bande Nere&lt;/td&gt;
&lt;td&gt;4,930&lt;/td&gt;
&lt;td&gt;19.44&lt;/td&gt;
&lt;td&gt;4.73%&lt;/td&gt;
&lt;td&gt;21.1&lt;/td&gt;
&lt;td&gt;223 of 862*&lt;/td&gt;
&lt;td&gt;240 of 592*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Città Studi - Lambrate&lt;/td&gt;
&lt;td&gt;5,444&lt;/td&gt;
&lt;td&gt;21.43&lt;/td&gt;
&lt;td&gt;4.72%&lt;/td&gt;
&lt;td&gt;21.2&lt;/td&gt;
&lt;td&gt;220 of 1,237*&lt;/td&gt;
&lt;td&gt;240 of 686*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Porta Vittoria&lt;/td&gt;
&lt;td&gt;6,229&lt;/td&gt;
&lt;td&gt;24.39&lt;/td&gt;
&lt;td&gt;4.70%&lt;/td&gt;
&lt;td&gt;21.3&lt;/td&gt;
&lt;td&gt;228 of 882*&lt;/td&gt;
&lt;td&gt;240 of 1,405*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Garibaldi - Porta Venezia&lt;/td&gt;
&lt;td&gt;7,333&lt;/td&gt;
&lt;td&gt;27.20&lt;/td&gt;
&lt;td&gt;4.45%&lt;/td&gt;
&lt;td&gt;22.5&lt;/td&gt;
&lt;td&gt;222 of 1,956*&lt;/td&gt;
&lt;td&gt;240 of 2,265*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fiera - De Angeli&lt;/td&gt;
&lt;td&gt;7,414&lt;/td&gt;
&lt;td&gt;26.39&lt;/td&gt;
&lt;td&gt;4.27%&lt;/td&gt;
&lt;td&gt;23.4&lt;/td&gt;
&lt;td&gt;227 of 1,562*&lt;/td&gt;
&lt;td&gt;240 of 1,885*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigli - Bocconi&lt;/td&gt;
&lt;td&gt;7,101&lt;/td&gt;
&lt;td&gt;25.02&lt;/td&gt;
&lt;td&gt;4.23%&lt;/td&gt;
&lt;td&gt;23.7&lt;/td&gt;
&lt;td&gt;229 of 941*&lt;/td&gt;
&lt;td&gt;240 of 1,408*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centro Storico&lt;/td&gt;
&lt;td&gt;11,771&lt;/td&gt;
&lt;td&gt;37.50&lt;/td&gt;
&lt;td&gt;3.82%&lt;/td&gt;
&lt;td&gt;26.2&lt;/td&gt;
&lt;td&gt;298 of 313&lt;/td&gt;
&lt;td&gt;240 of 791*&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The top row is an outlier. Quarto Oggiaro - Vialba - Cascina Merlata had a median sale price close to Baggio's (€3,384 vs €3,313 per m²) but a much higher median rent (€21.95 vs €15.24), from 54 rentals. A gap like that is worth checking listing by listing before you believe it. For example, the mix of new and old buildings on each side may differ.&lt;/li&gt;
&lt;li&gt;Without that row, Milan's zones span 3.82% to 5.53%, and 9 of the 18 sit between 5.20% and 5.53%.&lt;/li&gt;
&lt;li&gt;Many Italian sale listings are auctions ("asta"), which are left out. That is why "used" can be well below "listed" even where a zone was read in full.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Small flats vs family flats
&lt;/h2&gt;

&lt;p&gt;Every report also splits its figures by rooms. Here are the whole-city bands (yield, with sale / rent listings used):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rooms band&lt;/th&gt;
&lt;th&gt;Madrid&lt;/th&gt;
&lt;th&gt;Lisbon&lt;/th&gt;
&lt;th&gt;Milan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0-1&lt;/td&gt;
&lt;td&gt;5.16% (61 / 78)&lt;/td&gt;
&lt;td&gt;3.88% (46 / 77)&lt;/td&gt;
&lt;td&gt;5.64% (27 / 54)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4.77% (108 / 77)&lt;/td&gt;
&lt;td&gt;3.76% (85 / 79)&lt;/td&gt;
&lt;td&gt;5.27% (153 / 139)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3.89% (136 / 40)&lt;/td&gt;
&lt;td&gt;4.43% (51 / 58)&lt;/td&gt;
&lt;td&gt;5.46% (130 / 41)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Madrid and Lisbon count bedrooms. Italy counts rooms including the living room, so Milan's "2" is a one-bedroom flat and its "0-1" is a studio (monolocale). Compare bands within a city, not across cities. These bands come from sampled sides with 27 to 153 listings each, and the actor's documentation puts the sampling error at band level at about 10%. Madrid shows a clear gradient from 0-1 to 3 bedrooms, with smaller homes yielding more. In Lisbon and Milan the differences are small enough that sampling error could account for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the numbers were computed
&lt;/h2&gt;

&lt;p&gt;For each area, two idealista searches were read: homes for sale, and homes for rent with idealista's own long-term filter. These are the actual searches for Villaverde:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.idealista.com/venta-viviendas/madrid/villaverde/
https://www.idealista.com/alquiler-viviendas/madrid/villaverde/con-alquiler-de-larga-temporada/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Only the results pages were read: price, previous price, size, rooms and tags from each card. No property pages, and no personal data.&lt;/li&gt;
&lt;li&gt;Sides with up to 360 listings were read in full. Larger sides were sampled. Pages were sorted by price, then read at evenly spaced positions from cheapest to dearest, and each page was weighted by the share of the list it stands for. A sample taken only from the first pages in default order would be biased towards whatever idealista shows first.&lt;/li&gt;
&lt;li&gt;Listings that are not a free-market price were left out: bare ownership (nuda propiedad), occupied homes, homes sold with a tenant ("alquilada", "arrendada", "affittata") and auctions. Seasonal lets were left out of the rent side.&lt;/li&gt;
&lt;li&gt;Price per m² was computed for every remaining listing, and the median was taken on each side. The median is used rather than the mean so that a handful of penthouses doesn't drag the figure.&lt;/li&gt;
&lt;li&gt;Gross yield = 12 × median rent per m² ÷ median sale price per m². For Villaverde that is 12 × 19.52 ÷ 3,241 = 7.23%.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The sampling was checked against a full read of one Madrid neighbourhood (374 sale listings, 14 October). The sample's median sale price per m² was 1.9% off and the yield was 0.07 points off. That is one check, not a guarantee for every area.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;p&gt;Read these before you use any number above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asking prices, not transactions.&lt;/strong&gt; Both sides are what advertisers ask. Final sale prices and agreed rents can differ, and the gap varies by area and over time. Listings that don't sell or let stay online longer, so the stock of listings can over-represent homes priced above the market.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gross, not net.&lt;/strong&gt; The yield comes before community fees, property tax, insurance, maintenance, vacancy, letting fees, purchase taxes and costs, and income tax. Net yield is always lower, and how much lower depends on the property and on you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different homes on each side.&lt;/strong&gt; Rental listings were smaller than sale listings in 62 of the 66 areas. For Madrid city, the median was 99 m² for sale and 84 m² for rent. Smaller homes rent for more per m², which tends to push a per-m² gross yield up. To compare like with like, use the rooms bands, or filter both sides to the same size and type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample size.&lt;/strong&gt; Every row shows its sample. Rows with fewer than 30 listings with price and size on either side are flagged as low sample. A yield needs at least 5 listings on each side. Several of the highest yields above come from rent sides of 30 to 69 listings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One morning.&lt;/strong&gt; All figures were read between 09:12 and 09:25 UTC on 18 October 2026. Listing stock changes daily. Re-run the same areas monthly to see a trend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Districts are big.&lt;/strong&gt; A Madrid district or a Milan zone mixes very different streets. The same method works one level down (a district's neighbourhoods) when you need that detail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not investment advice.&lt;/strong&gt; This is a screening tool for deciding where to look next, not a valuation.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;You can reproduce any row by hand. For one neighbourhood, it takes an evening:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the idealista sale search for the area. Open the rent search for the same area with the long-term filter on (&lt;code&gt;con-alquiler-de-larga-temporada&lt;/code&gt; in Spain, &lt;code&gt;com-arrendamento-longa-duracao&lt;/code&gt; in Portugal, &lt;code&gt;con-affitto-lungo-termine&lt;/code&gt; in Italy).&lt;/li&gt;
&lt;li&gt;Sort both by price. If a side has a few hundred listings, read all of it. If it has more, take pages spread evenly from cheapest to dearest, not just the first few.&lt;/li&gt;
&lt;li&gt;Copy price and m² for each listing into a sheet, and skip auctions, bare ownership and tenanted homes.&lt;/li&gt;
&lt;li&gt;Add a column &lt;code&gt;=price/m2&lt;/code&gt;, take &lt;code&gt;MEDIAN()&lt;/code&gt; of it on each side, then compute &lt;code&gt;=12*rent_median/sale_median&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Write down how many listings you used on each side. If the rent side is under 30, treat the result as a hint, not a figure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the whole method. The actor does the same thing for many areas at once, every time with the same rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running it for any area
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In the Apify Console:&lt;/strong&gt; open &lt;a href="https://apify.com/amitaviv/idealista-rental-yield-finder" rel="noopener noreferrer"&gt;Idealista Rental Yield Finder&lt;/a&gt; and paste one or more areas, either as idealista search URLs or as location slugs. Turn on "Also report every sub-area" for one report per district, then press Start. The reports download as JSON, CSV or Excel, and a &lt;code&gt;COMPARISON&lt;/code&gt; table sorted by yield is saved with the run.&lt;/p&gt;

&lt;p&gt;These are the inputs used for this post:&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;"areas"&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;"madrid-madrid"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"includeSubAreas"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"areas"&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;"pt:lisboa"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"includeSubAreas"&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"areas"&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;"it:milano-milano"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"includeSubAreas"&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;Narrower questions use the same fields. For example, two-bedroom flats in each neighbourhood of Madrid's Centro:&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;"areas"&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;"madrid/centro"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"includeSubAreas"&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;"propertyType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"flats"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rooms"&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;"2"&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;You can also paste any idealista search URL with filters already set. Rooms, size, type and features are applied to both the sale and the rent side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From code:&lt;/strong&gt; start a run, then fetch the reports when it finishes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# start&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &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="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/amitaviv~idealista-rental-yield-finder/runs"&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;'{"areas":["pt:lisboa"],"includeSubAreas":true}'&lt;/span&gt;
&lt;span class="c"&gt;# the response holds data.id, data.defaultDatasetId and data.defaultKeyValueStoreId&lt;/span&gt;

&lt;span class="c"&gt;# status (READY / RUNNING / SUCCEEDED / FAILED / TIMED-OUT / ABORTED)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&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="s2"&gt;"https://api.apify.com/v2/actor-runs/&amp;lt;runId&amp;gt;"&lt;/span&gt;

&lt;span class="c"&gt;# reports as CSV, and the ranked comparison&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&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="s2"&gt;"https://api.apify.com/v2/datasets/&amp;lt;datasetId&amp;gt;/items?format=csv"&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&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="s2"&gt;"https://api.apify.com/v2/key-value-stores/&amp;lt;storeId&amp;gt;/records/COMPARISON"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A whole city with its districts took about 8 minutes for Madrid and about 13 minutes each for Lisbon and Milan, so start the run and poll it rather than waiting on one HTTP request. To build a market tracker, a monthly schedule per city keeps a history of the same areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;You pay per report delivered, not for run time or proxy traffic. These are the prices on 18 October 2026, by Apify plan:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Bronze&lt;/th&gt;
&lt;th&gt;Silver&lt;/th&gt;
&lt;th&gt;Gold and above&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Area or sub-area report&lt;/td&gt;
&lt;td&gt;$0.06&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;td&gt;$0.045&lt;/td&gt;
&lt;td&gt;$0.04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run start (per GB of memory, 2 GB by default)&lt;/td&gt;
&lt;td&gt;$0.0042&lt;/td&gt;
&lt;td&gt;$0.0035&lt;/td&gt;
&lt;td&gt;$0.00315&lt;/td&gt;
&lt;td&gt;$0.0028&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At Bronze prices, the runs behind this post cost:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Reports&lt;/th&gt;
&lt;th&gt;Bronze price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Madrid + 21 districts&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;22 × $0.05 + 2 × $0.0035 = $1.107&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lisbon + 24 parishes&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;$1.257&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Milan + 18 zones&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;$0.957&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One neighbourhood&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;$0.057&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An area that fails, or that has no listings, is not charged. If you set a maximum charge for a run, the actor stops before going over and keeps what it delivered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data and legal notes
&lt;/h2&gt;

&lt;p&gt;The actor reads only listing pages that idealista shows publicly without a login, and it returns aggregated statistics per area. It returns no names, phone numbers, photos or other personal data. If you use it, you are responsible for respecting idealista's terms and the data-protection and database rules of your country.&lt;/p&gt;

&lt;p&gt;The figures in this post come from three runs on 18 October 2026: &lt;code&gt;LqPvqgvQXyScM1mg1&lt;/code&gt; (Madrid), &lt;code&gt;PUEuFzkTvHyPOsbJF&lt;/code&gt; (Lisbon) and &lt;code&gt;fqQBYybaqbaPHbloJ&lt;/code&gt; (Milan).&lt;/p&gt;

&lt;p&gt;If you run it on another city and something looks wrong, open an issue on the actor page with the run id.&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>realestate</category>
      <category>datascience</category>
      <category>investing</category>
    </item>
    <item>
      <title>How to see which companies are hiring right now (and what changed this week) from Greenhouse, Lever, Ashby and Workday boards</title>
      <dc:creator>Amit Aviv</dc:creator>
      <pubDate>Sun, 18 Oct 2026 11:34:43 +0000</pubDate>
      <link>https://dev.to/amitaviv/how-to-see-which-companies-are-hiring-right-now-and-what-changed-this-week-from-greenhouse-5gci</link>
      <guid>https://dev.to/amitaviv/how-to-see-which-companies-are-hiring-right-now-and-what-changed-this-week-from-greenhouse-5gci</guid>
      <description>&lt;p&gt;A company's open roles hint at where its money is going next. If it adds five enterprise Account Executives in Germany, it probably plans to sell harder there. If it closes its design roles and opens compliance roles, its priorities may have shifted. You don't need a data vendor to see this. Most tech companies list their jobs through a hosted job board such as Greenhouse, Lever, Ashby or Workday, and those boards serve the jobs as public JSON so that the company's own careers page can show them.&lt;/p&gt;

&lt;p&gt;This post covers three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to read those boards yourself with a 24-line script.&lt;/li&gt;
&lt;li&gt;What a weekly "who is hiring, and what changed" check looked like on eight well-known companies on 18 October 2026, with the real output.&lt;/li&gt;
&lt;li&gt;How to schedule the check weekly and send the results to Slack or a Google Sheet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I maintain the &lt;a href="https://apify.com/amitaviv/company-hiring-tracker" rel="noopener noreferrer"&gt;Company Hiring Tracker&lt;/a&gt; actor on Apify, which produced the examples below. The do-it-yourself part works without it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The job boards serve public JSON
&lt;/h2&gt;

&lt;p&gt;Each of these endpoints answered on 18 October 2026, and the job counts matched the actor's run that day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Greenhouse (Vercel: 93 open jobs)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://boards-api.greenhouse.io/v1/boards/vercel/jobs

&lt;span class="c"&gt;# Lever (Palantir: 310)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://api.lever.co/v0/postings/palantir?mode=json"&lt;/span&gt;

&lt;span class="c"&gt;# Ashby (Linear: 29)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.ashbyhq.com/posting-api/job-board/linear

&lt;span class="c"&gt;# Workday (Zendesk: 139). Workday uses POST and pages of 20.&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://zendesk.wd1.myworkdayjobs.com/wday/cxs/zendesk/zendesk/jobs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"limit":20,"offset":0,"appliedFacets":{},"searchText":""}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The board name in the URL is usually the company's slug, which you can read off the careers page link (&lt;code&gt;job-boards.greenhouse.io/vercel&lt;/code&gt;, &lt;code&gt;jobs.lever.co/palantir&lt;/code&gt;, &lt;code&gt;jobs.ashbyhq.com/linear&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The interesting signal is not the number of open jobs but &lt;strong&gt;what changed&lt;/strong&gt;. Here is a minimal weekly diff for one Greenhouse board, using only the Python standard library (3.11 or later):&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;sys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&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="c1"&gt;# e.g. vercel -&amp;gt; https://job-boards.greenhouse.io/vercel
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&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;https://boards-api.greenhouse.io/v1/boards/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/jobs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;jobs&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;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jobs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;week_ago&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;first_published&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;week_ago&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="n"&gt;slug&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;jobs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; open jobs, &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;recent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; first published in the last 7 days&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Compare with the snapshot saved by the previous run, then save this one.
&lt;/span&gt;&lt;span class="n"&gt;snap&lt;/span&gt; &lt;span class="o"&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="n"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;before&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;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;FileNotFoundError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&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;j&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;jobs&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;before&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;jid&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&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;NEW   &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;jid&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;jid&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&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;CLOSED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;jid&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&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;&lt;code&gt;python3 board_diff.py vercel&lt;/code&gt; printed &lt;code&gt;vercel: 93 open jobs, 2 first published in the last 7 days&lt;/code&gt; on 18 October. Run it from cron once a week and you have a basic hiring monitor for one company.&lt;/p&gt;

&lt;p&gt;It gets harder once you track a list of accounts instead of one company:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finding the board.&lt;/strong&gt; A CRM gives you &lt;code&gt;figma.com&lt;/code&gt;, not &lt;code&gt;greenhouse:figma&lt;/code&gt;. You have to read the careers page, find which vendor it embeds, and check that the board really belongs to that company. A careers page can link to someone else's board.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each vendor is different.&lt;/strong&gt; The date fields differ (&lt;code&gt;first_published&lt;/code&gt;, &lt;code&gt;createdAt&lt;/code&gt;, &lt;code&gt;publishedAt&lt;/code&gt;). Workday is paged and only says "Posted 3 Days Ago", up to "30+ Days Ago".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Counting by team.&lt;/strong&gt; "How many sales roles?" needs every title mapped to a function and a seniority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeping the history.&lt;/strong&gt; You need a snapshot per company, and the diff has to skip boards that were only partly read, or you get phantom "closed" jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is what the actor does, so the rest of this post uses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real example: eight companies on 18 October 2026
&lt;/h2&gt;

&lt;p&gt;Input (run &lt;code&gt;TcvvetXuELC1Ph1xz&lt;/code&gt;, 12 seconds):&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;"companies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"stripe.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"notion.so"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"linear.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"figma.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"databricks.com"&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://jobs.lever.co/palantir"&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://zendesk.wd1.myworkdayjobs.com/zendesk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"vercel.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&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;"account executive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data engineer"&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;Domains were resolved to their boards automatically. Notion, Linear and Vercel were found through links on their careers pages, and Stripe, Figma and Databricks by trying the company name on the job boards and checking the result. Palantir and Zendesk were given as board URLs. Workday is only used when you give the career-site URL, or when the company's website links to it.&lt;/p&gt;

&lt;p&gt;These companies had last been checked on 14 October, so each record also shows what changed in the four days since:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Company&lt;/th&gt;
&lt;th&gt;Board&lt;/th&gt;
&lt;th&gt;Open jobs&lt;/th&gt;
&lt;th&gt;Posted in last 7 days&lt;/th&gt;
&lt;th&gt;Posted in last 30 days&lt;/th&gt;
&lt;th&gt;New since last run&lt;/th&gt;
&lt;th&gt;Closed since last run&lt;/th&gt;
&lt;th&gt;Net change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Databricks&lt;/td&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;898&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;+4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stripe&lt;/td&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;732&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;240&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Palantir&lt;/td&gt;
&lt;td&gt;Lever&lt;/td&gt;
&lt;td&gt;310&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;−4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Figma&lt;/td&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;139&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;−6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zendesk&lt;/td&gt;
&lt;td&gt;Workday&lt;/td&gt;
&lt;td&gt;139&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;−1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;td&gt;Ashby&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;−2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;Greenhouse&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;+3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linear&lt;/td&gt;
&lt;td&gt;Ashby&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;−1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Stripe shows no changes because its previous check was earlier the same morning, not on 14 October. That is what a record looks like when nothing has moved.&lt;/p&gt;

&lt;p&gt;Here is Vercel's record, shortened (the per-location, per-department and latest-jobs lists are cut):&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"greenhouse:vercel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"companyName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Vercel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"greenhouse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"boardUrl"&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://job-boards.greenhouse.io/vercel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"matchedBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"careers-page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isHiring"&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;"openJobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"countComplete"&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;"jobsPostedLast7Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsPostedLast30Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsPostedLast90Days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"medianJobAgeDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsByFunction"&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="nl"&gt;"Sales"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Engineering"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Design"&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;"Product"&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;"Finance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Marketing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"People &amp;amp; HR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Customer Success &amp;amp; Support"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Legal &amp;amp; Compliance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Other"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Data &amp;amp; AI"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Operations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsBySeniority"&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="nl"&gt;"mid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"manager"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"senior"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"lead"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"director"&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;"intern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"leadershipJobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsByCountry"&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="nl"&gt;"US"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"GB"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"DE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"AU"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"IN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jobsByWorkplace"&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="nl"&gt;"remote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"hybrid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"onsite"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"unspecified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywordMatches"&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="nl"&gt;"account executive"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data engineer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isFirstRun"&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;"previousRunAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-14T16:10:40.459Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openJobsAtPreviousRun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"openJobsChange"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"newJobsSinceLastRun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"closedJobsSinceLastRun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"functionChanges"&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="nl"&gt;"Sales"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"newJobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GTM 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;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Field Readiness"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"seniority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hybrid - San Francisco, New York City, Austin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"postedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-10-15T23:13:47.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&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://job-boards.greenhouse.io/vercel/jobs/6225825004"&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="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security Software Engineer, IAM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"seniority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Remote - United States"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"postedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-25T00:19:22.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&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://job-boards.greenhouse.io/vercel/jobs/6093255004"&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="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Solutions Architect"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"department"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Solution Architects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"function"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"seniority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lead"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Remote - United Kingdom, Germany"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"postedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-02-09T21:37:43.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&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://job-boards.greenhouse.io/vercel/jobs/5796302004"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"closedJobs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What the fields mean
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hiring velocity&lt;/strong&gt; counts the jobs that are open now, grouped by when the board says each one was posted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jobsPostedLast7Days&lt;/code&gt;, &lt;code&gt;jobsPostedLast30Days&lt;/code&gt;, &lt;code&gt;jobsPostedLast90Days&lt;/code&gt;: open jobs whose posting date falls in that window. Databricks had 47 of its 898 open jobs posted in the last 7 days. Palantir had 5 of 310.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;medianJobAgeDays&lt;/code&gt;: the age of the typical open job. A high median means many long-running postings. Palantir's was 479 days and Linear's 143. A low median means the openings are mostly recent.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jobsWithPostingDate&lt;/code&gt;: how many jobs had a date at all. This matters for Workday, which only shows dates up to "30+ Days Ago". Zendesk had dates on 81 of its 139 jobs, so its 90-day count covers only those 81.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Changes since the previous run&lt;/strong&gt; compare this run's job ids with the last run's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;newJobsSinceLastRun&lt;/code&gt; and &lt;code&gt;newJobs&lt;/code&gt;: jobs that are open now and were not open last time. Some carry an older &lt;code&gt;postedAt&lt;/code&gt;. Vercel's "Security Software Engineer, IAM" is dated June, yet it was not in the 14 October snapshot. If you only want freshly posted roles, also filter on &lt;code&gt;postedAt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;closedJobsSinceLastRun&lt;/code&gt; and &lt;code&gt;closedJobs&lt;/code&gt;: jobs that were open last time and are gone now. A closed job may have been filled, paused or re-posted under a new id, which counts as one closed and one new. A job is only reported closed when both runs read the whole board (&lt;code&gt;countComplete: true&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;openJobsChange&lt;/code&gt;: the net change. It can hide a lot of movement. Databricks was +4 net, but that was 30 new jobs and 26 closed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;functionChanges&lt;/code&gt;: the net change per function. Databricks was Engineering +4, Data &amp;amp; AI +4 and Sales −7. Figma was Operations −4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;function&lt;/code&gt; and &lt;code&gt;seniority&lt;/code&gt; come from the job title (and the department when the title is ambiguous). They are rules of thumb, not a ground truth: "Account Executive" is Sales/mid, and "Staff Engineer" is lead. Use them for trends rather than for exact headcount.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three practical uses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Outbound sales triggers
&lt;/h3&gt;

&lt;p&gt;A company that is hiring for a function is likely to spend on it: on tools for the new people, and on the problems that new team was hired to solve. Two ways to use this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Companies mode with &lt;code&gt;keywords&lt;/code&gt;&lt;/strong&gt; gives a count per keyword for every account. In the run above, "account executive" matched 106 open titles at Stripe, 81 at Databricks, 26 at Zendesk and 0 at Notion. "security" matched 28 at Databricks and 24 at Palantir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jobs mode with filters&lt;/strong&gt; lists the matching roles themselves. Run &lt;code&gt;fgfuI8MIvIvOvYb5A&lt;/code&gt; asked for titles containing "account executive" posted in the last 7 days at five companies, and returned 29 jobs in 9 seconds: 12 at Stripe, 12 at Databricks, 5 at Zendesk, and none at Figma or Vercel. Four of them:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Company&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;Posted&lt;/th&gt;
&lt;th&gt;Pay (where published)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stripe&lt;/td&gt;
&lt;td&gt;Account Executive, Funded Startups DACH&lt;/td&gt;
&lt;td&gt;Berlin&lt;/td&gt;
&lt;td&gt;2026-10-16&lt;/td&gt;
&lt;td&gt;not published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks&lt;/td&gt;
&lt;td&gt;Emerging Enterprise Core Account Executive, DACH&lt;/td&gt;
&lt;td&gt;Munich, Germany&lt;/td&gt;
&lt;td&gt;2026-10-15&lt;/td&gt;
&lt;td&gt;not published&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databricks&lt;/td&gt;
&lt;td&gt;Enterprise Account Executive, Federal Health&lt;/td&gt;
&lt;td&gt;Remote - Washington D.C.&lt;/td&gt;
&lt;td&gt;2026-10-14&lt;/td&gt;
&lt;td&gt;$272,000 – $374,000 USD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zendesk&lt;/td&gt;
&lt;td&gt;Senior Enterprise Account Executive&lt;/td&gt;
&lt;td&gt;Remote, Colorado&lt;/td&gt;
&lt;td&gt;about 2026-10-16 (Workday says "2 days ago")&lt;/td&gt;
&lt;td&gt;not published&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you sell sales tooling into DACH, those first two rows suggest which accounts to look at first this week. The data contains roles, not people: no recruiter or hiring-manager names or contact details. Use it to choose accounts and timing, and reach people through your normal, lawful channels.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Competitor tracking
&lt;/h3&gt;

&lt;p&gt;Put your competitors in one list with their own tracking key (&lt;code&gt;"monitorKey": "competitors"&lt;/code&gt;), run it weekly, and read &lt;code&gt;functionChanges&lt;/code&gt;, &lt;code&gt;newJobs&lt;/code&gt; and &lt;code&gt;closedJobs&lt;/code&gt;. In the four days covered above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figma closed 8 roles and opened 2. The new ones were "Director, Governance Risk &amp;amp; Compliance" and "Compliance Engineer". The closed ones included "Federal Compliance Manager" and "Senior Analyst, Revenue Transformation".&lt;/li&gt;
&lt;li&gt;Vercel added two Sales-function roles (one of them a "GTM Engineer") and one Security role, and closed nothing.&lt;/li&gt;
&lt;li&gt;Notion had 17 of its 128 open roles in Japan and 5 in Korea (&lt;code&gt;jobsByCountry&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One week of changes is an anecdote. The value comes from the same list read every week for a quarter.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Investment and market research
&lt;/h3&gt;

&lt;p&gt;For a portfolio or a market map, compare the velocity and mix fields across companies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pace&lt;/strong&gt;: the 30-day count against the total open jobs. Stripe: 240 of 732 posted in the last 30 days. Palantir: 16 of 310.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mix&lt;/strong&gt;: Sales was the largest function at Stripe (239 of 732) and Figma (50 of 139). Engineering was largest at Palantir (173 of 310) and Databricks (329 of 898, with Sales close behind at 316).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seniority&lt;/strong&gt;: &lt;code&gt;leadershipJobs&lt;/code&gt; (manager, director and executive titles) was 136 at Stripe and 176 at Databricks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open roles are a signal, not a headcount. Some companies keep evergreen postings open for years, and some hire through channels that never show up on a board. Read the trend across several weeks before drawing conclusions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run it weekly and send the results to Slack or a Google Sheet
&lt;/h2&gt;

&lt;p&gt;These steps are all in the Apify Console, with no code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Save the input as a task.&lt;/strong&gt; Open the &lt;a href="https://apify.com/amitaviv/company-hiring-tracker" rel="noopener noreferrer"&gt;actor&lt;/a&gt;, paste your companies (domains from a CRM export work as they are), set a tracking key such as &lt;code&gt;crm-tier-1&lt;/code&gt; so this list keeps its own history, and save the input as a task. Make two tasks if you want both views:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Weekly account signals&lt;/em&gt;: mode "companies". One record per company, with the new and closed jobs inside it.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;New roles feed&lt;/em&gt;: mode "jobs", with &lt;code&gt;onlyNew: true&lt;/code&gt;, your &lt;code&gt;keywords&lt;/code&gt;, and &lt;code&gt;postedWithinDays: 7&lt;/code&gt;. Each run delivers, and charges for, only jobs that earlier &lt;code&gt;onlyNew&lt;/code&gt; runs with the same tracking key did not deliver. Without &lt;code&gt;postedWithinDays&lt;/code&gt;, the first run delivers every open job that matches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Schedule it.&lt;/strong&gt; Go to &lt;strong&gt;Schedules → Create new&lt;/strong&gt;, set a cron expression such as &lt;code&gt;0 8 * * 1&lt;/code&gt; (08:00 every Monday) and a timezone, add your task, and click &lt;strong&gt;Enable&lt;/strong&gt;. New schedules are created disabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Send to Slack.&lt;/strong&gt; In the task's &lt;strong&gt;Integrations&lt;/strong&gt; tab, choose Slack, connect your workspace, pick a channel and the event "run succeeded". The message field accepts a template, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*Weekly hiring check done*
Results: https://console.apify.com/actors/runs/{{resource.id}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Slack message announces the run and links to it. If you want the job titles themselves in the channel, add a webhook integration on the same event and point it at a Make, Zapier or n8n flow that reads the run's dataset and posts each row.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Send to a Google Sheet.&lt;/strong&gt; In the same Integrations tab, either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if your Integrations tab offers it as an actor-to-actor integration, add the &lt;em&gt;Google Sheets Import &amp;amp; Export&lt;/em&gt; actor (&lt;code&gt;lukaskrivka/google-sheets&lt;/code&gt;), connect your Google account, choose the spreadsheet, and set &lt;code&gt;datasetId&lt;/code&gt; to &lt;code&gt;{{resource.defaultDatasetId}}&lt;/code&gt; and &lt;code&gt;mode&lt;/code&gt; to &lt;code&gt;append&lt;/code&gt;, so every weekly run adds its new roles below last week's (it is a separate actor, billed for its own platform usage); or&lt;/li&gt;
&lt;li&gt;use &lt;strong&gt;Upload results to GDrive&lt;/strong&gt;, which saves each successful run's results as a file in an &lt;code&gt;Apify Uploads&lt;/code&gt; folder in your Google Drive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "new roles feed" task works best with the Sheet. Because &lt;code&gt;onlyNew&lt;/code&gt; delivers each job once, the sheet becomes a running log of every new matching role, one row each, with title, company, location, posting date, link and, where the board publishes it, salary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;The actor charges per event. The prices below are from the live pricing record on 18 October 2026, for the Free plan and the Bronze tier. Silver and Gold tiers pay less.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Free plan&lt;/th&gt;
&lt;th&gt;Bronze&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run start (per GB of memory; the default 512 MB counts as one)&lt;/td&gt;
&lt;td&gt;$0.0036&lt;/td&gt;
&lt;td&gt;$0.003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Company record (companies mode)&lt;/td&gt;
&lt;td&gt;$0.0048&lt;/td&gt;
&lt;td&gt;$0.004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job record (jobs mode)&lt;/td&gt;
&lt;td&gt;$0.0006&lt;/td&gt;
&lt;td&gt;$0.0005&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two runs in this post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eight companies, companies mode: 8 × $0.0048 + $0.0036 = &lt;strong&gt;$0.042&lt;/strong&gt; on the Free plan ($0.035 on Bronze).&lt;/li&gt;
&lt;li&gt;29 matching jobs, jobs mode: 29 × $0.0006 + $0.0036 = &lt;strong&gt;$0.021&lt;/strong&gt; on the Free plan ($0.0175 on Bronze).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A worked example: you track 200 accounts that resolve to a board, once a week, in companies mode. Each run costs 200 × $0.0048 + $0.0036 = $0.96 on the Free plan, or $3.85 for four weekly runs ($0.80 and $3.21 on Bronze). Companies whose board can't be found cost nothing, and they are listed in the run summary with the reason. A maximum charge set on the run is respected: the actor stops before it would exceed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits worth knowing before you rely on it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supported boards&lt;/strong&gt;: Greenhouse, Lever, Ashby, Workable, SmartRecruiters, Recruitee, Personio, Teamtailor and Workday. Not supported: iCIMS, Taleo, SuccessFactors, Eightfold, Phenom, BambooHR, Jobvite, custom career sites, and EU-hosted Greenhouse boards. In a test on 101 well-known tech domains, 72 resolved to a board and 29 did not (21 linked no supported board). For a company that doesn't resolve, paste its board URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workday&lt;/strong&gt; is only used when you give the career-site URL, or when the company's website links to it. Its jobs have no department, and they have no date when older than 30 days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Salary&lt;/strong&gt; only appears where the board publishes it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One board per company.&lt;/strong&gt; A company that lists jobs from several boards on one careers page will show fewer jobs than its page does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only need one or two companies, the script above is enough. If you want a list of accounts checked every Monday, with the diff, the team mix and a Slack or Sheet feed, try &lt;a href="https://apify.com/amitaviv/company-hiring-tracker" rel="noopener noreferrer"&gt;Company Hiring Tracker on Apify&lt;/a&gt; on your own list. The default input runs on three companies.&lt;/p&gt;

</description>
      <category>startup</category>
      <category>automation</category>
      <category>datascience</category>
      <category>sales</category>
    </item>
  </channel>
</rss>
