# Greenhouse Job Listing Verifier — Source Evidence (`winstonvale/source-backed-greenhouse-job-verifier`) Actor

Check stored Greenhouse board tokens and job IDs against complete official board responses. Explicit unknown states, fingerprints, and no applicant data.

- **URL**: https://apify.com/winstonvale/source-backed-greenhouse-job-verifier.md
- **Developed by:** [Winston Vale](https://apify.com/winstonvale) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 listing-checks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Winston Source-backed Greenhouse Job Verifier

Check customer-supplied Greenhouse job IDs against one complete official board
response per company. The Actor is designed for job-board operators and data
workflows that already store a Greenhouse board token and posting ID and need a
fail-closed availability check without reconstructing job URLs.

This is an unofficial integration maintained by Winston. It is not affiliated
with, sponsored by, or endorsed by Greenhouse. It reads only Greenhouse's public
GET-only Job Board API and never collects applications, resumes, candidate data,
or login-protected information.

### Quick start

Supply one through 500 records across at most 25 distinct boards. Each record
may contain `boardToken` and `jobId`, or an official Greenhouse job `url`.
`inputId` is your stable reference.

```json
{
  "listings": [
    {
      "inputId": "saved-role-42",
      "boardToken": "webflow",
      "jobId": "7951430"
    },
    {
      "inputId": "example-missing-role",
      "url": "https://job-boards.greenhouse.io/webflow/jobs/9999999999999999999"
    }
  ]
}
```

Repeated inputs remain separate results, while all records for one board share
one official board fetch. The result order matches the input order.

The Actor can be run from Apify Console, the public saved task, or Apify's API
and MCP integrations. It is currently eligible for Apify's agentic payments, so
compatible agents can discover, run, and pay for it through Apify-supported
agentic protocols without a separate Winston account or credential. This is a
platform access route, not evidence that an external agent has paid or run it.

### Status contract

| Status | Meaning |
| --- | --- |
| `PUBLISHED` | The job ID was positively observed in a successfully parsed complete official board response. |
| `NOT_PRESENT_IN_COMPLETE_BOARD` | The job ID was absent from that complete response. This does not establish why. |
| `UNKNOWN` | Retrieval failed, the response was incomplete, or its schema was inconsistent. No absence claim is made. |
| `UNSUPPORTED` | The input is outside the documented Greenhouse contract. |

Every row includes the input identifier, resolved official source, observation
time, board-response SHA-256 fingerprint, status, and reason. A matched job also
includes a deterministic SHA-256 fingerprint of the complete returned job
object. These hashes identify the observed bytes/content; they are not signatures
from Greenhouse and do not prove historical state.

Absence never means a role was filled, a hiring freeze exists, or an employer
published a deceptive listing. A removal claim requires a prior `PUBLISHED`
observation and a later `NOT_PRESENT_IN_COMPLETE_BOARD` observation for the same
board and job ID; this Actor does not maintain that history for you.

### Best fit and alternatives

This Actor is best suited to a Greenhouse-only job-board workflow that already
stores a stable `inputId`, `boardToken`, and `jobId` and periodically checks a
selected list before retaining or manually reviewing records. It accepts those
keys directly, preserves `inputId` for the join, reuses one complete board read
within a run, and returns source and matched-job fingerprints.

At the current provisional price, 50 resolved checks cost **USD 0.105 per run**
or **USD 0.420 for four unchanged weekly rechecks**. The current
[ClearSignal Job Posting Verifier](https://apify.com/clearsignaltools/job-posting-verifier)
supports four ATS providers and an optional review report, but requires posting
URLs and costs USD 0.25005 per 50-result run or USD 1.00020 for four weekly
runs. ClearSignal is cheaper for a single resolved check because its start fee
is lower; Winston becomes cheaper from two resolved checks at current prices.

Direct use of Greenhouse's public unauthenticated
[Job Board API](https://docs.greenhouse.io/job-board.html) has no provider fee
and is the strongest alternative when you already operate code for board
fetching, completeness/schema checks, ID joins, scheduling, evidence retention,
and safe failure handling. Neither paid Actor maintains history or avoids its
result charge when an unchanged posting is checked again. Store listings and
user counts do not prove paid demand.

### Pricing

The current provisional price is **USD 0.005 per run plus USD 0.002 per resolved
check** (`PUBLISHED` or `NOT_PRESENT_IN_COMPLETE_BOARD`). `UNKNOWN` and
`UNSUPPORTED` results carry no `listing-check` result fee, but the run-start fee
still applies. With no volume discounts, the complete event charge is USD 0.007
for one resolved check and USD 1.005 for the 500-check run maximum.

Apify platform usage is included in those event prices rather than added to the
buyer bill. The launch configuration disables the automatic
`apify-default-dataset-item` event to prevent a second per-row charge. The Actor
is monetized at these displayed prices. They remain provisional during the
fourteen-day commercial experiment. Promotional use, owner tests, platform
tests, and platform credits are not evidence of customer willingness to pay.

Cloud acceptance at 256 MB measured USD 0.00297 of platform usage for a
500-result/two-board run and USD 0.00029 for a 25-board/25-result run. Those
measurements support the launch price, but customer margin and accessible cash
remain unproved until paid external use and payout readiness exist. The Actor
rejects a monetized configuration that lacks its displayed `listing-check`
price or would add an automatic dataset-item fee to failure rows.

### Limits and failure handling

- Greenhouse only: `job-boards.greenhouse.io` and legacy
  `boards.greenhouse.io`, or explicit board token plus positive numeric job ID.
- At most 500 inputs, 25 distinct boards, and four concurrent boards per run.
- One documented list-jobs request per distinct board, with at most one bounded
  retry for transport errors, HTTP 429, and transient HTTP 5xx responses.
- Ten-second request timeout and 2 MB per-response ceiling. The distinct-board
  bound limits successful source response work to 50 MB per run, while boards
  are parsed and released incrementally rather than retained as a batch.
- A complete response requires a JSON object with `jobs`, `meta.total`, a count
  match, unique positive job IDs, and documented core job fields.
- HTTP 404, redirects, timeouts, truncated responses, count mismatches, duplicate
  IDs, malformed JSON, and schema changes yield `UNKNOWN`, never absence.
- Ordinary execution is deterministic and has no model dependency, browser,
  proxy, secret, or background service.

Use the Actor's Issues tab for support. Include a public example board/job ID and
the Apify run ID, and never post credentials or applicant information.

### Local reproducible run

From the repository root:

```bash
python3 -m products.greenhouse_job_verifier.cli input.json
python3 -m unittest \
  tests.test_greenhouse_job_verifier \
  tests.test_greenhouse_actor_adapter -v
```

The CLI prints the same batch contract without Apify storage or billing.

# Actor input Schema

## `listings` (type: `array`):

Each item needs inputId and either url, or boardToken plus jobId. Unsupported items produce an UNSUPPORTED result.

## `maxConcurrency` (type: `integer`):

Distinct official boards fetched at once, capped at four. Repeated listings from one board share a single fetch.

## Actor input object example

```json
{
  "listings": [
    {
      "inputId": "example-role",
      "boardToken": "webflow",
      "jobId": "7951430"
    }
  ],
  "maxConcurrency": 4
}
```

# Actor output Schema

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

No description

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

No description

# 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 = {
    "listings": [
        {
            "inputId": "example-role",
            "boardToken": "webflow",
            "jobId": "7951430"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("winstonvale/source-backed-greenhouse-job-verifier").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 = { "listings": [{
            "inputId": "example-role",
            "boardToken": "webflow",
            "jobId": "7951430",
        }] }

# Run the Actor and wait for it to finish
run = client.actor("winstonvale/source-backed-greenhouse-job-verifier").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 '{
  "listings": [
    {
      "inputId": "example-role",
      "boardToken": "webflow",
      "jobId": "7951430"
    }
  ]
}' |
apify call winstonvale/source-backed-greenhouse-job-verifier --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,winstonvale/source-backed-greenhouse-job-verifier"
        }
    }
}

```

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/x6w3HWbjVsVYRg76d/builds/EobVwB6U0f9iP0IBE/openapi.json
