How the data is built.
Every number on FedRange traces to a specific contract action in the public record. The methodology below describes what we pull, how we clean it, what we exclude, and what you should be skeptical about. The goal is not to dazzle; the goal is to be auditable. The founding cohort is focused on 561720 Janitorial Services — the methodology applies broadly to any service NAICS, but the pricing intelligence, proposal drafter, recompete radar, and SCA wage floor are tuned for janitorial today.
What FedRange does, in one sentence.
FedRange ingests federal contract award records from USASpending.gov, joins them against active solicitations from SAM.gov, and exposes the resulting comparable-price distributions to small federal janitorial contractors (NAICS 561720) who otherwise price their bids by gut feel.
Where the data comes from.
Two public endpoints are the entire source layer. We do not buy third-party data; we do not scrape paywalled aggregators. The provenance is intentionally narrow so the lineage is checkable end to end.
- USASpending.gov · api.usaspending.gov/api/v2/search/spending_by_award/Procurement contract awards (types A/B/C/D). Recipient name, UEI, award amount, awarding agency, NAICS code, place of performance.
- SAM.gov · api.sam.gov/opportunities/v2/searchActive solicitations + entity registration data (the "who is eligible to bid" layer). Free API key, 1,000 req/day cap.
How percentiles are computed.
For a given NAICS code we collect every award with a non-null, positive award_amount whose performance period starts within the last 24 months. We compute P10, P25, P50 (median), P75, and P90 using Postgres' percentile_cont aggregate — which is the linear-interpolation variant matching numpy.percentile defaults. Sample size is reported on every card; bands derived from samples under 50 awards should be read as directional, not authoritative.
We compute percentiles on award totals as published, not on amount per unit of work. A $1M five-year janitorial contract and a $1M one-year janitorial contract land in the same distribution. This is a known limitation we accept because the public record does not consistently expose unit-of-work normalisation across agencies.
You can preview the percentile band for any supported NAICS without signing up — see for example /slice/561720. The slice page renders the live P10–P90 band and the top 10 comparable awards, drawn from the same percentile_cont computation described here.
How we read the solicitation.
When a SAM.gov opportunity has attached documents — the RFQ or RFP itself, the PWS, the Q&A appendix — we download each attachment, extract the text with a server-side PDF parser (with OCR fallback for scanned pages), and split the result into Federal Acquisition Regulation parts. The three sections that drive the analyzer's output:
- Section L · Instructions to OfferorsPage count limits, font requirements, submission format, oral-presentation rules. We surface these so the draft sections respect the actual page budget rather than producing generic boilerplate.
- Section M · Evaluation FactorsThe criteria the contracting officer will actually score on — past performance weight, technical approach factors, price evaluation method. The single most under-read section of any federal solicitation; the analyzer prioritizes it.
- Section C / PWS / SOW · Statement of WorkWhat the government actually wants done — service levels, staffing, deliverables, periods of performance. Where the proposal draft anchors its Technical Approach and Management Approach sections.
Parsing is best-effort. Some solicitations don't use FAR section headers; for those the analyzer falls back to the full document text. When attachments are absent (a pre-solicitation, an RFI), the analyzer grounds on the synopsis description alone — clearly flagged as such in the output.
How the comp pool gets filtered.
NAICS alone is too coarse for many service categories. A janitorial NAICS pulls $19M fleet-supply contracts into the same bucket as a single-campus floor-care RFQ. To prevent that the analyzer narrows the pool by additional filters when the underlying opportunity carries them:
- Product / Service Code (PSC). The four-character code (e.g.
H342for QA / Inspection Services) that identifies the work-type more precisely than NAICS. When the opportunity carries a PSC the analyzer attempts to narrow the comp pool to same-PSC awards — falling back to the full NAICS pool when the same-PSC pool is too thin to anchor on. - Set-aside type. Small Business set-asides price differently than full-and-open. When the opportunity carries a non-open set-aside, the comp pool is narrowed to the same set-aside lineage (8(a), HUBZone, WOSB, SDVOSB all roll up to a small-business lens for prior-experience purposes).
- Place of performance (state). When the opportunity specifies a state, the band excludes out-of-state awards from the median calculation.
Appeals-Tier Dispute History (Court of Federal Claims).
When a bidder loses a federal contract on grounds they consider improper, the first stop is a GAO bid-protest filing. A subset of those decisions are appealed to the Court of Federal Claims (CFC), the Article-I court with jurisdiction over money claims against the United States. CFC opinions are precedential where GAO decisions are advisory — and the ones that get there are the litigated edge cases worth learning from.
FedRange ingests CFC opinions from govinfo.gov's USCOURTS collection. A regex classifier extracts the outcome (granted / denied / dismissed / partial / unknown) and the grounds invoked (price realism, technical evaluation, set-aside, OCI, latent ambiguity, past performance, etc.). The matched opinions for your NAICS + agency pair surface in the bid range card's Appeals-Tier Dispute History panel.
Scope limitation worth flagging: CFC sees only the fraction of GAO protests that escalate to federal court. The data over-represents larger contracts and litigated edge cases. When too few CFC opinions match a given NAICS + agency pair, the panel explicitly renders INSUFFICIENT DATA rather than a false-confident percentage.
What's excluded and why.
Non-competitive set-aside awards are excluded from every percentile band and the Top Winners table. Specifically: 8(a) Sole Source, SDVOSB Sole Source, HUBZone Sole Source, WOSB Sole Source, JWOD / AbilityOne (Javits-Wagner-O'Day Act) and any award flagged with the NIB / NISH legacy naming. These contracts are awarded without competition — the price reflects the agency's internal preference plus the vendor's pricing willingness, not what the open market would pay. Including them would list sole-source winners alongside firms that actually competed, which muddies the comp pool. The filter matches on the set_aside field with a case-insensitive regex of sole.source|jwod|javits.wagner|abilityone|nibs.
Competed set-asides (8(a) competitive, SDVOSB competitive, HUBZone competitive, WOSB competitive) are kept in the pool — those are still real bids against real competitors, just within a socioeconomic eligibility lane. Only the sole-source variants are stripped.
The proposal-drafter retrieval index intentionally does not apply this filter. Sole-source contracts still teach the drafter about real winning language even when they didn't compete — we just don't want their dollar values polluting the pricing band.
IDIQ ceiling values are surfaced separately from task-order obligations. The percentile chart uses obligation amounts (what was actually spent) rather than ceiling values (what the contract is theoretically worth) because pricing for a comparable task order is closer to obligation reality than to ceiling fiction.
Service Contract Act wage rates.
For Janitorial Services (NAICS 561720) — the active coverage today — the proposal drafter pulls the prevailing Service Contract Act (McNamara-O'Hara) wage determination for the customer's state and injects the floor rates directly into the pricing narrative. Pricing language that quotes loaded labor rates below the SCA floor gets flagged before the draft is shown to you — losing on a price-realism challenge because your rate sheet is below the federal wage floor is one of the avoidable own-goals we engineered out. (Roadmap: NEMT / paratransit 485991, courier 492110, home health 621610 reactivate as the founding janitorial cohort fills.)
The wage tables are seeded from the SAM.gov Wage Determinations Online (WDOL) collection and refreshed when DOL publishes a new determination for the relevant SCA conformance. Active coverage is Janitorial Services (561720) today; expansion to the other three service NAICS is on the roadmap as the founding cohort fills.
Predictive recompete radar.
Every contract has a period of performance. Slightly before that period ends, the agency posts a recompete solicitation — and the bidders who saw it coming have a 6–18 month head start on capture planning. FedRange surfaces contracts in your NAICS (optionally your state) whose period_end falls in the next 12–18 months, filtered to the same competitive-only pool as the percentile band. The same sole-source / AbilityOne exclusion regex applies — a sole-source incumbent isn't actually "recompeting" in any meaningful sense.
The radar appears on the public slice page (e.g. /slice/561720) and inside the in-app pricing intelligence brief. It is the cheapest pipeline-building signal we know how to extract from the public record.
Refresh cadence.
The awards table is re-ingested weekly (Monday 06:00 UTC) via an Inngest scheduled function. Per-award detail enrichment — top winners, agency mix — runs daily. Solicitation data from SAM.gov is pulled daily at 02:00 UTC. CFC opinion ingestion runs daily at 09:00 UTC.
Awards table last refreshed: June 5, 2026 at 2:06 PM UTC · 25,720 award rows total
Known limitations.
Things to be skeptical of, in approximate order of how often they bite:
- Modification noise. A single contract with seven modifications shows as seven actions. Our de-dup uses the unique award ID so the underlying contract counts once; obligation totals across modifications are summed, not double-counted.
- Recipient-name normalisation. "ABC SERVICES, LLC" and "ABC Services LLC" and "Abc Services L L C" are the same firm. We normalise to a canonical UEI when one is present and fall back to a case-insensitive name match when it is not. UEI columns are intermittently populated in our current ingest snapshot; UEI backfill is an active workstream.
- Place-of-performance state. The state shown reflects the POP state on the award, not the bidder's headquarters. A Maryland firm winning a Texas contract shows under TX, not MD.
- Set-aside status backfill. Some pre-2019 records lack set-aside type codes; we infer where possible from solicitation cross-reference but flag the inferred rows as such in the raw data layer.
Source citations.
[1] Federal Acquisition Regulation §15.305 — "Proposal Evaluation". The legal basis on which evaluators compare your bid against historical comparables. Available at acquisition.gov/far/15.305.
[2] USASpending.gov API Documentation. Department of the Treasury, Bureau of the Fiscal Service. Available at api.usaspending.gov/docs.
[3] SAM.gov Get Opportunities Public API. open.gsa.gov/api/get-opportunities-public-api.
[4] Court of Federal Claims bid-protest opinions, 2014-present, via the Government Printing Office's govinfo.gov USCOURTS collection. Each opinion is classified by outcome (granted / denied / dismissed / partial) and grounds (price realism, technical evaluation, set-aside, OCI, etc.) via a regex taxonomy applied to the opinion body. The appellate tier above GAO; opinions are precedential where GAO decisions are advisory. Searchable at govinfo.gov/app/collection/uscourts/national/cofc.