# Ashby Jobs Scraper: Salary, Equity & New Jobs (`digital_influx/ashby-jobs-scraper`) Actor

Search open jobs across 3,300+ startups and tech companies on Ashby, or read any company’s Ashby job board: Ramp, Notion, OpenAI and more. Salary and pay ranges per location, equity, workplace, employment type, seniority, visa and full text. Only-new-jobs mode. No login.

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

## Pricing

from $2.00 / 1,000 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

## Ashby Jobs Scraper: Salary, Equity & New Jobs

Search **open jobs across 3,300+ startups and tech companies that hire through Ashby**, or read **any company's Ashby job board** in full: Ramp, Notion, OpenAI, Snowflake and thousands more. Every job comes as a clean row with title, location, country, workplace (remote, hybrid, on-site), employment type, **salary**, **pay ranges per location or level**, **equity**, **seniority**, **visa sponsorship**, the **exact posting date** and the full description.

It reads Ashby's public job posting API, the same data a company's careers page shows. That means:

- **No proxies, no headless browser, no login.** Nothing breaks when a careers page changes its design.
- **Two ways to run it.** Leave *Ashby job boards* empty to search every company in our Ashby directory by title, location and date. Or paste the boards you care about and get every open job from each.
- **Fast searches over thousands of companies.** A daily index of every open Ashby job picks the companies that have a matching job, and only those are read live. A search for a week of software engineer jobs read 48 of the 3,396 companies in about 25 seconds.
- **The pay the company set in Ashby, as data.** Salary ranges per tier ("SF/NYC", "Atlanta"), the summary Ashby shows ("$130K – $200K • Offers Equity • Offers Commission") and whether equity is offered. In 30 companies, 1,363 of 2,149 jobs had a salary and 906 offered equity.
- **Only new jobs.** Schedule it daily and get just the postings that are new since the last run, and pay only for those.

### What you can use it for

- **Job boards and newsletters:** fresh startup and tech roles, filtered by keyword, location, seniority, workplace and employment type.
- **Recruiters and talent teams:** follow competitors' and target accounts' openings every day with only-new mode.
- **Sales intelligence:** hiring is a buying signal. A startup opening five sales roles is growing its go-to-market team.
- **Compensation research:** compare salary ranges, equity and commission across startups, locations and levels.
- **AI agents:** plain JSON with plain-text descriptions, ready for an LLM. Agents can call this Actor through the Apify MCP server.

### Input

| Field | What it does |
|---|---|
| Job title keywords | Keep jobs whose title has any of these words. Whole-word match: `intern` does not match `internal`. |
| Exclude title keywords | Drop titles with these words, e.g. `manager`. |
| Locations | Keep jobs whose location, secondary locations or country code contain the text: `New York`, `Germany`, `DE`. A two-letter code matches as a whole word or the country code, so `US` does not match "Dusseldorf". `remote` also matches jobs flagged remote. |
| Remote only | Only jobs that offer a fully remote option, as the company set it in Ashby. |
| Posted within (days) | Only jobs published on Ashby in the last N days. |
| Seniority | Keep only these levels, read from the title: intern, entry, not stated (usually mid-level), senior, lead, director, executive. |
| Workplace type | Remote, hybrid or on-site, as the company set it in Ashby (88% of jobs say it), or not stated. |
| Employment type | Full-time, part-time, contract, temporary or internship: every Ashby job has one. |
| Description keywords / Exclude description keywords | Whole-word match on the full description: `Kubernetes`, `GDPR`; exclude `clearance`. |
| Only jobs that state a salary | The compensation the company set in Ashby, or a pay range written in the description. |
| Only jobs that offer visa sponsorship | The description says the company sponsors visas. Jobs that say nothing are dropped. |
| **Ashby job boards (optional)** | Empty: search the whole directory. Or the boards to read in full: the address (`jobs.ashbyhq.com/ramp`), a link to any job on it, or just the board name (`ramp`). Any public board works, in our directory or not. |
| Exclude companies | When searching the directory: skip these companies. |
| Max jobs | Newest first. Empty: 200 for a directory search, and every job (up to 5,000) when you give boards. |
| Max jobs per company | Newest first. Keeps one big employer from filling the results. |
| Job description | Plain text (default), HTML, both, or none. |
| Only new jobs (for scheduled runs) | Save only jobs that earlier runs of the same search or boards did not save. |
| Memory name | Optional: share one memory between tasks, or start over with a new name. |

Search the directory for sales jobs with their pay, posted in the last 14 days:

```json
{
  "keywords": ["account executive", "sales"],
  "postedWithinDays": 14,
  "onlyWithSalary": true,
  "maxJobs": 100
}
```

The 50 newest jobs of each of three companies (leave out *maxJobsPerCompany* for every job):

```json
{
  "boards": ["https://jobs.ashbyhq.com/ramp", "https://jobs.ashbyhq.com/notion", "openai"],
  "maxJobsPerCompany": 50
}
```

Daily monitoring of new remote engineering roles across the directory (schedule it in *Schedules*):

```json
{
  "keywords": ["engineer"],
  "workplaceTypes": ["remote"],
  "maxJobs": 200,
  "onlyNew": true
}
```

**How to find a company's Ashby board:** open the company's careers page and click on any job. If the address starts with `jobs.ashbyhq.com/`, the board name is the part after the slash (`jobs.ashbyhq.com/ramp` → `ramp`). Companies that show Ashby jobs on their own domain often link to that address from the **Apply** button.

### Output

One item per job. This one came from a directory search for account executives with a salary:

```json
{
  "id": "4919f9ef-73ce-4f9d-ae70-0c6856635d88",
  "platform": "ashby",
  "companySlug": "harperinsure",
  "company": "Harperinsure",
  "title": "Account Executive, Service",
  "department": "Growth",
  "team": "Growth",
  "location": "San Francisco",
  "locations": ["San Francisco", "New York", "Atlanta"],
  "country": "US",
  "remote": false,
  "workplaceType": "onsite",
  "employmentType": "Full time",
  "experienceLevel": null,
  "seniority": null,
  "postedAt": "2026-09-24T18:47:26.655Z",
  "updatedAt": null,
  "url": "https://jobs.ashbyhq.com/harperinsure/4919f9ef-73ce-4f9d-ae70-0c6856635d88",
  "applyUrl": "https://jobs.ashbyhq.com/harperinsure/4919f9ef-73ce-4f9d-ae70-0c6856635d88/application",
  "salary": { "min": 130000, "max": 200000, "currency": "USD", "period": "year", "text": "$130K - $200K", "source": "platform" },
  "payRanges": [
    { "title": "SF/NYC", "min": 150000, "max": 200000, "currency": "USD", "period": "year" },
    { "title": "Atlanta", "min": 130000, "max": 180000, "currency": "USD", "period": "year" }
  ],
  "compensationSummary": "$130K – $200K • Offers Equity • Offers Commission • Offers Bonus • Multiple Ranges",
  "offersEquity": true,
  "yearsOfExperience": null,
  "visaSponsorship": null,
  "descriptionText": "ACCOUNT EXECUTIVE, SERVICE\n\nHarper is an AI-native commercial insurance company in San Francisco...",
  "descriptionHtml": null,
  "scrapedAt": "2026-09-30T20:11:07.751Z"
}
```

Field notes:

- `companySlug` is the Ashby board name. `company` is the company name from our directory, or made from the board name when you give boards (Ashby's API sends no company name).
- `country` is an ISO 3166-1 alpha-2 code (`US`, `GB`, `DE`) from the address the company set in Ashby.
- `remote: true` means the job offers a fully remote option (Ashby's own flag). `workplaceType` is `remote`, `hybrid` or `onsite` as the company set it, or `null`.
- `salary` is the compensation the company set in Ashby, as numbers with its period (`source: "platform"`). With several tiers in one currency it spans them all, as Ashby's summary does. When Ashby has none, it is read from the description (`source: "description"`) only when it is clearly pay.
- `payRanges` are the salary ranges one by one, per tier, with the company's own label (a location or a level) and the period. `compensationSummary` is the line Ashby shows on the job, including commission and bonus. `offersEquity` is `true` when the company offers equity, `false` when it published its pay without equity, and `null` when it published no pay.
- `seniority` is read from the title: `intern`, `entry`, `senior`, `lead` (lead, staff, principal), `director` (director, head of) or `executive` (VP, C-level). `null` means the title names no level.
- `yearsOfExperience` is the minimum asked for in the description ("5+ years of experience" → 5).
- `visaSponsorship` is `true` when the description offers visa sponsorship, `false` when it says there is none, and `null` when it does not say.
- The run's **OUTPUT** record in the key-value store has the totals: companies read, open jobs, matches, jobs already saved by an earlier run, boards not found on Ashby and inputs that are not Ashby boards.

### Only new jobs

Turn on **Only new jobs** and schedule the task (daily or hourly). Each run saves only the jobs that earlier runs of the same search, or the same boards and filters, did not save, so you get just the new postings and pay only for those. The memory is kept for 180 days in a key-value store named `ashby-jobs-state` in your own Apify account.

Each search has its own memory. To share one between two tasks, give both the same **Memory name**; to start over, give a new one.

### Pricing

Pay per event: you pay **only for jobs saved to the dataset**, not for the jobs that were read and filtered out, and not for jobs skipped by *Only new jobs*. Filters cost nothing, so a precise filter is the cheapest run. Set a maximum cost for a run and the Actor stops cleanly when it is reached.

### Good to know

- Only **public** job boards are read: the same jobs anyone sees on the company's careers page. Jobs a company keeps unlisted are left out.
- The directory holds the Ashby boards found in the public Common Crawl web index and checked live. It is rebuilt every month. A company that is not in it can still be read by giving its board.
- The daily index makes a directory search fast. A company whose first matching job appeared after the index was built is found once the index includes it (it is rebuilt every day). Boards you give are always read live.
- Ashby lists every job of a board with its description and pay in one request, so description filters cost no extra requests.
- **Greenhouse, Lever, Workday and more?** Our **ATS Job Scraper** reads 12 job platforms, Ashby included, with the same columns, and our **Job Search API** searches 20,000+ company career sites on 7 platforms. There are also our **Greenhouse Jobs Scraper** and **Workday Jobs Scraper**.

### Support

Found a board that doesn't load, or a field that looks wrong? Open an issue on the Actor's Issues tab with the board address. Issues get an answer within a few days.

# Actor input Schema

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

Keep jobs whose title contains any of these words (whole-word match: 'intern' does not match 'internal'). Example: software engineer, data scientist. Leave empty for all jobs.

## `excludeKeywords` (type: `array`):

Drop jobs whose title contains any of these words, e.g. senior, manager, intern.

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

Keep jobs whose location, any secondary location or country code contains one of these texts: New York, Germany, DE, London. Codes of two letters match whole words only. The word 'remote' also matches jobs flagged remote.

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

Keep only jobs that offer a fully remote option, as the company set it in Ashby.

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

Keep only jobs published on Ashby in the last N days.

## `seniority` (type: `array`):

Keep only these levels, read from the job title: "Senior Data Engineer" is senior, "Head of Sales" is director. "Not stated" keeps titles without a level word, which are mostly mid-level roles. Empty = all levels.

## `workplaceTypes` (type: `array`):

Keep only these workplace types, as the company set them in Ashby (remote, hybrid, on-site). 88% of Ashby jobs state it; add "Not stated" to keep the others. Empty = all.

## `employmentTypes` (type: `array`):

Keep only these employment types, as the company set them in Ashby (every Ashby job has one). Empty = all.

## `descriptionKeywords` (type: `array`):

Keep jobs whose description contains any of these words (whole-word match), e.g. Python, Kubernetes, GDPR.

## `excludeDescriptionKeywords` (type: `array`):

Drop jobs whose description contains any of these words, e.g. clearance, relocation.

## `onlyWithSalary` (type: `boolean`):

Keep only jobs with a salary: the compensation the company set in Ashby, or a pay range written in the description.

## `onlyVisaSponsorship` (type: `boolean`):

Keep only jobs whose description says the company sponsors visas. Jobs that say nothing about it are dropped.

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

Leave empty to search every company in our Ashby directory (3,300+). Or add companies' Ashby job boards to read just those, whole: the board address (jobs.ashbyhq.com/ramp) or only its name on Ashby (ramp). A link to any job on the board works too. The filters above apply to both.

## `excludeCompanies` (type: `array`):

When searching the directory: skip companies whose name or Ashby board name contains one of these texts.

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

Newest first, across all companies. Empty: 200 for a directory search, and every job (up to 5,000) when you give boards. You also never pay more than the spending limit you set for the run.

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

Newest first. Keeps one big employer from filling the results. 0 or empty = no limit.

## `descriptionFormat` (type: `string`):

Plain text is best for spreadsheets and AI agents. 'None' makes results smaller; the salary and compensation fields stay.

## `onlyNew` (type: `boolean`):

Save only jobs that earlier runs of this same search (or these same boards) did not save, so a daily schedule gives you just the new postings and you pay only for those. The memory is kept for 180 days in a key-value store named "ashby-jobs-state" in your account.

## `stateKey` (type: `string`):

By default each search or set of boards has its own memory. Give a name to share one memory between tasks, or a new name to start over. Letters, digits, dot, dash and underscore.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "remoteOnly": false,
  "postedWithinDays": 7,
  "onlyWithSalary": false,
  "onlyVisaSponsorship": false,
  "maxJobs": 50,
  "descriptionFormat": "text",
  "onlyNew": false
}
```

# 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 = {
    "keywords": [
        "software engineer"
    ],
    "postedWithinDays": 7,
    "maxJobs": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("digital_influx/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 = {
    "keywords": ["software engineer"],
    "postedWithinDays": 7,
    "maxJobs": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("digital_influx/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 '{
  "keywords": [
    "software engineer"
  ],
  "postedWithinDays": 7,
  "maxJobs": 50
}' |
apify call digital_influx/ashby-jobs-scraper --silent --output-dataset

```

## MCP server setup

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