# Ashby Jobs Scraper (`cliqtomedia/ashby-jobs-scraper`) Actor

Get current public jobs from Ashby-hosted career boards with descriptions, locations, filters and published compensation.

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

## Pricing

$0.75 / 1,000 useful job rows

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

## Ashby Jobs Scraper

Ashby Jobs Scraper gets current public jobs from one or more Ashby-hosted
career boards. Add a board slug, a board URL, or an exact public job URL. The
Actor returns one JSON row for each job it saves.

This is an independent tool. It is not affiliated with, endorsed by, or
sponsored by Ashby, Inc. It reads only public job-board data.

### What you get

Each job row can include:

- job title, department and team;
- primary and secondary locations;
- remote, workplace and employment type;
- published time, job URL and apply URL;
- the source HTML and plain-text description;
- published compensation, when the employer provides it.

The Actor keeps source values and does not guess missing values. Missing salary
or location data stays empty.

Each run also writes a run summary (`RUN_SUMMARY`). The summary shows the final
result for every input. It separates a valid empty board, a missing job, an
invalid input and a technical error.

### How to use it

1. Choose `all` to read current jobs from board slugs or board URLs.
2. Choose `exact` to read one or more canonical Ashby job URLs.
3. Add up to 50 board or job URL values.
4. Turn on compensation if you want published salary bands.
5. Add filters when you want only matching titles, locations, teams or dates.
6. Start the run and open the Dataset for job rows.

The default input reads the `ramp` board. It is a small, stable example for a
quick first run. You can also use `linear`, `notion`, or another known Ashby
board slug.

### Charging

Apify charges for job rows saved to the Dataset. Invalid inputs, empty boards
and technical failures save no job rows. Repeated board inputs are fetched once
and repeated source jobs appear once.

The active Apify pricing page is the source for the current rate. The rate can
change independently from this README.

### Limits and source behavior

- The Actor accepts only HTTPS URLs on `jobs.ashbyhq.com`.
- The Actor does not discover every Ashby company.
- The Actor does not read private workspaces or submit applications.
- The Actor does not crawl arbitrary URLs, use a browser, or enrich people.
- The input schema has a safety cap of 11,446 output rows.
- The largest checked live input used 50 boards and returned 11,446 unique
  rows. A larger source response is stopped at this safety limit.
- A source response above the safe response size is reported as an error.

The source is live and can change. A run is a current snapshot, not a history
of every job ever posted. Ashby may remove a public job or change its public
posting endpoint.

### When a run is incomplete

Open `RUN_SUMMARY` when the Dataset is empty or partial. Look for the input
status and error code. A `result_limit` status means a safety limit stopped
more rows. A `not_found` status means the board or job was not found. An
`upstream_error` or `invalid_response` status means the public source could
not be read safely.

### Need help?

Include the Apify Run ID, the input you used, the number of Dataset rows and
the related `RUN_SUMMARY` entry. Do not send account tokens or cookies.

The full field contract is in [docs/SPEC.md](docs/SPEC.md) and
[docs/OUTPUT-CONTRACT.md](docs/OUTPUT-CONTRACT.md).

# Changelog

This Actor's version history is a separate document: https://apify.com/cliqtomedia/ashby-jobs-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Use all for board snapshots or exact for hosted job URLs.

## `boards` (type: `array`):

Enter Ashby board slugs/URLs in all mode, or canonical hosted job URLs in exact mode. Only jobs.ashbyhq.com is accepted.

## `includeCompensation` (type: `boolean`):

Ask Ashby's public endpoint for compensation fields when the employer publishes them.

## `includeUnlisted` (type: `boolean`):

All mode defaults to listed postings only. Exact mode may return a matching direct-only row.

## `filters` (type: `object`):

Filters are applied locally after the complete board response is fetched.

## `maxResultsPerBoard` (type: `integer`):

Optional limit on rows from each board. Applied after filters.

## `maxOutputItems` (type: `integer`):

Maximum number of job rows saved in one run. Empty inputs and errors do not create rows.

## `concurrency` (type: `integer`):

Maximum number of board requests sent at the same time.

## Actor input object example

```json
{
  "mode": "all",
  "boards": [
    "ramp",
    "https://jobs.ashbyhq.com/linear"
  ],
  "includeCompensation": true,
  "includeUnlisted": false,
  "filters": {},
  "maxOutputItems": 11446,
  "concurrency": 4
}
```

# Actor output Schema

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

One row per emitted public Ashby posting.

## `runSummary` (type: `string`):

The final result for each input in the default key-value store.

# 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 = {
    "boards": [
        "ramp"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/ashby-jobs-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 = { "boards": ["ramp"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/ashby-jobs-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 '{
  "boards": [
    "ramp"
  ]
}' |
apify call cliqtomedia/ashby-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/ashby-jobs-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/MW2vOd2xf2nMHOeZ3/builds/JHp3NAto5NIHK95fc/openapi.json
