Turning `$140k – $180k • 0.1% – 0.4%` into six columns
Compensation on Wellfound is a display string. What it takes to split it into minimum, maximum, currency, period and an equity range — and why the original string still ships.
Wellfound publishes compensation as a single display string such as `$140k – $180k • 0.1% – 0.4%`, which is unusable for filtering or aggregation. This Actor parses it into `salary_min`, `salary_max`, `salary_currency` and `salary_period`, filled on 86.7% of enriched rows, plus `equity_min_pct` and `equity_max_pct`, and keeps the original in `compensation_raw`, present on 79.5% of rows overall with a category minimum of 60.3%. Keeping the raw string is what makes the parse checkable rather than something you have to trust.
Key points
`compensation_raw` is present on 79.5% of rows overall, with the lowest category at 60.3% — so roughly a fifth of postings state no compensation at all.
Where a string exists, the parse fills `salary_min` and `salary_max` on 86.7% of enriched rows.
Equity is parsed into a percentage range, because `0.1% – 0.4%` sorts and filters as text and not as a number.
The raw string always ships alongside the parsed values, so a suspicious row can be checked against what the site actually said.
The salary rates are of enriched rows, so they depend on `enrichFromJobPage` being on — which it is by default.
Compensation is the field most people come for and the field most likely to arrive unusable. Here is what happens to it.
What the source publishes
compensation_raw
"$140k – $180k • 0.1% – 0.4%"
One string, two ranges, a currency symbol, an abbreviation and a bullet. It renders well and it cannot be filtered, sorted, averaged or compared.
The six columns it becomes
Field
From the example above
salary_min
Value140000
salary_max
Value180000
salary_currency
ValueUSD
salary_period
Valueyear
equity_min_pct
Value0.1
equity_max_pct
Value0.4
equity_offered is the boolean alongside them, so a posting that mentions equity without a range is still distinguishable from one that mentions none.
How often each one is actually filled
compensation_raw is present on 79.5% of rows overall, and the lowest role category measured was 60.3% — so roughly one posting in five states no compensation at all, and in some categories two in five. Where a string exists, minimum and maximum parse out on 86.7% of enriched rows.
Why the raw string still ships
Because a parse is a derivation, and derivations fail quietly — a currency symbol nobody anticipated, a range written with a hyphen instead of an en dash, a monthly figure that looks annual. Keeping the original next to the result is what lets a suspicious row be checked instead of trusted. It is the same reasoning behind shipping both the rounded and the exact subscriber count.
The field people forget: period
salary_period is the field that makes the numbers comparable. A range that turns out to be monthly, mixed into an annual average, moves the average and nothing announces it. Always group by period before aggregating.
Frequently asked questions
▸How many Wellfound postings state a salary?
About four in five: `compensation_raw` is present on 79.5% of rows overall, and the lowest role category measured was 60.3%. Where a string exists, min and max parse out on 86.7% of enriched rows.
▸Is equity parsed too?
Yes, into `equity_min_pct` and `equity_max_pct`, with `equity_offered` as the boolean. A range written as text cannot be filtered or averaged, which is the whole reason to parse it.
▸Why keep `compensation_raw` if it is parsed?
Because a parse is a derivation and derivations go wrong quietly. Keeping the original next to the result is what lets somebody check a row that looks odd instead of having to trust the parser.
▸Do I need enrichment for salary?
For the structured fields, yes — the 86.7% figure is of enriched rows. `enrichFromJobPage` is on by default and costs one extra request per job. The raw compensation string and the full description come without it.
Sources
Every URL below was requested and returned a page on the date shown.
All 58 fields grouped by what they describe, with the rate each was filled on across 2,229 jobs — and the three that are published as ranges rather than averages.
A walkthrough of extracting startup job listings: how Wellfound's URL-path filtering constrains what you can ask for, which caps actually bound a run, and what arrives in each row.
There is no documented public endpoint for startup job listings. What robots.txt permits, what Cloudflare sits in front of, and which surface is actually readable.