# Ashby Jobs API: Job Postings from 2,168 Companies (`constanciodev/ashby-jobs-scraper`) Actor

Pull open job postings from any company on Ashby, 2,168 searchable by name, with compensation range, country, department, work model and seniority. Filter by keyword, location, remote and date. ATS jobs API for job boards, recruiting and sales signals. No login, no proxy, pay per job.

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

## Pricing

from $1.10 / 1,000 job postings

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

## Ashby Jobs API: job postings from 2,168 companies

**Monitor open jobs from 2,168 companies on Ashby, with salary range, country, department and
seniority.** Paste a job board URL, a board slug or just a company name (OpenAI, Snowflake, Airwallex, Harvey and Mistral AI...), add a
keyword or a location, and receive title, full description, posting date, location, work model,
pay range and seniority for each job. You pay only for the jobs you receive.

Built by **Constancio Dev**, a small engineering studio focused on data pipelines and B2B
automation. [constanciodev.com.br](https://constanciodev.com.br)

### What you get

- **2,168 companies searchable by name.** The built-in index has **2,168 validated Ashby
  boards** (checked against the public Ashby API on 22/10/2026). Type a company name, paste a
  board URL such as `https://jobs.ashbyhq.com/openai` or use the slug (`openai`).
- **Clean, structured fields.** Title, full description as plain text, publication date,
  location, ISO country code, US or Brazilian state, department, employment type, salary
  range and currency, seniority and years of experience when the posting states them.
- **Filters that save money.** Keywords (title), locations, remote only and posted within the last
  N days run before delivery, so jobs you filter out cost nothing.
- **No login, no browser, no proxy.** It reads the same public Ashby job board API that careers
  pages use, with 512 MB of memory.
- **Salary beyond the structured field.** When the structured range is missing, the Actor parses
  the description (USD, EUR, GBP, CAD, BRL and 30 other currencies).

### Example output

One dataset item per job. Real item from a local test run on 22/10/2026 (description shortened,
a few fields omitted):

```json
{
  "id": "harvey:04e17f81-d0a7-4f83-8526-ec4c9532ddcc",
  "title": "Senior Software Engineer, Frontend",
  "company": "Harvey",
  "company_slug": "harvey",
  "url": "https://jobs.ashbyhq.com/harvey/04e17f81-d0a7-4f83-8526-ec4c9532ddcc",
  "location": "San Francisco",
  "country": "US",
  "state": null,
  "work_model": "hybrid",
  "employment_type": "Full-time",
  "department": "Engineering",
  "posted_at": "2024-03-08T01:46:09.108000+00:00",
  "salary_min": 200000,
  "salary_max": 260000,
  "salary_currency": "USD",
  "salary_period": "year",
  "seniority": "senior",
  "years_experience": null,
  "description": "Why Harvey\n\nAt Harvey, we're transforming how legal and professional services operate. ..."
}
```

The real item also has `job_id`, `board_url` and `scraped_at`. A field the
posting does not support is `null`, never guessed. Export the dataset as JSON, CSV, Excel or
through the Apify API.

| Field | Meaning |
|---|---|
| `id` | Board slug plus Ashby job id. Stable across runs, good for deduplication. |
| `company`, `company_slug`, `board_url` | Who is hiring and where the job came from. |
| `url` | Public job page. |
| `location`, `country`, `state` | Location as published, ISO country code, US or Brazilian state. |
| `work_model` | `remote`, `hybrid` or `onsite`, as Ashby publishes it in `workplaceType` (or `isRemote`). |
| `employment_type` | Employment type, for example `Full-time` or `Contract`. |
| `department` | Department or team. |
| `posted_at` | Publication date (ISO 8601). |
| `salary_min`, `salary_max`, `salary_currency`, `salary_period` | Ashby compensation range when the employer publishes it, otherwise parsed from the description. |
| `seniority`, `years_experience` | From the title and the description. |
| `description` | Full description as plain text. |

### Input examples

**1. Fresh engineering jobs for a job board or newsletter**

```json
{
  "companies": ["OpenAI", "Snowflake", "Harvey"],
  "keywords": ["engineer", "data"],
  "locations": ["United States", "Remote"],
  "postedWithinDays": 14,
  "maxItems": 200
}
```

**2. Remote jobs only, without the long descriptions**

```json
{
  "companies": ["https://jobs.ashbyhq.com/openai", "Harvey"],
  "remoteOnly": true,
  "includeDescription": false,
  "maxItems": 100
}
```

**3. Daily hiring signal for sales (schedule it once a day)**

```json
{
  "companies": ["OpenAI", "Snowflake", "Harvey"],
  "keywords": ["head of", "director", "account executive"],
  "postedWithinDays": 1,
  "includeDescription": false
}
```

#### Input reference

| Field | What it does |
|---|---|
| `companies` | Ashby board URLs, slugs like `openai`, or company names from the index. |
| `keywords` | Keep jobs whose title contains at least one of these words. Empty keeps every job. |
| `locations` | Keep jobs whose location contains one of these, or whose country matches (`Texas`, `Germany`, `US`). |
| `remoteOnly` | Keep only jobs whose work model Ashby publishes as remote. |
| `postedWithinDays` | Keep only jobs posted in the last N days. Jobs with no date are left out when set. |
| `maxItems` | Stop after this many jobs in total (default 50). This is also your cost cap. |
| `maxJobsPerCompany` | Jobs per board after the filters. 0 uses `maxItems`. |
| `includeDescription` | Include the full description as plain text (default: true). |

Where to find the slug: open the company's careers page and click any job. If the address (or the
"Apply" link) goes to `jobs.ashbyhq.com/<slug>`, the part right after the host is the slug.

### Pricing

Pay per event: a price per job delivered to the dataset, which depends on your Apify plan, plus
$0.00005 per GB of memory when the run starts.

| Apify plan | Price per 1,000 jobs |
|---|---|
| Free | $1.80 |
| Starter (Bronze) | $1.60 |
| Scale (Silver) | $1.10 |
| Business (Gold) and above | $1.10 |

Jobs removed by your filters cost nothing. `maxItems` caps the cost of every run (default 50),
and a run also stops when it reaches the maximum cost per run you set in Apify.

### FAQ

**Is it allowed to collect Ashby job postings?** The Actor only reads job postings that
companies publish openly through Ashby's public job board API, without login, and respects
`robots.txt`. Check the terms that apply to your own use of the data.

**How do I get only new jobs every day?** Schedule the Actor with `postedWithinDays: 1` and your
keywords. This Actor has no monitor mode that remembers earlier runs; the ATS Jobs API Actor has
one (see below).

**A company name is not found. What now?** Paste the board URL or the slug instead. The log lists
every input that could not be read or has no public board, and the run continues with the rest.

**Can I get jobs from other ATS platforms?** Yes. See the other Actors by
[Constancio Dev](https://apify.com/constanciodev): [Greenhouse](https://apify.com/constanciodev/greenhouse-jobs-scraper), [Lever](https://apify.com/constanciodev/lever-jobs-scraper) and [Workday](https://apify.com/constanciodev/workday-jobs-scraper), and
[ATS Jobs API](https://apify.com/constanciodev/ats-jobs-worldwide), which covers all of them in
one output format, with seniority, area and remote-from-Brazil filters and a monitor mode.

**Something is wrong or missing?** Open an issue on the Actor's Issues tab. It is read and
answered, usually within a day.

### Limits

- **Only public boards.** Jobs that a company keeps off its public Ashby board are not covered.
  The index is a snapshot of 22/10/2026; a company that moved to another ATS shows up as a failure
  line in the log, and the run continues with the rest.
- **Work model depends on the employer.** `work_model` comes from the
  `workplaceType` field, which companies do not always fill. A job can
  stay listed for a long time: check `posted_at`.
- **Seniority is read from the title** (and from the years of experience in the description when
  the title has no level). When neither says it, it is `null`. This Actor does not classify area
  or remote-from-Brazil; the ATS Jobs API Actor does.
- **Salary only when it is written,** in the structured field or in the description text. Many
  postings have none.
- **No contact fields.** The output has no recruiter name, e-mail or phone field.
- **Polite crawler.** It identifies itself, respects `robots.txt` and paces its requests.

# Actor input Schema

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

Ashby job board URLs such as https://jobs.ashbyhq.com/openai, the board slug 'openai', or a company name from the built-in index of validated boards ('OpenAI', 'Snowflake'). A name that is not in the index is reported in the log; paste the board URL instead.

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

Keep jobs whose title contains at least one of these words (case and accents ignored). Empty keeps every job.

## `locations` (type: `array`):

Keep jobs whose location contains one of these, or whose country matches: 'Texas', 'Germany', 'US', 'Remote'. Empty keeps every location.

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

Keep only jobs whose work model Ashby publishes as remote.

## `postedWithinDays` (type: `integer`):

Keep only jobs posted in the last N days. Jobs with no date are left out when this is set. Empty or 0 keeps every date.

## `maxItems` (type: `integer`):

Stop after this many jobs across all companies. You pay per job delivered, so this is also your cost cap.

## `maxJobsPerCompany` (type: `integer`):

Jobs per board after the filters, in the order the board lists them. 0 uses the total limit.

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

Turn off for a smaller dataset with only the structured fields.

## Actor input object example

```json
{
  "companies": [
    "https://jobs.ashbyhq.com/openai"
  ],
  "remoteOnly": false,
  "maxItems": 20,
  "maxJobsPerCompany": 0,
  "includeDescription": true
}
```

# Actor output Schema

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

Every job posting delivered in this run, as dataset items.

# 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 = {
    "companies": [
        "https://jobs.ashbyhq.com/openai"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("constanciodev/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 = {
    "companies": ["https://jobs.ashbyhq.com/openai"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("constanciodev/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 '{
  "companies": [
    "https://jobs.ashbyhq.com/openai"
  ],
  "maxItems": 20
}' |
apify call constanciodev/ashby-jobs-scraper --silent --output-dataset

```

## MCP server setup

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