How this data is built
This is a plain-language walkthrough of the definitions behind every KPI, chart, and entity page on Proletaria. It follows the same definitions as the public API contract; where a number can’t be honestly computed it is null or a COLLECTING state, never a placeholder.
Universe and employer selection
The tracked universe is a curated registry of employers, one record per company, reviewed before onboarding. An employer enters coverage once its careers site or ATS has been verified to detect real postings; it is not a scrape of every job board on the internet, and it is not exhaustive of the labor market.
What a posting is
A posting is one job listing observed on an employer’s own careers site or ATS, identified by a stable listing URL. The same role reposted under a new URL is treated as a new posting; Proletaria does not attempt to de-duplicate reposts across URLs.
Active, new, and removed
A posting’s effective post date is coalesce(posted_at, first_seen) — the employer’s own stated date when it publishes one, falling back to the date Proletaria first observed the listing. A posting counts as new on the day its effective post date falls, and as removed on the first daily diff that no longer finds it live (the closed-day rule) — not the day it was last seen, which can lag the employer’s actual removal by up to one scrape cycle. Active is simply: seen in the most recent completed diff.
Pay parsing and midpoint
Pay ranges are parsed only from what the employer discloses on the posting itself — never inferred from title, level, or location. Where a range is disclosed, the midpoint of min and max is what feeds pay medians and comparisons; a single disclosed figure is used as-is. Undisclosed pay is null, not zero or an average.
Work mode
Work mode (remote / hybrid / onsite) is read from the employer’s own posting language and location metadata. A posting with no work-mode signal is left null rather than defaulted to onsite.
Seniority rule
Seniority is extracted from title and description text where it is stated. Where a posting states no seniority signal at all, it is defaulted to mid-level rather than left null — this is a deliberate simplification, and it means the mid-level bucket is inflated by every posting that simply didn’t say. Treat senior/staff/principal and intern/junior counts as the more reliable signal; treat mid-level as “stated mid, or unstated.”
Skill extraction and vocabulary governance
Skills are extracted from posting text against a controlled vocabulary defined in this project’s skills registry, not free-text tags. Deterministic equivalences (case, punctuation, plurals) are normalized in code; semantic equivalences (for example, “data analytics” folding into “data analysis”) are reviewed aliases, never assigned by a similarity score. A name the vocabulary doesn’t yet recognize is admitted as proposed — it stays attached to the listing, but does not appear in the public skill index until reviewed. A merged skill slug leaves a redirect, so a skill URL you’ve linked to never silently breaks.
Scrape gates and quarantine
Every daily scrape passes through validation gates before it is allowed to affect an employer’s posting counts. A scrape that fails validation — too few postings relative to recent history, a fetch error, a change in page structure the parser doesn’t recognize — is quarantined: that employer is excluded from that day’s diff entirely, rather than having its real postings marked “removed” by a bad read. Quarantine over deletion, always.
Disclosure and suppression floors
Aggregates are suppressed below a minimum sample so a single employer or a thin slice of data can’t be read back out of a summary statistic:
- A pay median requires at least 30 priced listings and at least 10% pay disclosure in that slice; below either floor the median is
null. - A skill co-occurrence pair requires at least 10 listings carrying both skills (
pair_count ≥ 10); thinner pairs are omitted rather than shown with noisy confidence. - Time-to-fill is a right-censored median computed over closed postings only, and is suppressed while the platform has under 90 days of history — a young employer’s time-to-fill is not yet a stable number.
- Trending and mover rankings require a baseline population — 50 listings for a skill, 20 for a title group — below which a swing is too small a base to call a trend.
Known limits
- Employer onboarding has been ramping since 2026-08-12; earlier history is thinner for employers added since, and coverage widens over time rather than starting complete.
- Time-to-fill is right-censored: a posting still open at the end of the observed window hasn’t “filled” yet by definition, so medians understate the true time-to-fill for slow-to-close roles.
- A meaningful share of active listings carry no mappable geography (remote-only language, or a location the metro model doesn’t resolve); location-based views describe the listings that do map, not the whole active set. The metro map itself shows its own mapped-vs-unmapped split live.
- Coverage mixes US and non-US employers and postings; regional comparisons should account for that mix rather than assume a single labor market.
Current coverage counts (companies tracked, active listings, days of history) are not repeated here as static numbers — see the live counters on the overview page or /api/meta, which is the single source of truth for them and updates daily.
See also the data & API page for the public API and its data-use terms, and about for who builds this and how to request a correction.