Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Salary Validation

GrantKit validates proposed salaries against Bureau of Labor Statistics (BLS) Occupational Employment and Wage Statistics (OEWS) data to ensure they’re reasonable and defensible.

Why Validate Salaries?

NSF and other funders scrutinize personnel costs. Salaries significantly above market rates may:

GrantKit compares your proposed salaries to national and regional wage percentiles, flagging potential issues before submission.

How it runs

Salary validation runs as part of grantkit check — but only when a BLS_API_KEY is set in the environment, because it makes network calls to the BLS API. Without a key, check skips it entirely and stays offline.

export BLS_API_KEY="your-key-here"   # https://www.bls.gov/developers/
grantkit check

Personnel are read from your budget.yaml (personnel.senior_key). Each person may carry an occupation (a SOC code or a supported name), months, and area; GrantKit annualizes the salary and estimates its OEWS percentile. Findings surface as check items:

For ad-hoc checks outside a grant, use the programmatic API below.

Supported Occupations

NameSOC CodeDescription
software_developer15-1252Software Developers
data_scientist15-2051Data Scientists
cs_professor25-1021Computer Science Teachers, Postsecondary
economist19-3011Economists
postdoc19-4099Life, Physical, Social Science Technicians
research_assistant19-4061Social Science Research Assistants
statistician15-2041Statisticians
operations_research15-2031Operations Research Analysts

You can also use SOC codes directly: --occupation 15-1252

Supported Areas

NameCodeDescription
national0000000National average
san_francisco41860San Francisco-Oakland-Hayward, CA
boston14460Boston-Cambridge-Nashua, MA-NH
washington_dc47900Washington-Arlington-Alexandria, DC-VA-MD-WV
new_york35620New York-Newark-Jersey City, NY-NJ-PA
los_angeles31080Los Angeles-Long Beach-Anaheim, CA
seattle42660Seattle-Tacoma-Bellevue, WA
austin12420Austin-Round Rock, TX

Thresholds

PercentileStatus
< 10thWarning: unusually low
10th - 75thOK
75th - 95thWarning: above market median
> 95thError: requires justification

Programmatic Usage

from grantkit.budget import SalaryValidator, get_salary_validator

validator = get_salary_validator(default_area="san_francisco")

result = validator.validate_salary(
    salary=150000,
    occupation="software_developer",
    months=12,
)

print(f"Percentile: {result.percentile}")
print(f"Valid: {result.is_valid}")
print(f"Warnings: {result.warnings}")

Data Source

Wage data comes from the BLS Occupational Employment and Wage Statistics (OEWS) program:

GrantKit caches OEWS data locally to avoid repeated API calls. Use a BLS API key for higher rate limits:

export BLS_API_KEY="your-key-here"

Register for a free key at https://www.bls.gov/developers/