| Ticker | Sector | Period | Revenue | n reqs | Hiring R&D | Filed R&D | R&D ratio | Hiring S&M | Filed S&M | Hiring COGS | Filed COGS | Signal |
|---|
| Sector | Open reqs | Tickers | Coverage | Avg salary | Est. payroll | % of universe |
|---|
| Ticker | Sector | n | R&D count | R&D $ | Δpp | Interpretation |
|---|
| Ticker | Sector | AI reqs | Total | Share |
|---|
| Sector | Total reqs | AI/ML % | GPU % | Cloud % |
|---|
| Ticker | Open today | Tracked ever | Closed (lifetime) | Avg days open | Closure rate |
|---|
| Ticker | n | Desc | Salary | Emp | Posted | Dept | Skills | Yrs |
|---|
How this dashboard is built: every job-board URL, the deduplication logic, the anti-bot tooling, every bug fixed and what to watch for. Snapshot 2026-06-02 — 35 tickers, 62 distinct (ticker, ats, board) leaves, ~39,000 open reqs/day.
Public, unauthenticated. Listing JSON at https://boards-api.greenhouse.io/v1/boards/<slug>/jobs; per-job detail at …/jobs/<job_id>.
| Ticker | Subsidiary | Slug | Listing URL |
|---|---|---|---|
| ABNB | Airbnb | airbnb | …/boards/airbnb/jobs |
| APP | AppLovin | applovin | …/boards/applovin/jobs |
| CART | Instacart (Maplebear) | instacart | …/boards/instacart/jobs |
| COMP | Compass | urbancompass | …/boards/urbancompass/jobs |
| CVNA | Carvana | carvana | …/boards/carvana/jobs |
| CVNA | Carvana → ADESA | adesa | …/boards/adesa/jobs |
| DASH | DoorDash | doordashusa | …/boards/doordashusa/jobs |
| DASH | DoorDash → Bbot (2022) | bbot | …/boards/bbot/jobs |
| EXPE | Expedia → Trivago (60%) | trivago | …/boards/trivago/jobs |
| GOOGL | Alphabet → Calico Labs | calicolabs | …/boards/calicolabs/jobs |
| LIFE | Ethos Technologies | ethoslife | …/boards/ethoslife/jobs |
| LYFT | Lyft | lyft | …/boards/lyft/jobs |
| PINS | pinterest | …/boards/pinterest/jobs | |
| PTON | Peloton | peloton | …/boards/peloton/jobs |
| RBLX | Roblox | roblox | …/boards/roblox/jobs |
| RDDT | reddit | …/boards/reddit/jobs | |
| ROKU | Roku | roku | …/boards/roku/jobs |
| TTWO | Take-Two (corp) | taketwo | …/boards/taketwo/jobs |
| TTWO | Rockstar Games | rockstargames | …/boards/rockstargames/jobs |
| TTWO | 2K Games | 2k | …/boards/2k/jobs |
| TTWO | Zynga | zyngacareers | …/boards/zyngacareers/jobs |
| TTWO | Gearbox (acq Apr 2024) | gearbox | …/boards/gearbox/jobs |
| UBER | Uber → Careem (2020) | careem | …/boards/careem/jobs |
| BKNG | Booking → Agoda | agoda | …/boards/agoda/jobs |
| BKNG | Booking → OpenTable (2014) | opentable | …/boards/opentable/jobs |
POST to https://<tenant>.<subdomain>.myworkdayjobs.com/wday/cxs/<tenant>/<site>/jobs with body {"appliedFacets":{}, "limit":20, "offset":0, "searchText":""}. The subdomain (wd1/wd3/wd5/wd108) is the Workday cluster. Pagination caps at 10000.
| Ticker | Tenant | Sub | Site | Full POST URL |
|---|---|---|---|---|
| ETSY | etsy | wd5 | Etsy_Careers | https://etsy.wd5.myworkdayjobs.com/wday/cxs/etsy/Etsy_Careers/jobs |
| SNAP | snapchat | wd1 | snap | https://snapchat.wd1.myworkdayjobs.com/wday/cxs/snapchat/snap/jobs |
| EXPE | expedia | wd108 | search | https://expedia.wd108.myworkdayjobs.com/wday/cxs/expedia/search/jobs |
| Z | zillow | wd5 | Zillow_Group_External | https://zillow.wd5.myworkdayjobs.com/wday/cxs/zillow/Zillow_Group_External/jobs |
| GOOGL→Verily | verily | wd1 | Verily_Careers | https://verily.wd1.myworkdayjobs.com/wday/cxs/verily/Verily_Careers/jobs |
| U | unitytech | wd1 | Unity | https://unitytech.wd1.myworkdayjobs.com/wday/cxs/unitytech/Unity/jobs |
EXPE's Workday is the single consolidated portal for the entire Expedia Group (Hotels.com, Vrbo, Travelocity, Hotwire, Orbitz, Ebookers, CheapTickets, CarRentals, Wotif, Expedia Cruises). No per-brand careers subdomain exists.
Public API https://api.lever.co/v0/postings/<company>?mode=json — returns descriptionPlain (clean text), description (HTML), createdAt (Unix ms), categories.{team, commitment, location}.
| Ticker | Company slug | Full URL |
|---|---|---|
| MTCH | matchgroup | …/v0/postings/matchgroup |
| WMG | wmg | …/v0/postings/wmg |
BMBL was Lever-hosted (bumbleinc) from ~May 2026 until ~Sep 2026, when the Lever board went empty and team.bumble.com switched to Ashby — see §1.4.
GraphQL: https://jobs.ashbyhq.com/api/non-user-graphql?op=ApiJobBoardWithTeams, body {"operationName":"ApiJobBoardWithTeams","variables":{"organizationHostedJobsPageName":"kayak"}}.
| Ticker | Org | Human listing |
|---|---|---|
| BKNG→KAYAK | kayak | jobs.ashbyhq.com/kayak |
| BMBL | bumbleinc | jobs.ashbyhq.com/bumbleinc |
OPEN migrated Greenhouse → Rippling on 2026-05-18. Old Greenhouse board now 404s. Clean public API:
| Ticker | Slug | Listing API |
|---|---|---|
| OPEN | opendoor | api.rippling.com/platform/api/ats/v1/board/opendoor/jobs |
Phenom is a third-party career-site platform. Its paginated API caps at ~500 with shuffle-induced duplicates — the bypass is the SEO sitemap (see §4.6). Each detail page embeds JSON-LD JobPosting.
| Ticker | Listing UI | Sitemap |
|---|---|---|
| EBAY | jobs.ebayinc.com/us/en/search-results | sitemap.xml → sitemap1 (500) + sitemap2 (77) = 576 |
| CHWY | careers.chewy.com/us/en/search-results | (pagination; sitemap not yet enabled) |
amazon_jobs) — 4 passes, 8+ board valueshttps://www.amazon.jobs/en/search.json — sharded by 60 business_category buckets (endpoint hard-caps hits=10000 globally). Saves board='amazon', department=<category>. The department drives the AWS-only / Fulfillment-only virtual pills.https://hiring.amazon.com/app/api/jobs/ (US), hiring.amazon.ca (CA). Spikes to 1000s at peak season.https://dspjobhub.com/vacancies-sitemap.xml — NOT Amazon employees (independent contractors) but a proxy for delivery demand.https://www.amazon.jobs/en/jobs/<id>.https://careers.wholefoodsmarket.com/api/v1/posts — ~2,761 retail/store. Detail enrichment intentionally skipped (too expensive nightly).https://www.onemedical.com/about/careers/jobs/ — ~283 healthcare/clinical, JSON-LD detail.https://careers.booking.com/api/jobs?count=100&offset=0https://careers.priceline.com/job-sitemap.xml; custom <p>/<li> extractor inside <article> (Priceline dropped JSON-LD May 2026).https://careers.deliveroo.co.uk/role-sitemap.xml (fetched via Bright Data — CF-challenged from datacenter IP); custom <p> extractor (JSON-LD now only @graph WebPage/BreadcrumbList).https://wolt.com/en/jobs?country=ALL — DoorDash's EMEA+APAC+LATAM markets, jobs in initial HTML.https://www.google.com/about/careers/applications/jobs/results/?page=<N> — server-rendered AF_initDataCallback({key:'ds:1', data:[...]}); 3-layer Oxylabs fallback (direct → rotating → sticky). Embedded totalHits in last array element.https://careers.withwaymo.com/sitemap.xml + JSON-LD detail. CloudFront WAF rejects Python TLS → curl_cffi impersonate=chrome120 + Bright Data fallback.https://www.metacareers.com/api/graphql/ with doc_id=29615178951461218 (rotates ~quarterly). Requires Accept-Encoding: br (brotli) or returns 400.https://www.metacareers.com/profile/job_details/<jid> — JSON-LD JobPosting (description) + public_compensation regex (salary). Both off one fetch.https://www.lifeattinder.com/sitemap.xml + JSON-LD detail.https://api.lifeatspotify.com/wp-json/animal/v1/job/search (no description) + __NEXT_DATA__ detail at props.pageProps.job.content.descriptionHtml.jobs.uber.com/api/jobs/search/?page=N&pagesize=100 — first-party JSON (title/teams/locations/salary/DisplayDate/description HTML; pagesize honoured to 100 → 6 calls) fetched via Bright Data Web Unlocker because Cloudflare challenges direct + Oxylabs; /en/jobs/sitemap.xml is unchallenged and supplies the authoritative req_id set. The old www.uber.com/api/loadSearchJobsResults RPC was removed ~Aug 2026. Corp only (drivers not captured).umusicus.wd1, umusicuk.wd1, umusicapac.wd1.https://vividseats.applytojob.com/apply (Greenhouse-style).https://www.wayfair.com/a/careers/careers/job_search_data has descriptions inline.api.lever.co/v0/postings/wattpad/<uuid>; Korean subs (NAVER, STUDIO_LICO) via RSC self.__next_f.push([1, "…"]) payload (pick the push with the most HTML tags).| Tool | Purpose | Cost |
|---|---|---|
httpx | Default HTTP client for most scrapers | Free |
curl_cffi (chrome120) | Spoof Chrome TLS fingerprint when CDNs reject Python TLS (Waymo, Deliveroo) | Free |
| Bright Data Web Unlocker | Anti-bot static pages (Deliveroo CF sitemap, EBAY sitemap discovery) | $0.0015/req |
| Bright Data Scraping Browser | PerimeterX/Akamai — real Chrome session (Wayfair only) | $0.008/req |
| Oxylabs Residential | Per-page proxy fallback for rate-limited APIs (Phenom, Google layer-2/3) | $7/GB |
brotli | Required for Meta GraphQL (refuses without Accept-Encoding: br) | Free |
| Playwright | Originally GOOGL/META; now only W. Connects to BD Scraping Browser over CDP. | Free |
Typical nightly cost: <$0.10 Bright Data + ~$5/mo Oxylabs. Worst case if multiple CDNs degrade: ~$2.50/night (capped by BD_MAX_CALLS_PER_RUN=1500).
storage._dedup)Key is (ticker, req_id); first occurrence wins. Collapses the same req appearing under multiple board values (Amazon category shards, TTWO sibling boards, Rippling cross-listed UUIDs).
def _dedup(postings):
seen = set(); out = []
for p in postings:
key = (p.ticker, p.req_id)
if key in seen: continue
seen.add(key); out.append(p)
return out
storage.record_run)DELETE is scoped to (run_date, ticker, ats, board IN <boards-in-result>) — so multiple yaml entries sharing (ticker, ats) but different boards (CVNA carvana+adesa, BKNG agoda+opentable, AMZN's 8 boards) don't wipe each other.
AMZN's "AWS only" and "Fulfillment only" pills are post-hoc department filters on the same Amazon rows — NOT separate scrapes:
department='aws' (~7,196)department IN (fulfillment-and-operations, fulfillment-ops, fulfillment-ops-team, transportation-and-logistics, transportation-shipping-logistics)Each virtual leaf carries virtual:True so the "All" total excludes them — else AMZN would double-count by ~11,600. (This was the 37,825-vs-26,163 bug.)
Keyed by yaml disambiguator (board/tenant/company/org), not (ticker, ats) — avoids false "95% drop" when one of CVNA's two greenhouse boards reports its smaller count alone. Also now consults the runs table + re-runs after extended retries so transient Workday flake (ETSY/SNAP/UMG/Z) doesn't false-alarm.
Descriptions stored with literal garbage. Google's AF_initDataCallback serializes HTML with JSON unicode escapes; normalize_description's tag regex never saw a real <. fix _js_unescape() before normalize, then strip leading/trailing JSON-array wrappers. watch spot-check last 80 chars of a GOOGL desc — should be real text, not "],2],.
Title parser missed orgs in trailing parentheticals, comma-less titles, and orgs not in KNOWN_ORGS. fix strip (English, Japanese) suffixes, expand KNOWN_ORGS to 60+ orgs, mine "About the team" paragraph as fallback, preserve acronym casing (AI not Ai). watch top depts should be Google Cloud / Data Center / GCS / YouTube / DeepMind.
Listing GraphQL returns only 5 fields. fix parse JSON-LD JobPosting off the Pass-2 detail HTML we already fetch for comp (no extra requests). watch doc_id rotates ~quarterly; 0/N enriched in logs → re-capture HAR.
CloudFront WAF profiles the TLS handshake (JA3/JA4), not just headers → 202/405. fix curl_cffi.Session(impersonate="chrome120") as the direct client (free, ~95%); Bright Data Web Unlocker sequential fallback for stragglers. Went 9/410 → 410/410.
Returned 390 Role-#N stubs. curl_cffi AND BD Web Unlocker both fail. fix BD Scraping Browser (real Chrome + residential IP); the backing XHR has descriptions inline. 0 → 377 real jobs at $0.24/mo.
Phenom's ?from=N&s=1 shuffles results so duplicates fill page slots; ~78 jobs unreachable. fix use the SEO sitemap (sitemap1.xml 500 + sitemap2.xml 77 = 576). Lightsail fetches sitemaps directly; only the search API was IP-blocked.
JobPosting JSON-LD replaced by @graph with only WebPage/BreadcrumbList; helper silently returned blanks. Plus CF challenged the sitemap from datacenter IP. fix sitemap via BD, custom <p> extractor, concurrency 8→4 (CF burst limit).
Concatenated description + description_short both led with "Transform the future…" marketing, repeated across 100x-reposted reqs. fix restructure to basic_qualifications → responsibilities (marker-split) → preferred_qualifications; smart-excerpt at export time anchors on "Key job responsibilities" markers.
Anomaly check fired before extended retries recovered transient Workday flake. fix consult the runs table (ok-run = not missing) and re-run after extended retries.
All-total summed virtual leaves (AWS + Fulfillment) on top of the Amazon rows they filter → 37,825 vs real 26,163. fix exclude virtual:True leaves from the sum.
A regen after 00:00 UTC creates a scrape_exports/<tomorrow>/ dir; web server routes / there showing partial data. watch when backfilling near midnight UTC (19:00-20:00 ET), remove the rogue dir + restamp rows.
OXYLABS_USER="..." with literal quotes → %22 in proxy URL → httpx InvalidURL. fix proxy.py strips surrounding quotes universally. watch don't quote env-var values.
comp pass: 0/N enriched → re-capture HAR.<company>.workdayjobs.com for the new redirect.<sitemapindex>, but if the root URL moves, update yaml.Minimum viable (~95% of dollar value, zero external cost): Greenhouse + Workday + Lever scrapers cover 32 of 35 tickers (~3 files, ~600 lines). Add Amazon corp (biggest single source) + Google Careers (regex on AF_initDataCallback). One $40/mo Lightsail box, SQLite, Cloudflare DNS, Let's Encrypt.
Don't repeat these mistakes:
playwright + Oxylabs proxy= — Chromium hits ERR_TUNNEL_CONNECTION_FAILED. Use httpx proxy=.(run_date, ticker, ats) when entries share that but differ on board.Full version with every URL and code snippet lives in REPLICATION_GUIDE.md in the project repo. ↑ back to top