# Ashby Jobs API - Title, Location, Department Data (`om_kh/ashby-jobs-api`) Actor

Ashby jobs API: every open job from any jobs.ashbyhq.com board as clean data, with title, location, department, date, full description, salary, skills, apply link, seniority and remote flags. $1.50 per 1,000 jobs, first 3 per run free. Filters run before billing. No login.

- **URL**: https://apify.com/om_kh/ashby-jobs-api.md
- **Developed by:** [Khandji Omar](https://apify.com/om_kh) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 job listings

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 — Every Open Job From Any Ashby Board

> Pass up to 100 Ashby company handles in one run, get every open role as clean rows. First **3 jobs free on every run**, then **$1.50 per 1,000**.

### In short: what you give, what you get, what it costs

| | |
|---|---|
| **You give** | Ashby company handles or board links (`ramp`), up to 100 per run, with optional keyword, location and remote filters |
| **We do** | Read each company's official public Ashby job feed; filters run before billing |
| **You get** | One row per open job: title, location, department, posted date, apply link and description, plus job function, seniority and remote flags |
| **It costs** | $1.50 per 1,000 jobs + $0.001 per run. A company with 35 open roles costs about **$0.05**. The first 3 jobs of every run are free. No supplier fee |
| **It does not** | Scrape LinkedIn, Indeed or job boards, or read pages behind a login |

A real result row is shown further down this page.

### Compared with bovi/greenhouse-lever-ashby-job-scraper

Read on the Store on 2026-10-23 (Greenhouse, Lever & Ashby Job Scraper API | $1.50/1K). Where it does better, this section says so.

- **Built on the site's own data**, not a resold scraper: no second Actor between you and the source.
- **Free results on every run** and a hard cost cap (`maxTotalChargeUsd`).
- **Price:** $1.5 per 1,000 here, $1.5 there.

### Why this one

Most job scrapers ask you to buy a token, run a proxy, or fight an anti-bot
wall. This Actor reads the **Ashby board endpoint directly** — the same one
the careers page itself calls. Three consequences:

1. **Nothing to buy.** No token, no cookie, no API key, nothing that expires.
2. **It does not break.** No HTML parsing, so a Ashby redesign changes nothing.
3. **It stays cheap.** There is no upstream scraper to pay for, which is why the
   first 3 jobs of every run are free.

### What a run costs

**$1.50 per 1,000 job listings** — $0.0015 each, and only for listings actually
delivered to you. There is no per-run fee: a run that finds nothing costs $0.

#### Ask for many companies at once

Measured on this Actor at ~35 open roles per company:

| Companies in one run | Jobs returned | You pay | Per job |
|---|---|---|---|
| 1 | 35 | **$0.05** | $0.0014 |
| 10 | 350 | **$0.52** | $0.0015 |
| 50 | 1,750 | **$2.62** | $0.0015 |

Batching does not change the price per job — it changes your wall clock. Fifty
companies asked together take one run instead of fifty, and the free allowance
below is the only thing that makes a small run cheaper per row.

### Free tier — 3 job listings on every run

**The first 3 job listings of every run are free.** Not a trial, not a first-run
coupon: it applies to every run you ever make, so you can wire this Actor into a
pipeline and evaluate it on your own target boards before a cent is billed.

Beyond the free 3 you pay **$0.0015 per job listing** — $1.50 per 1,000 — and only
for listings actually delivered to you.

### What you pass (input)

| Field | What it does |
|---|---|
| `ashbyCompanies` | Company handles — the `<handle>` in `jobs.ashbyhq.com/<handle>` |
| `keywords` | Keep only roles whose title matches, whole words only |
| `excludeKeywords` | Drop roles whose title matches |
| `locations` | Keep only roles in these locations |
| `remoteOnly` | Keep only remote roles |
| `postedAfter` | Keep only roles posted on or after this date |
| `maxTotalChargeUsd` | Hard ceiling on what one run can cost you |

Filters run **before** billing, so you are never charged for a row you filtered out.

### What you get per job

A real row from this Actor's latest run on Apify (2026-10-23; long texts are cut and people's names hidden here, your dataset has them in full):

```json
{
  "source_url": "https://jobs.ashbyhq.com/ramp/b9568fb8-a47e-4738-87fb-a6d88c3a505f",
  "title": "Account Manager | Commercial",
  "company": "ramp",
  "location": "New York, NY (HQ)",
  "department": "Sales",
  "posted_at": "2025-12-10T14:44:21.253+00:00",
  "source": "ashby",
  "salary": "$160K – $230K • Offers Equity • Offers Commission • Multiple Ranges",
  "job_id": "b9568fb8-a47e-4738-87fb-a6d88c3a505f",
  "description": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams, embedded in the transaction flow of every dollar a business spen...",
  "employment_type": "FullTime",
  "workplace_type": "remote",
  "apply_url": "https://jobs.ashbyhq.com/ramp/b9568fb8-a47e-4738-87fb-a6d88c3a505f/application",
  "handle": "(hidden here)",
  "ats": "ashby",
  "function": "Sales",
  "seniority": "Manager",
  "is_remote": false,
  "posted_within_days": 317,
  "is_recent": false,
  "experience_years": 3,
  "skills": [
    "Salesforce",
    "NetSuite"
  ],
  "education": "Bachelor",
  "salary_min": 160000,
  "salary_max": 230000,
  "salary_currency": "USD"
}
```

`title`, `location`, `department`, `posted_at`, `source_url` (a canonical apply
link), `handle`, `ats`, plus the normalised `function`, `seniority` and
`is_remote` fields the whole Vigia jobs family shares.

Duplicate roles are removed by apply link before billing: two handles belonging
to the same group cannot make you pay twice for one role.

### Job descriptions and facts read from the text

With `includeDescription` (on by default) each row also carries the **full job description** as plain text, the salary, contract type, workplace type and apply link when Ashby publishes them, plus facts read from the text by rules, without AI: `experience_years`, `skills`, `visa_sponsorship`, `education`, `salary_min`, `salary_max`, `salary_currency`. Same price. Turn it off for lighter rows.

### Use it from an AI agent (MCP and x402)

Connect Claude Desktop, Cursor, VS Code or any MCP client to Apify's MCP server
at `https://mcp.apify.com` and add this Actor, `om_kh/ashby-jobs-api`, as a tool — the
agent passes the same JSON as the run input and gets the dataset back.

AI agents that pay with **x402** can run it too, without an Apify account: the
Actor charges only per result delivered, so an agent pays exactly for what it gets.

### Honest failure modes

A board that is missing, private or renamed is **reported, never raised**: one
bad handle in a list of twenty does not cost you the other nineteen. Each entry
in `boards` tells you what that handle returned, and you are billed only for
jobs actually delivered.

### The rest of the family

- [Company Careers Page Scraper - Jobs from Any Career Site](https://apify.com/om_kh/careers-page-scraper) — give a
  company **website** and it finds which ATS is behind it
- [ATS Jobs API - Greenhouse, Lever, Ashby, Workday Jobs](https://apify.com/om_kh/ats-jobs-api) — nine providers in one
  Actor, when you want the control
- [Greenhouse Job Scraper - Title, Location, Salary API](https://apify.com/om_kh/greenhouse-jobs-api) ·
  [Lever.co Jobs API - Title, Location, Department, Salary](https://apify.com/om_kh/lever-jobs-api) ·
  [Ashby Jobs API - Title, Location, Department Data](https://apify.com/om_kh/ashby-jobs-api) ·
  [Workday Jobs API - Title, Location, Department Data](https://apify.com/om_kh/workday-jobs-api)

### Output example

One real row from a run on Apify:

```json
{
  "source_url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "title": "Security Engineer, Cloud",
  "company": "ramp",
  "location": "New York, NY (HQ)",
  "department": "Engineering",
  "posted_at": "2026-04-07T17:12:35.753+00:00",
  "source": "ashby",
  "salary": "$211.4K – $290.6K • Offers Equity",
  "job_id": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
  "description": "ABOUT RAMP\n\nRamp is building the smart infrastructure for finance teams, embedded in the transaction flow of every dollar a business spends. We automate how over $200B in annualized spend flows in and out of 70,000+ comp...",
  "employment_type": "FullTime",
  "workplace_type": "remote",
  "apply_url": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245/application",
  "handle": "ramp",
  "ats": "ashby",
  "function": "Engineering",
  "seniority": "Mid",
  "is_remote": false,
  "posted_within_days": 194,
  "is_recent": false,
  "experience_years": 3,
  "skills": [
    "Python",
    "Flask",
    "AWS"
  ]
}
```

### Frequently asked questions

**Do I need a Ashby account or API key?** No. The board endpoint this Actor
reads is the public one your own careers page uses.

**What does it cost to try?** Nothing. Every run gives you the first 3 jobs
free, and a run that returns fewer than that costs $0.

**How do I get jobs from a company website instead of a board handle?** Use the
[Company Careers Page Scraper - Jobs from Any Career Site](https://apify.com/om_kh/careers-page-scraper) — it detects
the ATS for you.

### How to use it in 3 steps

1. Click **Try for free** and add company handles in **ashbyCompanies** — the `<handle>` in `jobs.ashbyhq.com/<handle>`.
2. Optional: narrow the list with **keywords**, **locations**, **remote only** or **posted after**. Filters run before billing, so you only pay for jobs you keep.
3. Click **Start** and download the jobs as JSON, CSV or Excel, or read them from the API.

### Use cases

- **Job boards and aggregators** — pull every open role from Ashby companies, with a direct apply link.
- **Recruiting and sourcing** — watch target companies and react the day a role opens.
- **Sales intelligence** — a company hiring 10 engineers is a buying signal; use it as a lead trigger.
- **Market and salary research** — who is hiring for which function, where, and how fast.
- **Job alerts** — schedule daily and send new roles to Slack, email or a sheet.

### Use it from code (API)

Every Apify Actor is an API. Start a run and read the results with one call.

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("om_kh/ashby-jobs-api").call(run_input={"ashbyCompanies": ["ramp", "linear"], "keywords": ["engineer"], "remoteOnly": False})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('om_kh/ashby-jobs-api').call({
    "ashbyCompanies": [
        "ramp",
        "linear"
    ],
    "keywords": [
        "engineer"
    ],
    "remoteOnly": false
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**One HTTP call (cURL)** — runs the Actor and returns the dataset in the same response:

```bash
curl -X POST "https://api.apify.com/v2/acts/om_kh~ashby-jobs-api/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"ashbyCompanies": ["ramp", "linear"], "keywords": ["engineer"], "remoteOnly": false}'
```

### Integrations: n8n, Make, Zapier, Google Sheets

- **n8n** — the official *Apify* node, operation *Run Actor and get dataset*, Actor `om_kh/ashby-jobs-api`.
- **Make** — *Apify › Run an Actor*, then *Apify › Get Dataset Items*.
- **Zapier** — *Apify › Run Actor*; map the dataset items into your next step.
- **Google Sheets, webhooks, Slack** — add an integration from the *Integrations* tab of this Actor.
- **Schedules** — run it every hour or day from *Schedules* in Apify Console.

### Your feedback

Did this Actor save you time? A short review on the **Reviews** tab helps other people find it, and every review is read. Something missing or broken? Open an issue on the **Issues** tab: it is answered and fixed fast.

### More Actors from the same author

- [ATS Jobs API - Greenhouse, Lever, Ashby, Workday Jobs](https://apify.com/om_kh/ats-jobs-api) — one Actor for 9 ATS providers
- [Company Careers Page Scraper - Jobs from Any Career Site](https://apify.com/om_kh/careers-page-scraper) — give a company domain, it finds the ATS
- [Greenhouse Job Scraper - Title, Location, Salary API](https://apify.com/om_kh/greenhouse-jobs-api)
- [Lever.co Jobs API - Title, Location, Department, Salary](https://apify.com/om_kh/lever-jobs-api)
- [Workday Jobs API - Title, Location, Department Data](https://apify.com/om_kh/workday-jobs-api)
- [Hiring Signals API - Companies Hiring Now by Role](https://apify.com/om_kh/company-hiring-signals) — hiring velocity per company, as a buying trigger

### Support

Found a bug or have a feature request? Use the **Issues** tab on this Actor's Apify Store page, or message the author (`om_kh`) directly through Apify — every report gets a reply.

### Related tools

- Tracking companies across more than one ATS provider? → [ATS Jobs API - Greenhouse, Lever, Ashby, Workday Jobs](https://apify.com/om_kh/ats-jobs-api)

# Actor input Schema

## `ashbyCompanies` (type: `array`):

Ashby company handles - the <handle> in jobs.ashbyhq.com/<handle>. Returns every open role.

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

Keep only jobs whose title, department, company or location contains one of these words. Whole-word match. Filtering happens before billing - you are never charged for a job you filtered out.

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

Drop jobs matching any of these words, e.g. intern, senior, sales.

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

Keep only jobs whose location contains one of these, e.g. Berlin, United Kingdom.

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

Keep only roles whose location says remote, anywhere or distributed.

## `postedAfter` (type: `string`):

Keep only jobs posted on or after this date (YYYY-MM-DD). Jobs from providers that publish no date are kept.

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

Add the full job description (plain text), salary, contract type, workplace type and apply link when the system publishes them, plus facts read from the text: years of experience, skills, visa sponsorship, degree. Same price. Turn off for lighter rows.

## `maxTotalChargeUsd` (type: `number`):

Optional extra ceiling on what this run can bill you. Leave empty to use the run's own Max charge setting; if set, the lower of the two applies and the run stops delivering paid rows once it is reached.

## Actor input object example

```json
{
  "ashbyCompanies": [
    "ramp",
    "linear"
  ],
  "remoteOnly": false,
  "includeDescription": true
}
```

# Actor output Schema

## `report` (type: `string`):

A visual summary of delivery, charges, changes, and source issues.

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

Business-ready results in a sortable table. No JSON knowledge required.

## `csv` (type: `string`):

Results ready for spreadsheets, CRMs, and analytics tools.

## `excel` (type: `string`):

Results as an Excel workbook for non-technical teams.

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

Machine-readable delivery, billing, and source diagnostics.

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

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,om_kh/ashby-jobs-api"
        }
    }
}
```

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/eoaLQsQUnX6NdT0Ku/builds/B8zgskgfbvqRJNmff/openapi.json
