Hacker News Who is Hiring Scraper: Jobs, Emails & Salary avatar

Hacker News Who is Hiring Scraper: Jobs, Emails & Salary

Pricing

from $4.00 / 1,000 job posts

Go to Apify Store
Hacker News Who is Hiring Scraper: Jobs, Emails & Salary

Hacker News Who is Hiring Scraper: Jobs, Emails & Salary

Scrape Hacker News "Who is hiring?" threads into clean rows: company, domain, roles, tech stack, remote, Latin America eligibility, salary, visa, contact emails and apply links. One row per post or per company. Optional email pattern with MX check.

Pricing

from $4.00 / 1,000 job posts

Rating

0.0

(0)

Developer

Oswaldo Carabano

Oswaldo Carabano

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

22 days ago

Last modified

Share

Hacker News Who is Hiring Scraper: Jobs, Emails, Salary & LATAM

Turn the monthly Hacker News "Ask HN: Who is hiring?" thread into clean rows you can export to CSV, JSON or Excel: an HN jobs API alternative with no API key, no login and no browser. Every company post becomes one row with the company, its domain, the roles, the tech stack, remote or on-site, where remote hires can be, Latin America eligibility, the salary range and currency, visa sponsorship, contact emails and apply links, plus the full text. Optionally, get the company email pattern (for example first.last@) with its mail servers checked by DNS.

Or switch Output to companies and get one row per hiring company instead: every post the company made in the months you choose, merged into one deduplicated row (months it hired, all roles, stack, salary range, contact emails, apply links).

  • Every month since April 2011: 184 monthly hiring threads, about 93,700 company posts in total.
  • Parsed, not just copied: salary as numbers with currency and period, remote regions, LATAM eligibility with its evidence, de-obfuscated emails (name [at] company [dot] com).
  • Built for job seekers writing directly to companies, recruiters mapping who is hiring, and anyone tracking startup hiring and pay.
  • Posts or companies: one row per post, or one row per company with all its posts aggregated (outputType).
  • $0.004 per post, or $0.01 per company. You never pay for an error row or a duplicate.

What people use it for

If you are…You get
A developer looking for a remote jobposts that are remote, where remote hires can be, time zones, salary and the apply link
A developer in Latin AmericalatamOnly: posts with a positive signal that LATAM candidates can apply, and the evidence for each one
Writing to the hiring team directlythe company domain, its published contact emails, and the email pattern of the domain with MX records
Researching startup salariessalary min / max / currency / period for every band a post lists, equity, seniority
Tracking who is hiring month by monthcompany, domain, Y Combinator batch, funding stage and roles across any months since 2011
Building an outreach list of hiring companiesoutputType: companies: one deduplicated row per company, with the months it hired and how many posts it made
Building a job board or newsletterstructured rows plus the original text and HTML of every post

What actually arrives in a row

A post row has 64 fields. The rates below were measured on 1 Oct 2026 over the four latest monthly threads (July to October 2026, n = 848 company posts). We do not promise a field we have not measured.

Always there (100%)

postId · postUrl · storyTitle · month · threadType · author · postedAt · headerLine · rawText · rawHtml · scrapedAt

Parsed from the post

FieldFilledWhat it is
company91%from the first line, "Company: …" or "At X we are hiring"
domain80.8%company domain, from its website, a careers subdomain or a corporate email
companyUrl70%first link that is not a job board, social network or document
roles76%role titles from the first line, role lists and bullets
employmentTypes70%full-time, part-time, contract, internship
applyUrls67%ATS pages (Greenhouse, Lever, Ashby, Workable…) and careers pages
stack63%111 technologies recognised (Python, TypeScript, React, PostgreSQL, Rust, Kubernetes, LLMs…)
locations61%offices or allowed places, e.g. San Francisco, CA, London, UK
roleCategories55%backend, frontend, fullstack, mobile, data, ml-ai, devops-sre, security…
remote53.8% trueremote work offered
seniority45%intern, junior, senior, staff, principal, lead, founding, director…
salaryMin / salaryMax37%first salary range, as numbers, with salaryCurrency and salaryPeriod
remoteRegions34%worldwide, americas, latam, us, canada, europe, uk, emea, apac…
contactEmails28.8%contact emails, de-obfuscated (corporate and role addresses)
equity25%equity or stock options mentioned
fundingStage16.5%seed, series a…, bootstrapped, profitable
visaSponsorship8.7%stated in 8.7%: true (offers sponsorship) 3.5%, false (requires existing work authorization) 5.2%
timezones6.4%UTC-3, EST, "US time zones"…
ycBatch3.9%Y Combinator batch, e.g. S26

Salary currencies measured: USD 252, EUR 19, GBP 4, CAD 4, PLN 3, AUD 1, CHF 1 (of 284 posts with a currency). When a post lists several bands or currencies, all of them are in salaries.

Latin America eligibility

latamEligible answers "can someone in Latin America apply?" and latamSignals says why:

ValueMeaningShare (n = 848)
trueLATAM or a Latin American country or city in the location, or remote worldwide / Americas (mention:Brazil, remote:worldwide…)7.1%
falseremote restricted to other regions (remote-restricted:us), or an office outside Latin America65.9%
nullthe post does not say27.0%

Company email pattern (optional add-on)

With inferEmailPattern, each company domain gets an emailPattern object: pattern (e.g. first.last), confidence (0–0.99), evidence (the addresses it was learned from), alternatives, mxValid, mxHosts, emailProvider and catchAll. Measured on 480 domains: MX valid 95.6%, Google Workspace 71.7%, Microsoft 365 12.3%.

Most posts publish a role address (jobs@) rather than a personal one, so a pattern backed by observed addresses is rare: 4 of 480 domains (0.8%) in the sample above, 15 of 1,510 over the last 12 months. You are charged only for those. For every other domain you still get the MX records and provider and a best guess marked inferred: true, free.

No email is ever sent and no mail server is probed (no SMTP): catchAll is always null.


One row per company (outputType: companies)

Set Output to companies and every company becomes one row that merges all its posts in the months and filters you chose. Companies are grouped by domain (companyKey: "acme.com"); a company whose posts never give a domain is grouped by its normalized name (companyKey: "name:acme"), and a name-only post joins the domain group when that name appears with exactly one domain in the range. Filters apply to the posts before grouping, so remoteOnly gives you companies with remote posts, built from those posts only. Rows come newest hiring first, and maxItems counts companies.

What a company row adds: monthsHiring, monthsCount, postCount, firstPostedAt, lastPostedAt, lastPostUrl, lastHeaderLine, lastPostText, postIds / postUrls, authors, companyNames, remotePosts, latamEligiblePosts and locationPolicies, plus the post fields aggregated: roles, stack, locations, countries, remote regions, remote and latamEligible (true when any post says so), salary range (lowest and highest bound of the most common currency and period, never mixing currencies), every salary band with its month, contact emails, apply links, ATS, funding stage, YC batch and the email pattern.

Measured on 2 Oct 2026 over the last 12 monthly threads (November 2025 to October 2026, n = 1,822 companies from 3,475 posts):

FieldFilled
grouped by domain84.0%
company95.1%
roles81.5%
stack69.0%
applyUrls64.7%
remote true56.3%
contactEmails38.3%
atsProviders34.6%
salary range34.2%
fundingStage18.4%
latamEligible true6.1%
ycBatch3.4%

34.6% of those companies posted more than once in the 12 months, and 18.7% in three months or more (up to 12 posts; 1.91 posts per company on average). The "Who wants to be hired?" thread is not read in this mode: job seekers are not companies.


Privacy

  • Corporate and role addresses posted by a company are delivered as published.
  • Personal-domain addresses (gmail, outlook, yahoo, proton, icloud…) are removed from contactEmails and hidden in rawText and rawHtml unless you enable includePersonalEmails. In the measured sample, 19 of 269 addresses in company posts were on personal domains.
  • "Who wants to be hired?" posts are individuals, and so are the "SEEKING WORK" posts of the Freelancer thread. Both threads are off by default; when you add one, every email, phone number and CV link of those posts (including links to a CV document) is hidden unless you also enable includePersonalEmails. Turn it on only if you have a lawful basis to process that data.
  • The Hacker News username of the author is delivered, as shown on the site.

Input examples

The latest month, everything (what the daily test runs):

{}

Remote engineering posts of September 2026 with the email pattern:

{
"months": ["2026-09"],
"roleKeywords": ["engineer"],
"remoteOnly": true,
"inferEmailPattern": true,
"maxItems": 50
}

Every company that hired in the last six months, one row each:

{
"outputType": "companies",
"months": ["latest", "latest-1", "latest-2", "latest-3", "latest-4", "latest-5"],
"maxItems": 500
}

Three months of posts open to Latin America, for a scheduled run:

{
"months": ["latest", "latest-1", "latest-2"],
"latamOnly": true,
"stack": ["TypeScript", "Python"]
}

months accepts 2026-10, October 2026, latest and latest-N. All filters are applied to the parsed rows, so they filter exactly what you see.


Output example

One row, shortened (rawText and rawHtml cut; addresses replaced by examples):

{
"rowType": "post",
"postId": "49613617",
"postUrl": "https://news.ycombinator.com/item?id=49613617",
"storyTitle": "Ask HN: Who is hiring? (September 2026)",
"threadType": "hiring",
"postIntent": "hiring",
"month": "2026-09",
"author": "hn_user",
"postedAt": "2026-09-01T16:03:11Z",
"headerLine": "Search Atlas | Product Engineer | REMOTE (anywhere, EST hours) | Full-time contractor | $23-$34 USD/hour | https://careers.searchatlas.com/jobs/599248-pro",
"company": "Search Atlas",
"companyUrl": "https://careers.searchatlas.com/jobs/599248-product-engineer-pm",
"domain": "searchatlas.com",
"roles": ["Product Engineer (Product Manager role, not a Full-stack role)"],
"employmentTypes": ["full-time", "contract"],
"stack": ["TypeScript", "Python", "React", "Django", "LLMs"],
"remote": true,
"locationPolicy": "remote",
"remoteRegions": ["worldwide"],
"latamEligible": true,
"latamSignals": ["remote:worldwide"],
"timezones": ["EST", "EST hours"],
"salaryMin": 23,
"salaryMax": 34,
"salaryCurrency": "USD",
"salaryPeriod": "hour",
"visaSponsorship": null,
"contactEmails": ["first.last@example.com"],
"contactEmailsDetail": [{ "email": "first.last@example.com", "type": "named", "domain": "example.com", "obfuscated": false }],
"personalEmailsHidden": 0,
"applyUrls": ["https://careers.searchatlas.com/jobs/599248-product-engineer-pm"],
"emailPattern": {
"pattern": "first.last",
"confidence": 0.5,
"inferred": false,
"evidenceCount": 1,
"mxValid": true,
"mxHosts": ["aspmx.l.google.com"],
"emailProvider": "Google Workspace",
"catchAll": null,
"charged": true
},
"rawText": "Search Atlas | Product Engineer | REMOTE (anywhere, EST hours) | …",
"scrapedAt": "2026-10-01T23:40:12.511Z"
}

One company row, shortened (lists cut; the address replaced by an example):

{
"rowType": "company",
"companyKey": "albert.com",
"company": "ALBERT",
"domain": "albert.com",
"monthsHiring": ["2026-09", "2026-08", "2026-07", "2026-06"],
"monthsCount": 4,
"postCount": 4,
"firstPostedAt": "2026-06-03T00:08:25Z",
"lastPostedAt": "2026-09-08T19:19:18Z",
"lastPostUrl": "https://news.ycombinator.com/item?id=49615435",
"lastHeaderLine": "ALBERT | REMOTE ALMOST ANYWHERE IN THE WORLD| Hiring principal and distinguished engineers to build net new products | up to ~ $750k",
"postIds": ["49615435", "49172196", "48751913", "48377948"],
"seniority": ["principal"],
"stack": ["JavaScript", "Python", "React", "React Native", "PostgreSQL"],
"remote": true,
"remotePosts": 4,
"remoteRegions": ["worldwide"],
"latamEligible": true,
"latamEligiblePosts": 4,
"latamSignals": ["remote:worldwide"],
"salaryMin": 750000,
"salaryMax": 750000,
"salaryCurrency": "USD",
"salaryPeriod": "year",
"salaries": [{ "min": null, "max": 750000, "currency": "USD", "period": "year", "raw": "$750k", "month": "2026-09", "postId": "49615435" }],
"equity": true,
"contactEmails": ["recruiting@example.com"],
"fundingStage": "profitable",
"emailPattern": { "pattern": "first.last", "confidence": 0.1, "inferred": true, "mxValid": true, "emailProvider": "Google Workspace", "catchAll": null, "charged": false },
"lastPostText": "ALBERT | REMOTE ALMOST ANYWHERE IN THE WORLD| Hiring principal and distinguished…"
}

Pricing

Pay per event:

EventPrice
Post (one row, outputType: posts)$0.004 ($4 per 1,000 posts)
Hiring company (one row, outputType: companies)$0.01 ($10 per 1,000 companies)
Company email pattern (once per domain per run, only when backed by observed addresses)$0.01
Actor start$0.00001

Error rows are never charged, and a post or a company is never charged twice in the same run. When your maximum cost per run is reached, the run stops cleanly.

What real runs cost (measured on the Apify platform, 2 Oct 2026, 512 MB)

InputResultTimeYou pay
{} (latest month, 100 posts)100 posts5 s$0.40
September 2026, engineer, remote only, email pattern, 5050 posts + 1 email pattern6 s$0.21
Latest 3 months, latamOnly, email pattern43 posts6 s$0.17
outputType: companies (latest month, 100)100 companies4 s$1.00
outputType: companies, latest 2 months, email pattern, 150150 companies + 3 email patterns7 s$1.53
outputType: companies, latest 12 months, 100100 companies (3,483 posts merged)55 s$1.00
Maximum cost per run $0.50, 300 posts asked124 posts, then a clean stop4 s$0.50
A month in the future (2031-01)1 error row explaining why1 s$0.00

Set Max items to control the cost: you pay for the rows you get, nothing for the time the run takes.


How it compares (measured on 1 Oct 2026)

We read the output schemas of the 10 Hacker News "Who is hiring" actors in the Apify Store. The richest declares 25 fields. None of them delivers the company domain, salary as numbers, Latin America eligibility, an email pattern or MX records.


FAQ

Where does the data come from? From the public Hacker News search API, the same one the Hacker News search page uses. No login, no cookies, no browser, no API key.

Can I export Hacker News jobs to CSV or Excel? Yes. Every run is an Apify dataset: download it as CSV, JSON, Excel, XML or HTML, or read it through the Apify API. The dataset has ready views (overview, outreach, LATAM, compensation, companies).

Can I run it every month? Yes: schedule the actor (or a saved task) with months: ["latest"] and send each dataset to Google Sheets, Slack, Zapier or a webhook with Apify integrations. Each row has postId and postedAt to keep only the new ones.

How fast is it? On the Apify platform (2 Oct 2026, 512 MB): 100 posts in 5 seconds, 300 posts from two months in 6 seconds, and 12 months merged into companies in 55 seconds, with a memory peak of 102 MB. In local tests: 9,040 posts (12 months of both threads) in 42 seconds. Companies: 1,822 companies from 12 months in 23 seconds; the whole archive (184 threads, 90,427 posts, 24,169 companies) in 3 min 19 s within 512 MB of memory (measured on 2 Oct 2026).

Posts or companies? Posts when you want every job ad (one company can post every month). Companies when you want a deduplicated list of who is hiring, with how often and for what.

Which months exist? Monthly hiring threads exist from April 2011. The "Freelancer? Seeking freelancer?" thread was last posted in October 2025, so recent months have none; the run tells you when a requested thread does not exist.

The current month has few posts. The thread opens on the first weekday of the month and grows for days: on 1 Oct 2026 it had about 100 posts, while September 2026 ended with 254.

Why is a field empty? Posts are free text and many do not state a salary, a stack or a location. Every field is always present, with null when the post does not say.

Does it send emails or verify mailboxes? No. It only reads published posts and checks MX records by DNS.

Can I get the replies? Rows are top-level posts (the job posts). replyCount says how many direct replies each one has, and replyIds lists their Hacker News IDs.