Ashby Job Board Scraper - Every Open Role avatar

Ashby Job Board Scraper - Every Open Role

Pricing

from $0.75 / 1,000 results

Go to Apify Store
Ashby Job Board Scraper - Every Open Role

Ashby Job Board Scraper - Every Open Role

Scrapes every open posting on any Ashby job board at jobs.ashbyhq.com and returns title, company, department, employmentType, isRemote, postedAt and the apply URL, plus city, state and country read from Ashby's own postal address. Pass a board URL or just the company slug.

Pricing

from $0.75 / 1,000 results

Rating

0.0

(0)

Developer

String

String

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Share

What does Ashby Job Board Scraper do?

It reads a company's Ashby job board and writes one row per open posting. Give it a board URL such as https://jobs.ashbyhq.com/ramp, or just the slug ramp, and it returns the whole board: title, company, department, employment type, remote flag, published date, apply link, and a location already split into city, state and country.

Ashby hydrates its boards from a public posting API, and that API is what this Actor reads. The rendered page carries less than the API does. It has a title, a display location, a team id and a workplace type; the API adds the published timestamp, Ashby's own remote flag, the per-posting apply URL and a structured postal address.

  • One request returns every open posting on a board, whatever its size. There is no paginator to walk.
  • city, state and country come from Ashby's addressLocality, addressRegion and addressCountry, so they are read rather than guessed out of a display string.
  • A slug, a board URL and a deep link to one posting all resolve to the same board and cost one fetch, not three.
  • Nothing is hardcoded per company. Any tenant on jobs.ashbyhq.com works the same way.
  • No account, cookie or API key is involved. This is the board a logged-out visitor sees.

A measured run averaged 174 postings across 5.75 requests.

What data does it extract?

FieldTypeDescription
jobIdstringAshby's own posting UUID. Stable across runs, so it is the key to de-duplicate and diff on
titlestringThe posting title, trimmed
companystringThe organisation's display name, read from the board page. null if that page could not be read
tenantstringThe board slug, for example ramp
locationstringThe display location exactly as Ashby shows it, for example New York, NY (HQ)
citystringFrom the posting's addressLocality
statestringFrom addressRegion
countrystringFrom addressCountry. Ashby writes this as the tenant entered it, so USA and United States both occur
isRemotebooleanAshby's own flag on the posting, not inferred from the location text
departmentstringThe posting's department, falling back to its team when no department is set
employmentTypestringAshby's own value, written without a space, for example FullTime
postedAtstringISO 8601 timestamp, the posting's publishedAt
jobUrlstringDirect link to the posting
boardUrlstringhttps://jobs.ashbyhq.com/<tenant>
sourceUrlstringThe exact posting-API URL the row came from
collectedAtstringISO 8601 timestamp of the run

Any field can be null when the employer left it unset. tenant, boardUrl, sourceUrl and collectedAt are always present.

Why scrape Ashby job boards?

Ashby is the ATS a lot of well-funded technology companies moved to, so its boards are a good read on where that segment is putting headcount. Some things people do with the rows:

  • Watch a list of competitors and alert on new postings by diffing jobId between scheduled runs.
  • Infer team growth from the department mix. A board that adds six enterprise sales roles is telling you about the next quarter's go-to-market plan.
  • Feed a job board or talent CRM from the employer's own board rather than from an aggregator that lags it by days.
  • Build a recruiting list filtered on city, state, country or isRemote, then work it by department.
  • Check whether a company is genuinely hiring before a sales conversation, using postedAt to see how fresh the demand is.

How to use it

  1. Open the company's careers page and click through to its job board. If the address bar reads jobs.ashbyhq.com/<something>, the company is on Ashby and <something> is the slug.
  2. Paste the URL, or just the slug, into Job boards. Add up to 100 of them.
  3. Leave Maximum results at 1000 unless you are collecting several large boards at once.
  4. Click Start. Runs finish in seconds for a single board.
  5. Export the dataset as JSON, CSV or Excel, or read it through the API using the snippet below.
  6. To keep a watchlist current, schedule the run daily and diff on jobId.

Input

FieldTypeDefaultDescription
boardsarray of stringsrequiredAshby board URLs or company slugs. Between 1 and 100 entries
maxItemsinteger1000Cap on dataset rows, up to 50,000
concurrencyinteger2Boards fetched in parallel, up to 5
{
"boards": [
"https://jobs.ashbyhq.com/ramp",
"linear",
"jobs.ashbyhq.com/openai"
],
"maxItems": 1000,
"concurrency": 2
}

A URL on any other host is rejected with a reason rather than fetched, so a stray link in a long list fails that one entry instead of the run.

Output

One row per posting, pushed to the run's dataset. This is the shape, with illustrative values rather than a captured run:

{
"jobId": "34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"title": "Security Engineer, Cloud",
"company": "Ramp",
"tenant": "ramp",
"location": "New York, NY (HQ)",
"city": "New York City",
"state": "NY",
"country": "USA",
"isRemote": false,
"department": "Engineering",
"employmentType": "FullTime",
"postedAt": "2026-04-07T17:12:35.753+00:00",
"jobUrl": "https://jobs.ashbyhq.com/ramp/34413f8d-26bf-4bbc-8ade-eb309a0e2245",
"boardUrl": "https://jobs.ashbyhq.com/ramp",
"sourceUrl": "https://api.ashbyhq.com/posting-api/job-board/ramp?includeCompensation=true",
"collectedAt": "2026-08-20T09:14:02.118Z"
}

A remote posting typically has isRemote: true, a location like Remote (US), a country, and city and state both null, because Ashby publishes no locality for it.

Every run also writes a SUMMARY record to the key-value store with the item count, the failure count and each failed target with its error.

How much does it cost?

Pay per event. You are charged for each result row written to the dataset, and the current rate is on this Actor's pricing tab. Nothing is charged for a board that fails, because a failed board writes no rows.

Because one request returns a whole board, a large board costs the same fetch as a small one, and the bill scales with how many postings you keep rather than how many pages had to be walked.

Runs started from an Apify free plan stop at 250 requests and 250 results and report that they reached the limit. Any paid plan runs the full input and whatever maxItems you set. The cap exists because these fetches go through our own infrastructure, which Apify does not reimburse on free-plan runs, and it binds on requests as well as rows so a long input list cannot spend those fetches on rows the run will not return.

Using it with the Apify API

import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "<YOUR_APIFY_TOKEN>" });
const run = await client.actor("usestring/ashby-jobs").call({
boards: ["https://jobs.ashbyhq.com/ramp", "linear"],
maxItems: 1000
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const remote = items.filter((job) => job.isRemote);
console.log(`${items.length} postings, ${remote.length} remote`);

The same run is available through the REST API, the Python client and any of Apify's integrations.

An Ashby job board is a public recruiting page. The employer publishes it so that candidates and search engines can read it, and this Actor reads exactly what a logged-out visitor gets. No login, no cookie, no API key, and nothing behind an authentication wall.

The rows describe open roles, not people. There is no candidate data, no applicant count and no recruiter contact anywhere in the output. Where a posting names an individual, that name was already published by the employer on a public page.

That said, what you may do with collected data depends on where you and the data subjects are, and on the terms you agreed to. This is not legal advice. If your use case is unusual, ask a lawyer.

FAQ

How do I find a company's Ashby board? Follow the careers link on the company's own site. Ashby boards live at https://jobs.ashbyhq.com/<slug>, where the slug is usually the company name in lowercase: ramp, linear. Paste the URL or just the slug.

How many postings come back per request? All of them. The Ashby posting API answers with the entire board in one response, so a 600-posting board costs the same fetch as a 12-posting one. A board costs a second fetch only for the company's display name, which the posting API omits.

What happens if a board has no open roles? It is recorded as a failure rather than as an empty success. An unknown slug and a board with nothing on it look identical from the outside, and reporting "0 postings" for a typo would be worse than saying the board could not be read. The reason appears in the run's SUMMARY under failures.

Can I get salary or the full job description? No. The output is the board's posting fields listed above. Follow jobUrl for the description, and note that most Ashby boards publish no compensation at all.

How fresh are the rows? They are read live at run time, so they are as current as the employer's own board. postedAt is Ashby's publishedAt timestamp, which is the moment the posting went live rather than the last time it was edited.

Will one bad board fail the run? No. Each board is fetched independently and a failure is recorded with its error in SUMMARY. The run only exits with an error if every board failed, which stops a schedule from quietly succeeding on nothing.

Are there rate limits? Nothing you need to configure. Boards are fetched two at a time by default, which you can raise to five. Fetches are routed through our own service, which owns proxy rotation and session reuse, so a large watchlist is not hitting Ashby from one address.

Feedback

Found a board that does not parse, or a field that should be here and is not? Open an issue from this Actor's Store page and include the board URL. Bug reports with a URL in them get fixed quickly.