Labor rate benchmark (should-cost)
Return the distribution of awarded hourly labor rates for a labor category, from the ceiling rates on GSA Multiple Award Schedule (MAS) contracts. Give it a labor category (and optionally an education level, years of experience, NAICS, vendor, worksite, business size, or clearance) and it returns the rate percentiles plus real comparable awarded rates. This is the should-cost / IGCE labor input: what a labor category has actually been awarded at, which is how contractors build a cost estimate and how contracting officers benchmark a proposed rate.
Beyond the base distribution the response supports three parts of the actual pricing workflow:
- Out-year escalation (
escalation): the typical year-over-year change in the awarded ceiling rate, so you can set and justify option-year escalation. - Competitor / self rate card (
vendorfilter): scope the distribution to one vendor to read what a specific competitor, or your own company, has been awarded for the category. - Category discovery (
category_breakdown,suggestions): the category names in this data are free text, so a match pools variants and shows how it decomposes; a query that returns too few rates comes back with the nearest real categories to search instead.
It is the labor-rate companion to the contract pricing benchmark, which reads total contract value. Together they cover both sides of pricing a services bid: what the contract is worth, and what the labor inside it should cost. As with the benchmark, this is a market read, not "the price to win": the winning rate depends on your cost structure, the competition, and the evaluation method.
Parameters
labor_category is required. Unknown parameters return 400.
labor_category: the role to benchmark (for exampleProgram Manager,Software Engineer,Systems Administrator). Required.match:contains(default, substring match, soProgram Managercatches "Senior Program Manager") orexact.education_level:HS,AA,BA,MA,PHD, orOTHER. Case-insensitive, and common spellings resolve (BS,Bachelorsmap toBA;MasterstoMA). An unrecognized value returns400with the valid set, not an empty result.min_experience/max_experience: bound the minimum-years-of-experience the rate is priced at (0–60).naics: a 6-digit NAICS. Matched through the SIN, sonaics=541512scopes to IT-systems-design labor. (GSA SINs are NAICS-aligned; some are 5-digit families, so this is a prefix match.)vendor: a vendor name (substring, case-insensitive), for the competitor / self rate card.vendor=booz allenscopes the distribution to that vendor.worksite: where the work is performed.Customer(a government site),Contractor(the contractor's own facility), orVirtual. The response'sCustomer_Facility/Contractor_Facilityvalues are accepted as well. Rates differ by worksite: as of October 31, 2026 the Program Manager median is $176.89 at a customer facility and $188.83 at a contractor facility, so set it when the requirement names the place of performance.business_size:S(small business) orO(other than small).security_clearance:YesorNo.value_basis: which year's rate to measure.current(default),next_year, orsecond_year(the escalated option-year rates).sample_limit: how many comparable rates to return,0to25(default10), ordered by rate.
Response
A flat aggregate object:
labor_category,value_basis(echoed),min_sample_size.rate_distribution:sample_size: the number of awarded rates matched, counted the way GSA's CALC+ counts them: GSA lists a vendor's rate once per worksite and once per SIN it is offered under, so one price can count more than once.unit: alwaysUSD_per_hour.suppressed:truewhen fewer thanmin_sample_size(20) rates back the query;percentilesis thennullwith asuppressed_reason.percentiles:p10,p25,p50(median),p75,p90, in dollars per hour.min,max,avg.escalation: the typical out-year change in the ceiling rate, ornullwhen the sample is too small.median_next_year_pctandmedian_second_year_pctare the median year-over-year percentage change across the matched awards;basisnames the method andsample_sizethe number of awards behind it.rates_sample: up tosample_limitreal awarded rates, each withrate,labor_category,education_level,min_years_experience,vendor_name,idv_piid(the GSA contract),sin,naics,schedule,business_size,security_clearance,worksite(Customer_Facility,Contractor_Facility, orVirtual). GSA lists a rate once per worksite and once per SIN, so the same vendor, title and price can appear on several rows that differ only inworksiteorsin.category_breakdown: present when the match pooled more than one distinct category name. The top variants by sample size, each withlabor_category,sample_size, andmedian, so you can narrow to the exact one you mean.suggestions: present only when the result is suppressed (too few rates). The nearest real category names with theirsample_size, so a thin query points you to a better one.filters_applied,_sources(gsa_calc).
Read the range. Labor-category names vary between vendors, so contains intentionally pools variants (a "Program Manager" query includes "Program Manager II", "Program Manager - SVCM", and so on); the percentiles smooth over the naming noise, and category_breakdown shows the variants if you want to narrow.
Ceiling rates are the maximum billable rate on the schedule, not the average awarded price. The realistic should-cost target for a competitive bid is usually around the lower-middle of the range (p25–p50), not the ceiling.
Example
curl -H "Authorization: Bearer $GOVCON_API_KEY" \
"https://govconapi.com/api/v1/pricing/labor-rates?labor_category=Program%20Manager&education_level=BA&min_experience=5&max_experience=15&sample_limit=2"
{
"labor_category": "Program Manager",
"value_basis": "current",
"min_sample_size": 20,
"rate_distribution": {
"sample_size": 5259,
"unit": "USD_per_hour",
"suppressed": false,
"percentiles": { "p10": 127.99, "p25": 154.67, "p50": 184.76, "p75": 221.56, "p90": 264.78 },
"min": 36.28,
"max": 499.91,
"avg": 192.02
},
"escalation": {
"basis": "median year-over-year change in awarded ceiling rate",
"sample_size": 5152,
"median_next_year_pct": 2.6,
"median_second_year_pct": 2.7
},
"rates_sample": [
{
"rate": 36.28,
"labor_category": "Program Manager - SVCM",
"education_level": "BA",
"min_years_experience": 7,
"vendor_name": "SEBA PROFESSIONAL SERVICES LLC",
"idv_piid": "GS23F057AA",
"sin": "541614SVC",
"naics": "541614",
"schedule": "MAS",
"business_size": "S",
"security_clearance": "No",
"worksite": "Contractor_Facility"
}
],
"category_breakdown": [
{ "labor_category": "Program Manager", "sample_size": 1336, "median": 182.42 },
{ "labor_category": "Program Manager II", "sample_size": 318, "median": 197.21 },
{ "labor_category": "Program Manager 2", "sample_size": 81, "median": 188.83 }
],
"filters_applied": { "labor_category": "Program Manager", "match": "contains", "value_basis": "current", "education_level": "BA", "min_experience": 5, "max_experience": 15 },
"_sources": ["gsa_calc"]
}
More examples
Scope a role to an industry via NAICS (software engineers on IT-systems-design work):
curl -H "Authorization: Bearer $GOVCON_API_KEY" \
"https://govconapi.com/api/v1/pricing/labor-rates?labor_category=Software%20Engineer&naics=541512"
Read one vendor's rate card , what a specific competitor (or your own company) has been awarded for the category:
curl -H "Authorization: Bearer $GOVCON_API_KEY" \
"https://govconapi.com/api/v1/pricing/labor-rates?labor_category=Program%20Manager&vendor=booz%20allen"
Price on-site work, at a government facility:
curl -H "Authorization: Bearer $GOVCON_API_KEY" \
"https://govconapi.com/api/v1/pricing/labor-rates?labor_category=Program%20Manager&worksite=Customer"
Read the escalated out-year rate instead of the current year:
curl -H "Authorization: Bearer $GOVCON_API_KEY" \
"https://govconapi.com/api/v1/pricing/labor-rates?labor_category=Systems%20Administrator&value_basis=next_year"
When a query returns too few rates, the response is suppressed and carries suggestions , the nearest real category names to search instead. A labor_category=Program Mgr query, for example, comes back suppressed with suggestions led by Program Manager (1,775 rates), Program Manager II (455), and so on.
Plans and limits
This endpoint requires a paid plan (free returns 402). Unlike /pricing/benchmark and /pricing/position, which are Pro, this is on every paid plan: raw GSA CALC rates are a base dataset. It rides the standard per-key rate limit (1,000 requests/hour on paid plans, with a short per-minute burst cap) like any other data endpoint.
| Plan | Access |
|---|---|
| Free | not included (402) |
| Developer | included |
| Pro | included |
Errors
400,labor_categorymissing, an invalidmatchorvalue_basis, anaicsthat is not 6 digits, an unrecognizededucation_level/business_size/security_clearance/worksite,min_experiencegreater thanmax_experience, or an unknown query parameter.401, no API key.402, the free trial. This endpoint requires a paid plan (Developer or Pro).429, the standard rate limit was exceeded (1,000 requests/hour on paid plans, or the short per-minute burst).
A labor category with no matching rates returns 200 with a suppressed distribution (sample_size 0), not an error.
Notes for integrators
- Source: GSA CALC+ Contract-Awarded Labor Category ceiling rates on MAS services schedules, refreshed daily. These are awarded ceiling rates (the maximum billable), the standard IGCE / price-analysis labor reference.
naicsis derived from the SIN; GSA SINs are NAICS-aligned, and some are 5-digit families, sonaicsis a prefix match (a 6-digit code matches its SIN family).- Escalated
next_year/second_yearrates are the contract's own option-year pricing where the schedule provides them.