# Ashby Jobs API Scraper (`muhammadafzal/ashby-jobs-api`) Actor

Fetch public Ashby job postings across company boards with full descriptions, locations, departments, remote status, compensation, and apply URLs.

- **URL**: https://apify.com/muhammadafzal/ashby-jobs-api.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Jobs, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 ashby job results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Ashby Jobs API Scraper

Fetch public job postings from one or more Ashby-hosted job boards and return normalized, filterable records for recruiting research, job alerts, market analysis, and data pipelines. The Actor uses Ashby's official public Job Postings API; it does not require cookies, login credentials, or a browser.

### What it extracts

Each dataset row represents one currently published and listed Ashby job:

| Field | Meaning |
|---|---|
| `jobId`, `jobBoard` | Stable Ashby posting ID and organization board name |
| `title`, `department`, `team` | Role and organization classification |
| `employmentType`, `workplaceType`, `isRemote` | Employment and workplace arrangement |
| `location`, `secondaryLocations` | Primary and alternate displayed locations |
| `city`, `region`, `country` | Structured primary postal location when provided |
| `publishedAt` | Ashby publication timestamp |
| `jobUrl`, `applyUrl` | Public description and application links |
| `descriptionPlain`, `descriptionHtml` | Full plain description and optional original HTML |
| `compensationSummary` | Employer-provided public compensation summary |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryInterval` | Normalized first salary summary component when disclosed |
| `source`, `scrapedAt` | Provenance and extraction timestamp |

Missing optional source fields are returned as `null`; lists keep a stable array shape. The `OUTPUT` key-value record reports board success/failure counts, jobs received, filters, duplicates, warnings, and whether `maxResults` stopped the run.

### When to use it

Use this Actor when you know one or more organizations that host careers pages at `jobs.ashbyhq.com`. It is useful for monitoring openings, building job-search datasets, comparing hiring activity, researching remote roles, or feeding a workflow or AI agent with consistent job records.

Do not use it to discover every company using Ashby, retrieve private/draft jobs, submit applications, access candidate data, or interact with Ashby's authenticated recruiting API. Unlisted postings are intentionally excluded even if an upstream response contains them.

### Input

`jobBoards` is required. Each entry may be the final board name or the full organization board URL:

```json
{
  "jobBoards": ["Ashby", "https://jobs.ashbyhq.com/ramp"],
  "keyword": "engineer",
  "locations": ["United States", "Remote"],
  "departments": ["Engineering"],
  "remoteOnly": true,
  "publishedAfter": "2026-01-01",
  "includeCompensation": true,
  "includeDescriptionHtml": false,
  "maxResults": 100,
  "maxConcurrency": 5
}
```

Text filters are case-insensitive substring matches. Multiple entries in one filter use OR logic; separate filters combine with AND logic. For example, two locations plus one department keep jobs in either location that also match the department. `publishedAfter` accepts an ISO 8601 date or timestamp.

Ashby's public endpoint returns a whole board in one response, so there is no upstream pagination. `maxResults` caps the unique records written across all requested boards. Requests use bounded concurrency, a 30-second timeout, and up to three attempts for rate limits, server errors, and transient network failures.

### Output example

```json
{
  "jobId": "7458d4e9-da2e-47bd-98cb-adfda43d42b2",
  "jobBoard": "Ashby",
  "title": "Engineering Manager - EU",
  "department": "Engineering",
  "team": "EMEA Engineering",
  "employmentType": "FullTime",
  "location": "Remote - European Union",
  "secondaryLocations": ["Spain", "Italy", "Germany"],
  "city": null,
  "region": null,
  "country": "European Union",
  "isRemote": true,
  "workplaceType": "Remote",
  "publishedAt": "2024-03-04T14:29:08.532+00:00",
  "jobUrl": "https://jobs.ashbyhq.com/Ashby/7458d4e9-da2e-47bd-98cb-adfda43d42b2",
  "applyUrl": "https://jobs.ashbyhq.com/Ashby/7458d4e9-da2e-47bd-98cb-adfda43d42b2/application",
  "descriptionPlain": "Full public job description...",
  "descriptionHtml": null,
  "compensationSummary": "€110K – €185K • Offers Equity • Offers Bonus",
  "salaryMin": 110000,
  "salaryMax": 185000,
  "salaryCurrency": "EUR",
  "salaryInterval": "1 YEAR",
  "source": "api.ashbyhq.com/posting-api",
  "scrapedAt": "2026-09-05T00:00:00.000Z"
}
```

### Pay per event

| Event | Price | Trigger |
|---|---:|---|
| Actor start | $0.00005 | One run starts |
| Ashby job result | $0.001 | One validated job is written to the default dataset |

A run returning 100 jobs costs approximately `$0.10005` in event charges. A valid empty run costs only the start event. Prices are all-in unless the live Apify pricing panel explicitly says otherwise. Use the platform's maximum total charge setting and `maxResults` for budget control.

### Reliability and failure behavior

The Actor calls the documented first-party endpoint directly. `404` responses are reported as invalid/missing board warnings. `429`, `5xx`, timeouts, and transient network errors receive bounded retries. If some boards fail, valid records from healthy boards are preserved and the run is marked `PARTIAL`. If every board fails, the run is marked `FAILED`; no fabricated dataset rows or result events are produced. A healthy board with no jobs matching the filters is reported as `EMPTY`.

### Responsible use

Only public job-posting data is collected. Respect Ashby's terms, the hiring organization's policies, applicable privacy law, and reasonable request rates. Job descriptions may contain names, email addresses, or other personal data supplied by employers; collect and retain only what your lawful purpose requires. The Actor does not bypass authentication, CAPTCHAs, access controls, or application workflows.

For support, include the run ID, redacted input, and the `OUTPUT` summary. Do not include candidate data, API keys, cookies, or other secrets.

# Actor input Schema

## `jobBoards` (type: `array`):

Use this to select organizations. Enter a board name such as `Ashby` or a URL such as `https://jobs.ashbyhq.com/Ashby`; 1–50 unique boards are accepted. This is not an individual job URL.

## `keyword` (type: `string`):

Use this to keep jobs containing a phrase in the title, department, team, location, or plain-text description, for example `engineer`. Matching is case-insensitive; blank keeps all jobs.

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

Use this to keep jobs whose primary or secondary location contains any entry, for example `United States` or `London`. Matching is case-insensitive; an empty list disables the filter.

## `departments` (type: `array`):

Use this to keep jobs whose department contains any entry, for example `Engineering`. Matching is case-insensitive; an empty list disables the filter.

## `teams` (type: `array`):

Use this to keep jobs whose Ashby team contains any entry, for example `Growth`. Matching is case-insensitive; an empty list disables the filter.

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

Use this to keep any matching Ashby employment type, for example `FullTime`, `PartTime`, `Contract`, `Intern`, or `Temporary`. Values are matched case-insensitively; empty keeps all types.

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

Use this to keep any matching workplace type, for example `Remote`, `Hybrid`, or `OnSite`. Values are matched case-insensitively; empty keeps all types.

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

Use this when only postings marked remote by Ashby should be returned. The default `false` includes both remote and non-remote jobs.

## `publishedAfter` (type: `string`):

Use this to keep jobs published on or after an ISO 8601 date or timestamp, for example `2026-01-01`. Leave blank for any publication date; this is not a free-form relative date.

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

Use this to request public compensation fields from Ashby's official posting API. Enabled by default; jobs without disclosed compensation return null salary fields.

## `includeDescriptionHtml` (type: `boolean`):

Use this when the original rich job description is needed. The default `false` returns plain text only and keeps datasets smaller.

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

Use this to cap unique dataset records across all boards. The default is 100; accepted range is 1–10000. This is a result limit, not an API-page limit.

## `maxConcurrency` (type: `integer`):

Use this to control simultaneous Ashby board requests. The default is 5; accepted range is 1–10 to keep traffic bounded.

## Actor input object example

```json
{
  "jobBoards": [
    "Ashby"
  ],
  "keyword": "",
  "locations": [],
  "departments": [],
  "teams": [],
  "employmentTypes": [],
  "workplaceTypes": [],
  "remoteOnly": false,
  "publishedAfter": "",
  "includeCompensation": true,
  "includeDescriptionHtml": false,
  "maxResults": 100,
  "maxConcurrency": 5
}
```

# Actor output Schema

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

Schema-validated Ashby job records in the default dataset.

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

Status, board counts, filtering totals, warnings, and timing in the OUTPUT key-value record.

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

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

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

```

## MCP server setup

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