NOTICEBuilt on public records from USASpending.gov and SAM.gov. Not affiliated with any government agency.
Methodology

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 covers seven verticals — janitorial (561720), grounds (561730), security (561612), facilities support (561210), and the construction trades building (236220), HVAC (238220) & electrical (238210). The methodology applies to any service or construction NAICS; pricing, comps, and the recompete radar cover all seven, while the SCA wage floor applies to the four service verticals (construction runs on Davis-Bacon prevailing wage — that floor is on the roadmap).

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 services and construction contractors (NAICS 561720, 561730, 561612, 561210, 236220, 238220, 238210) 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/search
    Active 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 the annualized award value — each award’s obligated amount divided by its period of performance in years — so a $5M five-year contract and a $1M one-year contract of the same yearly run-rate land together. This matches how janitorial work is actually priced and bid (per year), and it is the same unit used across the opportunity analyzer, the slice pages, and the regional benchmarks. Note the underlying figure is the award’s obligation (not its base-plus-all-options ceiling), so treat the band as an annual run-rate estimate and confirm against the specific solicitation.

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 Offerors
    Page 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 Factors
    The 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 Work
    What 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. H342 for 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 each award’s obligated amount (funds committed), annualized by its period of performance, rather than ceiling values (what the contract is theoretically worth if every option is exercised) — because pricing for a comparable contract tracks obligation reality, not ceiling fiction.

Service Contract Act wage rates.

For the active coverage today — janitorial (561720), grounds & landscaping (561730), security guards (561612), and facilities support (561210) — 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, and home health 621610 as coverage expands.)

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. SCA wage coverage is janitorial (561720), grounds (561730), security (561612), and facilities support (561210) today; the construction trades (236220, 238220, 238210) run on Davis-Bacon prevailing wage, which is on the roadmap.

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: July 20, 2026 at 2:08 PM UTC · 63,620 award rows total

Known limitations.

Things to be skeptical of, in approximate order of how often they bite:

  1. 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.
  2. 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.
  3. 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.
  4. 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.