TradeOnRamp
TradeOnRamp

The way into HVAC, electrical and plumbing.

Methodology

Every fact row has a source_url, a verified_on date and a verification status the page prints verbatim. A page whose newest verification is older than 120 days shows a stale banner automatically. The changelog is append-only. Exports are regenerated on every request. No school, sponsor or employer is ranked by what it pays us.

The three honesty labels

LabelMeaningHow a row earns it
board-verifiedEvery cell confirmed against the source URLAgent A extracts a row with a verbatim quote; Agent B re-opens the URL and confirms each cell before published=true
board-page-seenThe source page was fetched and its structure/quotes confirmed; figures came from researchUsed when a board's hub page was captured but the per-tier subpages were not yet re-read (Texas TDLR in this build)
research-seededFrom the published research reports; not yet verified liveDefault for every row until the two-agent verification runs

Sources, cadence, normalization

SourceWhatCadenceRule
State board pages (8 states × 3 trades)License tiers, hours, exams, fees, renewal, CE, reciprocity6-hour hash check; re-normalize on diff; quarterly full re-verifyTwo-agent rule; per-row quote; changelog entry on any change
State statutes / handyman thresholds (12 states)Dollar threshold, exemptionsQuarterly + heartbeat hashSame two-agent rule
apprenticeship.gov Partner Finder / Job FinderSponsors (self-listed subset), open apprenticeship jobsWeekly (sponsors), 6-hour (jobs)Headless render → structured; never claim completeness
ETA Inside locator, UA locals, IEC/ABC/PHCC chapters, colleges, then each sponsor siteApplication windows, prerequisites, test dates, pay scheduleWeekly; 6-hour during a known windowNull over inferred — 'not published — call' when unknown
IPEDS C2023_APrograms × CIP × completionsAnnualFilter CIP 47.0201 / 46.0302 / 46.0503; join to institutions
EPA Section 608 certifier list~100 organizationsMonthlyTag modality (online / on-site / mail)
BLS OEWS (API v2)Metro / state / national percentiles + employment, May vintageAnnual on releaseSOC sanity (49-9021 is HVAC, not 49-2021); reject metro medians > 2× national; honour suppressed cells; O*NET mirror fills gaps and is labeled
Union CBA PDFsApprentice % of journeyman by periodPer contract; heartbeat hashPage-cited extraction; trade-level typical schedule until each local is read
Employer career pages (12 ATS adapters)Listings, employer-stated pay, credentials, sign-on bonus6-hour heartbeatQuote the requisition, null over inferred; dedupe; 2-miss expire → 14 days → HTTP 410; datePosted never reset; estimates never in JobPosting.baseSalary

This build's state

DatasetRowsProvenance right now
License requirements453Texas electrical + HVAC: tier structure verified against TDLR (2026-08-28); all other rows research-seeded
Apprenticeship sponsors321Research-seeded organization records across 15 metros; windows/test dates null pending the sponsor-site scrape
Training programs79Derived from college sponsors; IPEDS completions join pending
BLS OEWS cells420150 live BLS API cells (HVAC complete) + 220 O*NET-mirror cells of the same May-2025 vintage (electricians, plumbers); Las Vegas/Nashville electrician & plumber cells pending
Active listings0Not live yet — the listings crawl has not run; nothing listing-shaped is shown or indexed until it does

Last verification run: Sep 7, 2026 (research-folder, 497 rows checked, 913 changed). Last crawl runs: .

Pay-page rules

  • BLS OEWS is the anchor and is annual; it is never restated as a monthly number.
  • Employer-stated posting pay is shown with n, window and date, as offers — never as a wage estimate.
  • Third-party figures (Indeed, ZipRecruiter, Glassdoor, Salary.com, Talent.com) are reconciled on the page with their basis; the spread is 5–20%, not 30–45%.
  • The owner rung is a model built on The Job Numbers' hourly-rate and labor-burden calculators, labeled gross/pre-tax, and never presented as a survey figure.
  • Structured data: Occupation + estimatedSalary + FAQPage + Dataset on pay pages; JobPosting on job detail pages only, baseSalary only when employer-stated.

Download the datasets · Changelog · Disclosure