GET/v1/salary-competitiveness

Assess whether a salary offer is competitive for a role and location

Assess how a concrete salary offer positions against the market benchmark for a given role and location. This is the agent-first endpoint for answering 'Is this offer competitive?' questions — it accepts natural language job titles and locations and returns a percentile rank plus a categorical assessment. **When to use:** answer 'Is €65K competitive for a developer in Berlin?', flag below-market offers in an ATS before publishing, or build a 'salary score' widget for a candidate-facing dashboard. **How it works:** resolves the job title to a SOC (US) or ISCO (EU) code, resolves the location to a US metro or EU country, fetches the benchmark distribution (p10-p90), and computes the offered salary's percentile using log-normal interpolation. The `assessment` is one of `below_market` (<25th percentile), `competitive` (25th-75th), or `above_market` (>75th). **Currency handling:** if the offered `currency` differs from the benchmark currency (EUR for EU, USD for US), the response `methodology_note` will spell out that no FX conversion is applied — the caller must ensure semantic alignment. Source: BLS OES (US), Eurostat SES (EU). Required scope: `salary:read`.

Authentication

Requires API key via X-API-Key header.

Parameters

NameInTypeRequiredDescription
jobquerystringrequiredJob title in natural language, e.g. 'Software Developer', 'Data Scientist', 'Nurse'
locationquerystringrequiredCity, country, or metro area in natural language, e.g. 'Berlin', 'Austin, TX', 'Germany'
salaryquerynumberrequiredOffered salary amount in the supplied currency and period
salary_periodquerystringoptionalSalary period: 'annual', 'monthly', or 'hourly'
currencyquerystringoptionalCurrency code: 'USD' or 'EUR'

Example request

curl
curl -X GET \
  "https://salary.wageapi.com/api/v1/salary-competitiveness?job=%3Cjob%3E&location=%3Clocation%3E&salary=%3Csalary%3E&salary_period=annual&currency=USD" \
  -H "X-API-Key: YOUR_API_KEY"

Responses

200Successful Response
job_titlestringrequired
matched_titlestringrequired
locationstringrequired
offered_salarynumberrequired
currencystringrequired
assessmentstringrequiredenum: below_market | competitive | above_market
percentile_rankintegerrequired

Estimated percentile (0-100)

min 0 · max 100

benchmark_meananyoptional
one of:
option 1:
number
option 2:
null
benchmark_mediananyoptional
one of:
option 1:
number
option 2:
null
benchmark_p25anyoptional
one of:
option 1:
number
option 2:
null
benchmark_p75anyoptional
one of:
option 1:
number
option 2:
null
data_sourcestringrequired
data_yearanyoptional
one of:
option 1:
integer
option 2:
null
methodology_notestringrequired
400Location could not be resolved to a US metro or EU country.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
401Missing or invalid API key.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
403API key lacks the required scope for this endpoint.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
404No matching occupation or no published benchmark for this job/location pair.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
422Request validation failed (bad JSON shape, missing required fields, etc.).
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
429Daily rate limit exceeded for this API key.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null
500Unexpected server error. Includes a request_id for support.
errorErrorDetailrequired

Structured error payload returned by all Aethar APIs. Mirrors the shape produced by aethar_auth.exception_handlers so the OpenAPI spec accurately describes real error bodies for documentation readers and MCP clients.

codestringrequired

Machine-readable error code (e.g. INVALID_API_KEY)

messagestringrequired

Human-readable error message

statusintegerrequired

HTTP status code

request_idstringrequired

Request identifier — include in support tickets

suggestionanyoptional

Actionable hint on how to resolve the error

one of:
option 1:
string
option 2:
null
doc_urlanyoptional

Link to full documentation for this error code

one of:
option 1:
string
option 2:
null
fieldanyoptional

Field that caused the error (if applicable)

one of:
option 1:
string
option 2:
null
errorsanyoptional

Per-field validation errors (only for 422 VALIDATION_ERROR responses)

one of:
option 1:
array of object
object
option 2:
null

Try this endpoint

Create a free Aethar account and generate an API key in 2 minutes.

Create free account →