# Breezy HR Jobs Monitor & Scraper (`cliqtomedia/breezy-jobs-monitor-scraper`) Actor

Read public Breezy HR job boards with descriptions, salary and apply links. Track new, changed and removed jobs across complete scans. Export JSON or CSV.

- **URL**: https://apify.com/cliqtomedia/breezy-jobs-monitor-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Stats:** 2 total users, 1 monthly users, 90.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 current job saveds

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?

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

Read public Breezy HR jobs from company career boards. Get descriptions, salary data and job links in JSON or CSV. Turn on monitoring to see new, changed and removed jobs after a full scan. Pay $0.0018 per saved current job, plus $0.06 per run.

Add a `careerUrls` list. The default saves up to 10 current jobs. A limit or a source error gives an explicit status in **Board status**. Check this status before using the data.

![Breezy HR Jobs Monitor & Scraper: public input, structured results and supported export](https://api.apify.com/v2/key-value-stores/6m6FkFzsAqfzXUc25/records/readme-hero-20261010.png)

### Table of contents

- [What it does](#what-it-does)
- [Data](#data)
- [Quick start](#quick-start)
- [Input](#input)
- [Input examples](#input-examples)
- [Output example](#output-example)
- [Output fields](#output-fields)
- [Pricing](#pricing)
- [Use cases](#use-cases)
- [Monitoring](#monitoring)
- [API and integrations](#api-and-integrations)
- [Limits and partial results](#limits-and-partial-results)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related Actors](#related-actors)
- [Support](#support)

### What it does

The Actor reads known public Breezy boards at `https://company.breezy.hr/`. It gets the public job feed and reads structured job data on detail pages. If a page has no structured block, it reads the visible job description and feed metadata. You can add up to 4 board URLs in one run.

It returns current jobs with one fixed set of fields. Monitoring compares successful full scans. Custom career domains and a search across all Breezy companies are not supported. Use the company's Breezy URL.

### Data

Each row has a job ID, title, company, locations, employment types, date, clean description and public job URL. Salary is included when the employer provides structured salary data. `salary_text` keeps the feed's original salary text.

Missing employer data stays `null`. A public remote marker may also appear on hybrid roles. Check `workplace` and the description before treating a job as fully remote.

### Quick start

1. Open **Input**.
2. Add `https://the-san-francisco-standard.breezy.hr/` to `careerUrls`.
3. Keep `maxResults: 10` and `includeDescription: true`.
4. Click **Start**.
5. Open **Current jobs**. Check `job_id`, `title` and `salary`.
6. Open **Board status**. A full scan has `status: "complete"`.

```json
{"careerUrls":["https://the-san-francisco-standard.breezy.hr/"],"maxResults":10}
```

The board had 6 jobs when tested. Jobs may be added or closed later.

### Input

`careerUrls` is required. Other fields are optional. Unknown fields, wrong types and values outside these limits fail before source requests. Duplicate boards are read once. A public `/p/...` job URL selects its whole board.

| Key | Type | Default | Range / example | Effect and advice |
| --- | --- | --- | --- | --- |
| `careerUrls` | string array | Required; UI suggests Standard | 1–4 HTTPS Breezy roots | Add known boards. No credentials, custom domains or nonstandard ports. |
| `query` | string | `""` | Up to 200 characters; `"Python"` | All words must occur in title, company, full description, type or location. Leave empty for all jobs. |
| `location` | string | `""` | Up to 200 characters; `"US"` | Case-insensitive part of structured location. Leave empty for all places. |
| `remoteOnly` | boolean | `false` | `true` / `false` | Require the employer's `TELECOMMUTE` marker. This may include hybrid work. |
| `includeDescription` | boolean | `true` | `true` / `false` | Return plain description text. Detail pages are still read for other fields and filters. |
| `maxResults` | integer | `10` | 1–50 | Total saved current jobs across boards. Raise it for a full monitoring scan. |
| `monitor` | boolean | `false` | `true` / `false` | Compare with the last complete scan of the same stream and settings. |
| `monitorKey` | string | `"default"` | 1–64 letters, digits, `_` or `-` | Give each workflow its own name, such as `"weekly-tech"`. |

Filters work together: a job must pass every filter. `query` uses the full description even when `includeDescription` is false. No matching jobs is a valid complete empty result when every source read succeeds. Detail errors with active filters make the run partial; unknown values are not treated as confident filter results.

### Input examples

#### Several companies

```json
{"careerUrls":["https://plat4mation.breezy.hr/","https://the-san-francisco-standard.breezy.hr/"],"maxResults":50}
```

This collects current jobs from both boards. Order follows the feed, which can differ from the order shown on the career page.

#### Remote matching jobs

```json
{"careerUrls":["https://the-san-francisco-standard.breezy.hr/"],"remoteOnly":true,"maxResults":50,"monitor":true,"monitorKey":"remote-news"}
```

A complete first run sets the baseline. Later complete runs compare the same filtered set.

### Output example

This is a trimmed real row from the Quick start board. The omitted fields are described below.

```json
{
  "job_id": "48d4a6862c5d",
  "title": "AI & Work Reporter, Charter",
  "company": "The San Francisco Standard",
  "date_posted": "2026-06-02",
  "remote": true,
  "workplace": "hybrid",
  "salary": {"currency":"USD","unit":"YEAR","min":90000,"max":130000,"value":null},
  "salary_text": "$90,000 – $130,000 / year",
  "url": "https://the-san-francisco-standard.breezy.hr/p/48d4a6862c5d-ai-work-reporter-charter",
  "row_status": "complete",
  "change_type": "untracked"
}
```

### Output fields

All listed top-level fields are present in every saved row. `null` means the source did not provide the value, description was turned off, or detail data could not be read. Arrays may be empty.

| Field | Type / null | Example | Meaning |
| --- | --- | --- | --- |
| `job_id` | string | `48d4a6862c5d` | Feed job ID. Use board + ID across companies. |
| `title` | string | `AI & Work Reporter, Charter` | Detail title, or feed title on a partial row. |
| `company` | string / null | `The San Francisco Standard` | Employer name. |
| `company_url` | string / null | `https://the-san-francisco-standard.breezy.hr` | Public employer URL from detail, or board root. |
| `company_logo` | string / null | `null` | Public logo URL. |
| `description` | string / null | `AI & Work Reporter ...` | HTML converted to clean text. |
| `employment_types` | string array | `["FULL_TIME"]` | Values from structured job data. |
| `date_posted` | string / null | `2026-06-02` | Detail posting date. |
| `valid_through` | string / null | `null` | Employer's closing date, if provided. |
| `locations` | object array | `[{"city":"San Francisco",...}]` | Structured locations; see fields below. |
| `applicant_locations` | string array | `["US"]` | Published applicant country requirements. |
| `location_text` | string | `San Francisco, CA, US` | Joined city, region and country values. May be empty. |
| `remote` | boolean | `true` | Detail has `TELECOMMUTE`, or HTML fallback uses the feed remote flag. Not a guarantee of fully remote work. |
| `salary` | object / null | `{"currency":"USD",...}` | Structured salary; see fields below. |
| `url` | string | `https://...breezy.hr/p/...` | Public job and application page. |
| `source` | string | `breezyhr` | Source label. |
| `career_site_url` | string | `https://...breezy.hr/` | Board root used for this row. |
| `scraped_at` | string | `2026-10-03T00:00:00Z` | Scan start time in UTC. |
| `department` | string / null | `null` | Feed department. |
| `salary_text` | string / null | `$90,000 – $130,000 / year` | Original feed salary text. No guessed numeric parsing. |
| `feed_published_at` | string / null | `2026-07-06T15:54:14.718Z` | Feed date; it can differ from detail date. |
| `feed_remote` | boolean | `true` | Feed's remote flag. |
| `workplace` | string / null | `hybrid` | Feed's work model label value. |
| `detail_source` | string | `jsonld` / `public_html` / `unavailable` | Source of detail data. HTML fallback keeps missing structured dates and salary null. |
| `row_status` | string | `complete` / `partial` | Whether detail data was read. A partial row may have missing detail fields. |
| `change_type` | string | `new` | `untracked`, `new`, `changed` or `unchanged`. |
| `first_seen_at` | string / null | `2026-10-03T00:00:00Z` | First full monitored scan that saw the job; null without monitoring. |

Each `locations` item has six string-or-null fields: `name` (place name, e.g. null), `street` (street address, e.g. null), `city` (e.g. San Francisco), `region` (e.g. CA), `postal_code` (e.g. null) and `country` (e.g. US).

A non-null `salary` has `currency` (string/null, e.g. USD), `unit` (string/null, e.g. YEAR), `min` (number/null, e.g. 90000), `max` (number/null, e.g. 130000) and `value` (number/null, e.g. null). Values keep the published currency and period.

#### Other output surfaces

| Surface | Shape | What to check |
| --- | --- | --- |
| Dataset | One row per unique matching current job | Export or read jobs. Removed jobs are not Dataset rows. |
| KVS `OUTPUT` | Object: `status`, `rows`, `boards`, `changes`, `error`, `sourceCommit`, `schema_version` | Check completeness before updating your job board. |
| KVS `RUN_SUMMARY` | OUTPUT plus `requests`, `retries`, `durationMs`, `startedAt` | Check work and timing counters. |
| KVS `CHANGES` | `new`, `changed`, `removed`, `snapshot_updated` | `new`/`changed` are ID arrays; `removed` is an array of `{job_id,url}`. |

Each board report has `board`, `status`, `available`, `matched`, `emitted`, `detail_errors` and `reason`. Status is `complete`, `partial`, `not_found` or `error`. `reason` is a stable code or null. Overall `status` is `complete`, `partial` or `error`. Counters are integers. `error` is null or a stable failure code. `snapshot_updated` is boolean. `sourceCommit` identifies the code version. `schema_version` is 1.

### Pricing

The price is **$0.0018 per saved current job**, plus **$0.06 per run** at the supported 256–512 MB memory range. The price is the same on all Apify plans. New, changed and unchanged saved jobs use the same result price. Removed jobs in `CHANGES` have no extra charge. The $0.06 start charge also applies to empty, filtered and failed runs. A full filtered scan still reads job pages even when it saves no jobs.

| Saved jobs | Runs within the 50-row limit | Price |
| --- | --- | ---: |
| 10 | 1 | $0.07800 |
| 50 | 1 | $0.15000 |
| 100 | At least 2 separate runs | $0.30000 |
| 1,000 | At least 20 separate runs | $3.00000 |

The last two rows are price calculations for separate input sets, not a claim that one run can save 100 or 1,000 jobs. Source errors, empty runs and different batch sizes change the number of starts. Do not repeat the same set to obtain extra unique jobs.

Set Apify's maximum cost per run to at least $0.06 to cover the start event. Use $0.15 for up to 50 saved jobs, or $0.20 with room to spare. A $0.06360 cap allows the start and at most two rows. Use `maxResults` and the price cap together. A price cap can stop a scan before it is complete. Check `OUTPUT.status` and `snapshot_updated`. The 50-row acceptance run took about 53 seconds at 256 MB; source speed can change.

### Use cases

- Build a job board from known companies. Use `job_id` and `career_site_url` to update records.
- Follow hiring changes at target accounts. Read `CHANGES` after each complete monitored run.
- Collect research data. Export titles, dates, locations and disclosed salary values.

### Monitoring

Set `monitor: true` and a `monitorKey`. Use enough `maxResults` for every matching job. The first full scan marks jobs `new`. Later scans mark each current job `changed` or `unchanged`. Changes compare content, including salary and description, but ignore scrape time.

The Actor stores a snapshot in the account's named key-value store `breezy-jobs-monitor-state`. Changing boards, filters or `includeDescription` starts a separate baseline. The stream name alone does not connect different configurations. Deleting this storage loses history.

Only a complete scan replaces the baseline or reports removed jobs. Capped, failed and cancelled scans cannot prove removals. Their `new` and `changed` lists describe only the rows seen; do not use them as a full snapshot. Run each stream sequentially. Overlapping runs of the same stream are not supported.

To repeat scans, you can create an Apify schedule yourself. No schedule is created by the Actor.

### API and integrations

Start with the same JSON input through the [Apify API](https://docs.apify.com/api/v2). Read the returned default Dataset and KVS IDs. The output links in Console show **Current jobs**, **Board status**, **Run summary** and **Job changes**.

Export Dataset rows as JSON, CSV or Excel. In n8n, Make or your own code, use `career_site_url` + `job_id` as the record key. Read `OUTPUT.status` before replacing records. An AI agent using [Apify MCP](https://docs.apify.com/platform/integrations/mcp) can pass the same input and read the same results. These are platform integration paths; no external integration is configured by this Actor.

### Limits and partial results

- Up to 4 input boards and 50 saved current jobs per run. The feed itself may contain more jobs.
- Supported Cloud memory: 256 or 512 MB. The recommended timeout is 210 seconds; the 300-second Store test and larger finite positive timeouts are supported. Unsupported memory or an unlimited timeout is rejected before source work. Each request has a 15-second timeout. The Actor stops source work after 180 seconds or before its Cloud timeout.
- At most 200 source HTTP attempts, including retries. Feed body limit: 5 MiB. Detail body limit: 2 MiB. Total received source body data is limited to 16 MiB, including unsuccessful responses and retries. SOURCE_BYTE_LIMIT stops further reads; the scan cannot update its monitoring baseline.
- Only public HTTPS Breezy subdomains are allowed. Private network addresses and redirects are rejected.
- A blocked feed, invalid JSON or changed source format is an error, not an empty board.
- A valid empty feed or no filter matches is `complete` with zero rows.
- A missing board is `not_found`. If all boards fail or are missing, the platform run fails. Mixed results are `partial`.
- A detail error can save a partial metadata row without active filters. With active filters, an unreadable detail is skipped and the scan stays partial.
- No private applicant records, employer login, global company discovery or custom domain support.
- Dataset writes and monitoring snapshots are separate operations. A storage failure stops the scan. A restarted or resurrected run with an existing Dataset stops with `RESUME_NOT_SUPPORTED`. Start a new run to avoid mixing data from different scans. Do not overlap monitoring runs.

### Troubleshooting

**No rows:** Open Board status. `complete` can mean an empty board or no filter matches. Remove filters and check the public board.

**`not_found`:** Check the Breezy subdomain. An employer may have moved to another platform.

**`partial`:** Check the board's `reason`. `RESULT_LIMIT` means you need a larger result limit, up to 50. A source or detail error may need a later retry.

**No removed jobs:** Check `snapshot_updated`. The scan must be complete. Check that `monitorKey`, boards and filters are unchanged.

**Input error:** Use the exact keys above and an HTTPS Breezy root. Do not paste employer dashboard links.

### FAQ

#### Do I need a Breezy account?

No. The Actor reads public employer pages. It is an independent scraper, not a Breezy product.

#### Why are some values null?

The employer may not publish them. Check `row_status` for a detail read failure. The Actor does not estimate salary or dates.

#### Are all remote jobs fully remote?

No. The public marker can also appear on hybrid roles. Check `workplace`, applicant locations and the description.

#### Can this replace another Breezy scraper?

The core field names follow a public career-site scraper. Description spacing, location text and result order can differ. This Actor adds status and monitoring fields. Check your mapping before switching.

### Related Actors

- [Greenhouse Jobs Monitor & Scraper](https://apify.com/cliqtomedia/greenhouse-jobs-monitor-scraper) — collect known Greenhouse boards.
- [Lever Jobs Scraper](https://apify.com/cliqtomedia/lever-jobs-scraper) — collect known Lever boards.

### Support

Open an issue on the Actor page. Include the run ID, public Breezy board URL and the error code. Keep tokens and private data out of your message.

# Actor input Schema

## `careerUrls` (type: `array`):

Add 1–4 HTTPS Breezy board roots or public /p/ job URLs. Duplicate boards are read once. Custom domains are not supported.

## `query` (type: `string`):

All words must appear in title, company, full description, type or location. Empty means all jobs.

## `location` (type: `string`):

Case-insensitive text in structured location. Empty means all locations.

## `remoteOnly` (type: `boolean`):

Keep jobs with the public TELECOMMUTE marker. Some hybrid jobs also have this marker. Check workplace.

## `includeDescription` (type: `boolean`):

Return clean plain text. Detail pages are still read for salary, dates and filters.

## `maxResults` (type: `integer`):

Total saved current jobs, 1–50. Default 10. A capped scan is partial and cannot update the monitoring snapshot.

## `monitor` (type: `boolean`):

Compare full matching scans. First full run sets the baseline. CHANGES lists removed jobs. Use sequential runs.

## `monitorKey` (type: `string`):

Use a separate name for each monitoring workflow. Configuration changes create a new baseline.

## Actor input object example

```json
{
  "careerUrls": [
    "https://the-san-francisco-standard.breezy.hr/"
  ],
  "query": "",
  "location": "",
  "remoteOnly": false,
  "includeDescription": true,
  "maxResults": 10,
  "monitor": false,
  "monitorKey": "default"
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `output` (type: `string`):

No description

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

No description

## `changes` (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 = {
    "careerUrls": [
        "https://the-san-francisco-standard.breezy.hr/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/breezy-jobs-monitor-scraper").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 = { "careerUrls": ["https://the-san-francisco-standard.breezy.hr/"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/breezy-jobs-monitor-scraper").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 '{
  "careerUrls": [
    "https://the-san-francisco-standard.breezy.hr/"
  ]
}' |
apify call cliqtomedia/breezy-jobs-monitor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/breezy-jobs-monitor-scraper"
        }
    }
}
```

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/BANj9ZRd8K5sihyOn/builds/BarUbfgyFaDGSLR8s/openapi.json
