# Pay Transparency Checker: Job Ads Missing Salary (US, Canada) (`jtpalms/pay-transparency-checker`) Actor

Check job postings from thousands of company career sites against pay-transparency laws in Ontario, BC, PEI, New Brunswick and 17 US states and cities, including NYC, California, Colorado, Illinois, Massachusetts and New Jersey. Flags missing, open-ended or too-wide pay ranges.

- **URL**: https://apify.com/jtpalms/pay-transparency-checker.md
- **Developed by:** [JT Palms](https://apify.com/jtpalms) (community)
- **Categories:** Jobs, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 posting returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Pay Transparency Checker: job ads missing salary ranges

Check open job postings against pay-transparency laws in the US and Canada, and find the ones that show no pay range, only half of one, or (in Ontario) a range wider than the law allows. The postings come from a twice-daily index of thousands of company career sites (Greenhouse, Ashby, Lever, Workable, Recruitee, Personio, Breezy, Teamtailor, Gem and Pinpoint).

- **Laws covered:** Ontario (from January 2026), British Columbia, Prince Edward Island and New Brunswick (from June 2026) in Canada. In the US: California, Colorado, the District of Columbia, Hawaii, Illinois, Maryland, Massachusetts, Minnesota, New Jersey, New York State, Vermont and Washington, plus New York City, Westchester County, Ithaca, Jersey City and Cleveland. Columbus (Ohio) is checked from January 2027, when enforcement starts, and Delaware from September 2027. Each was checked against the statute or the official guidance, and every flag links to its source.
- **USD 5 per 1,000 postings returned.** Postings filtered out are free.

### What people use it for

- **HR and talent teams:** check your own open postings before a regulator or a candidate does.
- **Recruiters and job boards:** catch postings that would need a pay range before you syndicate them.
- **Compliance and employment lawyers:** size a client's exposure across locations.
- **Journalists and researchers:** measure how many postings in a city show pay, by company or by role.

### What you get

One row per posting:

```json
{
  "title": "Senior Data Engineer",
  "company": "Example Corp",
  "location": "New York, NY",
  "locations": ["New York, NY"],
  "jurisdictions": ["US-NY", "US-NY-NYC"],
  "payShown": false,
  "pay": null,
  "flags": [
    { "law": "US-NY", "issue": "no-pay-shown", "note": "No pay range found in the posting. New York State requires one from employers with 4+ employees." },
    { "law": "US-NY-NYC", "issue": "no-pay-shown", "note": "No pay range found in the posting. New York City requires one from employers with 4+ employees." }
  ],
  "sources": [
    { "code": "US-NY", "url": "https://www.nysenate.gov/legislation/laws/LAB/194-B" },
    { "code": "US-NY-NYC", "url": "https://www.nyc.gov/assets/cchr/downloads/pdf/publications/Salary-Transparency-Factsheet.pdf" }
  ],
  "jobUrl": "https://job-boards.greenhouse.io/example/jobs/123"
}
```

The run's **summary** counts, per law, how many postings were checked, how many showed pay, and how many were flagged, so you get a pay-transparency rate for a city or a company in one run.

Flags:

- **`no-pay-shown`**: no pay range was found, either in the job board's pay field or in the description.
- **`open-ended-range`**: only a minimum or only a maximum is shown, where the law requires both (British Columbia, New York, New York City, Westchester, Ithaca, New Jersey, Jersey City, the District of Columbia, Colorado, Washington, Maryland, Minnesota).
- **`range-too-wide`** (Ontario): the range is more than $50,000 a year wide. Hourly and monthly ranges are converted to yearly. Not checked when the range ends above $200,000 a year, where Ontario's rule does not apply.

### How to use it

1. Pick the **Jurisdictions** you care about, or leave it empty for all.
2. Narrow by **Companies**, **Job title keywords** or **Job board platforms** if you want.
3. Choose **Postings**: all open postings, or only new ones in a recent window (schedule it daily with "last 24 hours" to check new postings as they appear).
4. Run it and export the flagged postings as CSV, JSON or Excel.

### Important limits

- **This is a screening tool, not legal advice.** A flag means "review this posting", not "this posting breaks the law".
- **Employer size is not visible in a posting.** Most laws apply only above a headcount (for example 15+ employees in California). Each flag states the threshold; you decide whether the employer is covered.
- **Location decides the law.** A job counts when any of its locations is in the state or city. `location` is the first location the job board lists and `locations` lists them all, so a job posted for Quebec and Toronto is checked against Ontario's law. Fully remote postings without a location are not matched, although several laws also cover remote jobs that could be filled there.
- **Pay found in the text counts.** If the range is on a linked page rather than in the posting, the posting is flagged even where a link is allowed (Illinois).
- **Other required items** are not checked: benefits descriptions and application deadlines (US), and Ontario's statements on AI use in hiring, whether the job is an existing vacancy, and the ban on requiring Canadian experience.
- **Not covered yet:** Virginia (a 2026 law; added once its start date is confirmed from the official record), Albany County (NY State's law still applies there), Newfoundland and Labrador (its posting rule is enacted but not yet in force), provinces with no posting law, and the EU: no EU country currently requires a pay range in the job ad itself (Poland requires pay information before the interview; France has a pending bill).

### Related actors

- [Career Site Jobs Index: Greenhouse, Ashby, Lever & More](https://apify.com/JTPalms/ats-jobs-index): Fresh jobs from thousands of company career sites, indexed twice a day from the official public job-board APIs of Greenhouse, Ashby,...
- [Hiring Signals: Companies Hiring by Role, Team & Location](https://apify.com/JTPalms/hiring-signals): Find companies hiring right now, one row per company: open roles by team, seniority and location, roles posted in the last 7 and 30...
- [Career Page Jobs Scraper: Auto-Detects the Job Board (ATS)](https://apify.com/JTPalms/career-page-jobs): Give company websites or careers pages and get every open job.

### FAQ

**Where do the postings come from?** From companies' own public job boards, read through each platform's official public job feed and refreshed twice a day. No personal data is collected.

**Can I check one company's postings?** Yes: put its name in **Companies** and choose **All open postings**.

**A law changed or a flag is wrong?** Open an issue with the posting link or the law, and it will be corrected.

# Actor input Schema

## `jurisdictions` (type: `array`):

Which pay-transparency laws to check against. Leave empty for all of them. A job counts when its location is in that state or city.

## `companies` (type: `array`):

Only postings from companies whose name or job board name contains any of these texts, for example your own company.

## `keywords` (type: `array`):

Only postings whose title matches any of these, for example engineer or nurse.

## `ats` (type: `array`):

Only postings from these platforms. Leave empty for all.

## `timeRange` (type: `string`):

Which postings to check: all open ones, or only those new in a recent window.

## `onlyFlagged` (type: `boolean`):

Return only postings with a possible issue. Switch off to get every checked posting with its result (the summary counts them all either way).

## `maxJobs` (type: `integer`):

Stop after this many postings. You pay only for postings returned.

## Actor input object example

```json
{
  "jurisdictions": [
    "US-NY-NYC",
    "US-CA",
    "CA-ON"
  ],
  "timeRange": "7d",
  "onlyFlagged": true,
  "maxJobs": 100
}
```

# Actor output Schema

## `results` (type: `string`):

Postings checked, with flags and sources.

## `summary` (type: `string`):

Postings checked, with pay shown, and flagged, per law.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "jurisdictions": [
        "US-NY-NYC",
        "US-CA",
        "CA-ON"
    ],
    "timeRange": "7d",
    "maxJobs": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("jtpalms/pay-transparency-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "jurisdictions": [
        "US-NY-NYC",
        "US-CA",
        "CA-ON",
    ],
    "timeRange": "7d",
    "maxJobs": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("jtpalms/pay-transparency-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "jurisdictions": [
    "US-NY-NYC",
    "US-CA",
    "CA-ON"
  ],
  "timeRange": "7d",
  "maxJobs": 100
}' |
apify call jtpalms/pay-transparency-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jtpalms/pay-transparency-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/SFg5VcapfLHm5xRI0/builds/4eEcwk6s6gNkl5wnu/openapi.json
