{
  "openapi": "3.0.3",
  "info": {
    "title": "Wage Data API (H-1B/LCA vs BLS OEWS)",
    "version": "0.2.0",
    "description": "Employer and occupation wage percentiles from DOL OFLC LCA disclosure data, and BLS OEWS percentiles for every occupation nationally, by state and by metro area. Every 2xx response carries source attribution. Only 2xx GET responses count toward your monthly quota: 4xx and 5xx responses are refunded and HEAD requests are never metered.\n\nPlans: free, basic, pro and ultra keys have a monthly quota and a per-minute limit per key. The extension plan is a public key embedded in the RangeCheck browser extension: no monthly quota, a limit per client IP (20 per minute, 500 per day), only GET /v1/wages/occupation and GET /v1/wages/employer, and employer data only with a valid RangeCheck Pro license key in X-License-Key (verified server side with Polar).\n\nTitle matching: a title listed under several occupations is returned with match.ambiguous = true, match.candidates (up to 3, with national employment) and a score of 0.65 or less; treat it as no verdict.\n\nThis product includes information from the O*NET 30.0 Database by the U.S. Department of Labor, Employment and Training Administration (USDOL/ETA), used under the CC BY 4.0 license (https://creativecommons.org/licenses/by/4.0/). Modified: titles were normalised and mapped to OEWS codes. USDOL/ETA has not approved, endorsed, or tested these modifications. O*NET® is a trademark of USDOL/ETA."
  },
  "servers": [
    {
      "url": "https://data-api.premed-toolkit.workers.dev"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      },
      "LicenseKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-License-Key",
        "description": "Extension plan only: RangeCheck Pro (Polar) license key, required for employer data."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "NoMatchError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "no_match"
                ]
              },
              "message": {
                "type": "string"
              },
              "min_score": {
                "type": "number"
              },
              "suggestions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "soc": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "score": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Attribution": {
        "type": "object",
        "properties": {
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "as_of": {
                  "type": "string"
                }
              }
            }
          },
          "notice": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          }
        }
      },
      "Meta": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string"
          },
          "dataset": {
            "type": "string"
          },
          "billed_units": {
            "type": "integer"
          }
        }
      },
      "TitleMatch": {
        "type": "object",
        "properties": {
          "soc": {
            "type": "string",
            "example": "15-1252"
          },
          "title": {
            "type": "string",
            "description": "Official SOC title"
          },
          "matched_title": {
            "type": "string",
            "description": "The SOC title or O*NET alternate title that matched"
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "1 = exact title. Below 0.6 the API returns 404 no_match instead of guessing."
          },
          "method": {
            "type": "string",
            "enum": [
              "soc_code",
              "soc_title",
              "alternate_title",
              "title_tokens",
              "curated"
            ]
          },
          "ambiguous": {
            "type": "boolean",
            "description": "Present and true when the title is listed under several occupations; score is then 0.65 or less. Show the candidates, not a verdict."
          },
          "candidates": {
            "type": "array",
            "description": "Ambiguous titles only: up to 3 occupations, most likely first",
            "items": {
              "type": "object",
              "properties": {
                "soc": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "employment": {
                  "type": "integer",
                  "nullable": true
                }
              }
            }
          }
        }
      },
      "OccupationByTitle": {
        "type": "object",
        "properties": {
          "occupation": {
            "type": "string"
          },
          "soc": {
            "type": "string"
          },
          "match": {
            "$ref": "#/components/schemas/TitleMatch"
          },
          "area": {
            "type": "string",
            "description": "Metro title, two-letter state, or US"
          },
          "area_name": {
            "type": "string"
          },
          "area_code": {
            "type": "string"
          },
          "area_level": {
            "type": "string",
            "enum": [
              "metro",
              "state",
              "national"
            ]
          },
          "p10": {
            "type": "integer",
            "nullable": true,
            "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
          },
          "p25": {
            "type": "integer",
            "nullable": true,
            "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
          },
          "p50": {
            "type": "integer",
            "nullable": true,
            "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
          },
          "p75": {
            "type": "integer",
            "nullable": true,
            "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
          },
          "p90": {
            "type": "integer",
            "nullable": true,
            "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
          },
          "mean": {
            "type": "integer",
            "nullable": true
          },
          "employment": {
            "type": "integer",
            "nullable": true
          },
          "top_coded": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Percentiles at or above the BLS top code (null in the response)"
          },
          "top_code_usd": {
            "type": "integer"
          },
          "hourly_usd": {
            "type": "object",
            "properties": {
              "p10": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p25": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p50": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p75": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p90": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              }
            }
          },
          "wage_basis": {
            "type": "string",
            "enum": [
              "both",
              "hourly_only",
              "annual_only"
            ]
          },
          "year": {
            "type": "integer"
          },
          "source": {
            "type": "string",
            "example": "BLS OEWS May 2025, state estimate"
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Why a city or state was not used, when the area fell back"
          }
        }
      },
      "EmployerByName": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "query_name": {
            "type": "string"
          },
          "matched_name": {
            "type": "string"
          },
          "match": {
            "type": "string",
            "enum": [
              "exact",
              "fuzzy"
            ]
          },
          "scope": {
            "type": "string",
            "enum": [
              "employer",
              "title"
            ]
          },
          "title": {
            "type": "string"
          },
          "soc": {
            "type": "string"
          },
          "filings": {
            "type": "integer"
          },
          "employer_filings": {
            "type": "integer"
          },
          "p10": {
            "type": "integer",
            "nullable": true
          },
          "p25": {
            "type": "integer",
            "nullable": true
          },
          "p50": {
            "type": "integer",
            "nullable": true
          },
          "p75": {
            "type": "integer",
            "nullable": true
          },
          "p90": {
            "type": "integer",
            "nullable": true
          },
          "source": {
            "type": "string"
          },
          "wage_percentiles_usd": {
            "type": "object",
            "properties": {
              "p10": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p25": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p50": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p75": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p90": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              }
            }
          },
          "median_vs_oews_ratio": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "Employer": {
        "type": "object",
        "properties": {
          "employer": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "filings": {
            "type": "integer"
          },
          "wage_percentiles_usd": {
            "type": "object",
            "properties": {
              "p10": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p25": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p50": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p75": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p90": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              }
            }
          },
          "median_vs_oews_ratio": {
            "type": "number",
            "nullable": true
          },
          "wage_level_pct": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "top_states": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "occupations": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "name_variants_merged": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "OccupationMetro": {
        "type": "object",
        "properties": {
          "soc": {
            "type": "string"
          },
          "occupation": {
            "type": "string"
          },
          "metro": {
            "type": "string"
          },
          "msa_code": {
            "type": "string"
          },
          "metro_slug": {
            "type": "string"
          },
          "filings": {
            "type": "integer"
          },
          "lca_wage_percentiles_usd": {
            "type": "object",
            "properties": {
              "p10": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p25": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p50": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p75": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p90": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              }
            }
          },
          "oews_wage_percentiles_usd": {
            "type": "object",
            "properties": {
              "p10": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p25": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p50": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p75": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              },
              "p90": {
                "type": "integer",
                "nullable": true,
                "description": "Annual USD. null when BLS suppresses the estimate or it is top coded (see top_coded)."
              }
            }
          },
          "oews_median_usd": {
            "type": "integer",
            "nullable": true
          },
          "ratio_to_oews": {
            "type": "number",
            "nullable": true
          },
          "oews_employment": {
            "type": "number",
            "nullable": true
          },
          "wage_level_pct": {
            "type": "object"
          },
          "top_employers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "metros": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Present instead of the metro fields when metro is omitted"
          }
        }
      },
      "Search": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "calls_used": {
            "type": "integer"
          },
          "monthly_quota": {
            "type": "integer",
            "nullable": true
          },
          "calls_remaining": {
            "type": "integer",
            "nullable": true
          },
          "rate_limit_per_minute": {
            "type": "integer"
          }
        }
      }
    }
  },
  "paths": {
    "/v1/wages/employer/{slug}": {
      "get": {
        "operationId": "getEmployerWages",
        "summary": "H-1B/LCA wage percentiles for one employer",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "amazon"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "attribution",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Employer"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_encoding or bad_slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown employer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Only GET, HEAD and OPTIONS are supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal: unexpected error. Not billed; the quota unit is refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wages/occupation/{soc}": {
      "get": {
        "operationId": "getOccupationWages",
        "summary": "Occupation wages by metro (LCA vs OEWS)",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "soc",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{2}-\\d{4}$"
            },
            "example": "15-1252"
          },
          {
            "name": "metro",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Metro slug, MSA code or name fragment. Omit to list metros.",
            "example": "san-jose"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            },
            "description": "Metros listed when metro is omitted."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "attribution",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OccupationMetro"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_soc or bad_metro",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Only GET, HEAD and OPTIONS are supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal: unexpected error. Not billed; the quota unit is refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wages/search": {
      "get": {
        "operationId": "searchWages",
        "summary": "Search employers and occupations",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "google"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "employer",
                "occupation"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 10
            },
            "description": "Capped per plan (10 to 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "attribution",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Search"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_query or bad_type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Only GET, HEAD and OPTIONS are supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal: unexpected error. Not billed; the quota unit is refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wages/occupation": {
      "get": {
        "operationId": "getOccupationWagesByTitle",
        "summary": "Free-text job title to BLS OEWS percentiles (metro, then state, then national)",
        "description": "The title is matched to an SOC code against every OEWS SOC title and O*NET alternate titles, with a score. Below 0.6 the API returns 404 no_match with suggestions instead of guessing. A city is used only when it names a principal city of a metro in the requested state; otherwise the real BLS state estimate (or national estimate) is returned.",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          },
          {
            "ApiKeyHeader": [],
            "LicenseKey": []
          }
        ],
        "parameters": [
          {
            "name": "title",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "software engineer"
          },
          {
            "name": "level",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Accepted for client compatibility; not used."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "example": "TX",
            "description": "Two-letter U.S. state code (50 states, DC, PR, GU, VI). Anything else is 400 bad_state."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 60
            },
            "example": "Austin",
            "description": "Whole city name; fewer than 3 characters is ignored."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "attribution",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OccupationByTitle"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_query, title_too_long, bad_state or bad_city",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "no_match: no confident occupation match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NoMatchError"
                }
              }
            }
          },
          "405": {
            "description": "Only GET, HEAD and OPTIONS are supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal: unexpected error. Not billed; the quota unit is refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/wages/employer": {
      "get": {
        "operationId": "getEmployerWagesByName",
        "summary": "Employer wage percentiles by name, optional job title",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          },
          {
            "ApiKeyHeader": [],
            "LicenseKey": []
          }
        ],
        "description": "Extension plan: needs X-License-Key with a valid RangeCheck Pro license (403 pro_required otherwise; 503 license_check_unavailable when Polar cannot be reached).",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 100
            },
            "example": "Amazon"
          },
          {
            "name": "title",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "software",
            "description": "With title, p25/p50/p75/filings are for that employer's matching occupation and p10/p90 are null."
          },
          {
            "name": "X-License-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Extension plan only."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "attribution",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EmployerByName"
                    },
                    "attribution": {
                      "$ref": "#/components/schemas/Attribution"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_query or title_too_long",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No filings, or no filings matching title",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Only GET, HEAD and OPTIONS are supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal: unexpected error. Not billed; the quota unit is refunded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "license_check_unavailable (extension plan)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Current month usage and limits for your key (not metered)",
        "security": [
          {
            "ApiKeyHeader": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Usage"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "tier_unknown, endpoint_not_in_plan (extension plan), pro_required or pro_unavailable (extension plan employer data)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited (per minute, per key or per IP) or quota_exceeded (monthly). See Retry-After.",
            "headers": {
              "x-ratelimit-limit": {
                "description": "Requests allowed per minute for this key (or per IP on the extension plan when limited).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-ratelimit-remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-limit": {
                "description": "Monthly quota of the plan. Absent on plans without a monthly quota (extension, RapidAPI).",
                "schema": {
                  "type": "integer"
                }
              },
              "x-quota-remaining": {
                "description": "Calls left this UTC month.",
                "schema": {
                  "type": "integer"
                }
              },
              "retry-after": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/health": {
      "get": {
        "operationId": "health",
        "summary": "Liveness and dataset versions (no key needed)",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "datasets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "meta": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}