# BuiltIn Jobs Scraper - Tech Roles with Required Skills (`webdata_labs/builtin-jobs-scraper`) Actor

Scrape tech and startup jobs from Built In with the required-skills list for every role, plus company, industry tags, workplace type, experience level and the full description. Filter by country, category and remote. No login, no API key.

- **URL**: https://apify.com/webdata\_labs/builtin-jobs-scraper.md
- **Developed by:** [WebData Labs](https://apify.com/webdata_labs) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 job scrapeds

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?

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

## BuiltIn Jobs Scraper - tech roles with the skills each one requires

Scrape tech and startup jobs from **Built In** and get back a clean row per role with the **list of skills the job actually asks for**, the company, its industries, the workplace type, the experience level and Built In's own summary of the role.

No login. No API key. No browser. Pure HTTP, runs on 256 MB.

**$1.50 per 1,000 jobs. No Actor start fee.**

### ✅ What you get / ❌ what this isn't

✅ **Top skills as a structured array** on every row: `["Python", "Spark", "AWS", "Terraform"]`
✅ Company, its Built In profile URL and its industry tags
✅ Workplace type (Remote, Hybrid, In-Office and the mixed variants) and experience level
✅ Built In's own written summary of the role on every row, at no extra cost
✅ Optional full job description from the job page
✅ Filters for country, category and remote, plus a posted-within window
✅ Monitoring mode that returns only jobs you have not already been given

❌ No salary. Built In does not publish pay on its job cards or job pages, so there is no salary field
❌ Not a candidate or profile scraper. Public job listings only
❌ Not an apply bot

### 🔎 Why use this Actor

Most job scrapers give you a title, a company and a link. The field that makes a tech job feed worth having is **what the role actually requires**, and Built In publishes exactly that on every card.

This Actor returns it as an array you can group and count, which turns a job feed into a **skills-demand dataset**: which frameworks are hiring, which are cooling, which companies are staffing up on which stack, and how that differs by city and seniority. Measured on a sample of 60 US software roles: **60 of 60 carried a skills list**, averaging 8 to 12 skills each.

You also get Built In's summary of every role for free, so most use cases never need the slower full-description pass at all.

### 🗂️ Coverage

Built In lists tech and startup jobs. Countries you can pick:

- United States
- United Kingdom
- Canada
- Ireland
- Germany
- India
- Australia
- Portugal
- Spain
- Poland
- Mexico
- Brazil

Categories you can filter by:

- Software engineering
- Data and analytics
- Design and UX
- Product
- Operations
- Sales
- Marketing
- Finance
- HR
- Legal
- Customer success
- Content
- Cybersecurity
- Consulting
- Engineering
- Entry level

### 👥 Who it's for

- **Recruiters and sourcers** who need to know which stack a role wants before writing outreach.
- **Talent-market analysts** building skills-demand series: count `skills` by month, city or seniority.
- **Developer-tool and DevRel teams** measuring which companies are adopting their technology, from the job ads.
- **Job boards and aggregators** that want a clean tech feed with company and industry attached.
- **Sales teams** using hiring as a buying signal, with `industries` and `companyUrl` for enrichment.

### 📚 Example tasks

| What you want | Input |
| -- | -- |
| [Python roles in the US](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-python-jobs-in-the-us) | `{"searchQueries": ["python"], "country": "USA"}` |
| [All data and analytics jobs](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-data-and-analytics-jobs) | `{"category": "data-analytics", "country": "USA"}` |
| [Remote software engineering roles](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-remote-engineering-jobs) | `{"category": "dev-engineering", "country": "USA", "remoteOnly": true}` |
| [Machine learning jobs with full descriptions](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-machine-learning-jobs-with-descriptions) | `{"searchQueries": ["machine learning"], "country": "USA", "includeDescription": true}` |
| [Entry level tech jobs](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-entry-level-tech-jobs) | `{"category": "entry-level", "country": "USA"}` |
| [Cybersecurity roles posted this week](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-cybersecurity-jobs-this-week) | `{"category": "cybersecurity", "country": "USA", "postedWithinDays": "7"}` |
| Several stacks in one run | `{"searchQueries": ["rust", "golang", "kubernetes"], "country": "USA", "maxResults": 600}` |
| Product and design in Canada | `{"category": "product", "country": "CAN"}` |
| Paste a Built In search URL | `{"startUrls": ["https://builtin.com/jobs/remote/dev-engineering?search=react"]}` |
| [Only what is new since the last run](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-new-jobs-daily-monitor) | `{"searchQueries": ["python", "data engineer"], "country": "USA", "onlyNewJobs": true}` |
| [Tech jobs in the UK](https://apify.com/webdata_labs/builtin-jobs-scraper/examples/builtin-tech-jobs-in-the-uk) | `{"country": "GBR"}` |

### ⚙️ How it works

Give it keywords, a category, or a Built In search URL pasted from your browser. Every request carries an explicit country, because Built In personalises its results by visitor location and a run that leaves it to chance is not reproducible.

Each search is paged until Built In stops returning jobs it has not already given us. Every row is pushed to the dataset the moment it is parsed, so a run you stop early keeps everything it found.

### 🔁 Monitoring: only jobs you have not seen before

Set `onlyNewJobs` to `true` and schedule it. The Actor remembers the job ids it has **delivered** and returns only listings that are new since the last run, so a daily monitor never re-delivers, and never re-bills, the same posting.

Run it as a saved task and keep using that task: the memory belongs to the task, not to one-off runs from the Actor page.

### 📥 Input

| Field | Type | Default | What it does |
| -- | -- | -- | -- |
| `startUrls` | array | empty | Built In search URLs pasted from your browser. Keywords, country, category and remote are read from each one. |
| `searchQueries` | array | `["python"]` | One keyword search per line. Each is crawled separately. Leave empty to browse a whole category or country. |
| `country` | string | `USA` | Which country's jobs to return. |
| `category` | string | all | One Built In category, or all of them. |
| `remoteOnly` | boolean | `false` | Ask Built In for its remote board. See the caveat below: it is a preference, not a hard filter. |
| `postedWithinDays` | string | any | `1`, `3`, `7` or `30`. |
| `maxResults` | integer | `200` | Total jobs across all searches. |
| `includeDescription` | boolean | `false` | Also fetch the full description from each job page. Free, but slower: it adds one request per job. |
| `onlyNewJobs` | boolean | `false` | Return only jobs not delivered by a previous run of the same task. |

#### Accepted input aliases

Input pasted from another Actor's docs runs here without editing: `urls` and `url` for `startUrls`, `queries` and `keywords` for `searchQueries`, `maxItems` and `maxJobs` for `maxResults`.

There is nothing to configure about proxies, concurrency, retries or request pacing. Those are handled internally and included in the price.

### 📤 Output

One row per job.

```json
{
  "jobId": "11032078",
  "title": "Software Engineer II - Platform Engineer Databricks",
  "company": "JPMorganChase",
  "companyUrl": "https://builtin.com/company/jpmorgan-chase",
  "jobUrl": "https://builtin.com/job/software-engineer-ii-platform-engineer-databricks/11032078",
  "location": "Jersey City, NJ, USA",
  "workplaceType": "Hybrid",
  "experienceLevel": "Junior",
  "postedLabel": "An Hour Ago",
  "industries": ["Financial Services"],
  "skills": ["Spark", "AWS", "Databricks", "Git", "Java", "Jenkins", "Python", "Terraform"],
  "summary": "Builds and supports a managed AWS Databricks data platform, including platform design, configuration, workspace administration, monitoring and operational stability...",
  "descriptionText": null,
  "searchQuery": "python",
  "scrapedAt": "2026-09-05T16:20:11Z"
}
```

#### Output fields

| Field | Type | Description |
| -- | -- | -- |
| `jobId` | string | Built In's own job id. Stable, and what monitoring mode remembers. |
| `title` | string | Job title as posted. |
| `company` | string | Hiring company. |
| `companyUrl` | string | The company's Built In profile. |
| `jobUrl` | string | The listing on Built In. |
| `location` | string | City, state and country. Null on fully remote roles, about 6 in 60. |
| `workplaceType` | string | `Remote`, `Hybrid`, `In-Office`, `Remote or Hybrid` or `In-Office or Remote`. |
| `experienceLevel` | string | `Entry level`, `Junior`, `Mid level`, `Senior level` or `Expert/Leader`. |
| `postedLabel` | string | Built In's relative posting age, for example `An Hour Ago` or `3 Days Ago`. |
| `industries` | array | The company's industry tags. |
| `skills` | array | **The skills the role asks for.** The reason this Actor exists. |
| `summary` | string | Built In's own written summary of the role. Always present, no extra cost. |
| `descriptionText` | string | Full job description. Only when `includeDescription` is on. |
| `searchQuery` | string | Which of your keywords produced this row. |
| `scrapedAt` | string | UTC timestamp of the row. |

### 💵 How much does it cost to scrape Built In?

| Jobs | Cost |
| -- | -- |
| 100 | $0.15 |
| 1,000 | $1.50 |
| 10,000 | $15.00 |

$0.0015 per job and nothing else. No Actor start fee, so a run that returns nothing costs nothing. Skills, industries and the role summary are included at the base rate, and so are full descriptions when you turn them on.

### ⚠️ Limits and caveats

Measured 5 September 2026, so you do not spend a run finding them out.

- **There is no salary data.** Built In does not publish pay on its job cards or on its job pages, and the pages carry no structured job-posting markup either. If you need salary, this is the wrong source; if you need skills, there is no better one.
- **Results depend on the country you choose.** Built In personalises by visitor location: the same keyword from a European connection and from a US one shared **none** of their first 25 results. The Actor always sends your chosen country explicitly so a scheduled run stays reproducible. The default is the United States.
- **Remote, Hybrid and In-Office are a preference, not a hard filter.** Built In's own `/jobs/office` board returns mostly Hybrid roles. Trust the `workplaceType` field on each row, not the filter.
- **Posted dates are relative** (`Yesterday`, `3 Days Ago`) because that is exactly what Built In renders. There is no absolute timestamp to convert.
- **A broad search is deep.** A US `python` search served more than 5,000 jobs without running out, so `maxResults` is usually what ends a run rather than Built In running out of results.
- **Page size varies between 10 and 25** depending on the category, so progress is not a neat multiple of 25.
- **Full descriptions are much slower.** They add a page fetch per job, and Built In starts refusing connections if it is asked too quickly, so the Actor paces itself. A 200-job run takes about 5 seconds without descriptions and several minutes with them. They are off by default for that reason, and the per-row summary covers most needs.

### 🔁 Run it on the Apify platform

Schedule it, use monitoring mode, and pull results with the Apify API or the JavaScript and Python clients. The dataset exports as JSON, CSV, Excel and XML.

### 🤖 Use with AI agents via MCP

**Claude Code**

```bash
claude mcp add apify --transport http https://mcp.apify.com --header "Authorization: Bearer <YOUR_APIFY_TOKEN>"
```

**Cursor or Claude Desktop**

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Then ask in words: "find remote data engineering jobs on Built In that ask for dbt". The agent fills `searchQueries`, `country` and `remoteOnly` itself, which is why this Actor keeps structured inputs alongside URL input.

### 🔗 Use this Actor in n8n

Add the **Apify** node, choose **Run Actor**, pick `webdata_labs/builtin-jobs-scraper` and paste your input JSON. Chain **Get Dataset Items** after it. A common pattern is a daily schedule with `onlyNewJobs: true` feeding new roles into a spreadsheet or CRM.

### ⚖️ Is it legal to scrape Built In?

This Actor reads only public job listings that Built In serves to logged-out visitors. It does not log in, does not touch member profiles and does not collect personal data. Job listings are business information rather than personal data.

You remain responsible for what you do with the output. If you plan to republish listings, check Built In's terms and your own position first.

### 🧩 Related Actors

- [Dice Job Scraper](https://apify.com/webdata_labs/dice-job-scraper) - US tech roles with parsed salary ranges and the skills Dice tags each posting with.
- [Wellfound Jobs Scraper](https://apify.com/webdata_labs/wellfound-jobs-scraper) - startup roles with equity ranges, funding stage and the ATS each company runs.
- [We Work Remotely Jobs Scraper](https://apify.com/webdata_labs/weworkremotely-jobs-scraper) - remote-only postings, every live listing rather than the truncated search page.
- [XING Jobs Scraper](https://apify.com/webdata_labs/xing-jobs-scraper) - German-speaking roles with salary ranges and the employer's own apply URL.
- [Lead List Cleaner](https://apify.com/webdata_labs/lead-list-deduplicator) - merge several runs into one deduplicated, CRM-ready list.

### ❓ FAQ

#### Does it need a Built In login?

No. It reads only what Built In serves to logged-out visitors. There is no credential field.

#### Where do the skills come from?

Built In publishes a "Top Skills" list on each job card. The Actor returns it verbatim as an array, so you can count and group it without parsing free text.

#### Why is there no salary field?

Built In does not publish pay, anywhere. Rather than ship a column that is always null, there is no salary field at all. For salary data on European roles, see the XING Jobs Scraper linked above.

#### Why did I get jobs in the wrong country?

You should not: the Actor always sends the country you picked. If you pasted a `startUrls` entry that carries its own `country` parameter, that URL's country wins for that search.

#### How many jobs can I get?

More than 5,000 on a broad US keyword. `maxResults` is what ends most runs.

#### Are full descriptions worth turning on?

Often not. Every row already carries Built In's summary of the role. Turn descriptions on when you need the literal posting text, and expect the run to take several minutes instead of several seconds.

#### Does the remote filter really return only remote jobs?

No, and neither does Built In's own remote board. Filter your dataset on `workplaceType` afterwards if you need certainty.

#### How does monitoring mode remember what it has seen?

It stores the ids it actually delivered in a store that belongs to the task, so a scheduled task keeps its history across runs. Jobs it found but did not deliver, because your `maxResults` was reached, are deliberately not remembered.

#### Am I charged for a run that finds nothing?

No. The only charge is per job returned, and there is no start fee.

### 📝 Changelog

**0.1** - 5 September 2026. First release. Keyword, category, country and remote search, posted-within window, skills and industry arrays, Built In role summaries, optional full descriptions, and monitoring mode.

### 🛠️ Support

Found a bug or need a field? Open an issue on the Actor's Issues tab. Reports with a run id get fixed fastest.

### ⭐ Rate this Actor

If it saved you time, a rating helps other people find it.

# Actor input Schema

## `startUrls` (type: `array`):

Paste Built In job search URLs from your browser, for example https://builtin.com/jobs/remote/dev-engineering?search=python. Keywords, country, category and remote are read from each URL.

## `searchQueries` (type: `array`):

One keyword search per line, for example "python" or "machine learning". Each line is crawled separately. Leave empty to browse a whole category or country instead.

## `country` (type: `string`):

Which country's jobs to return. Built In personalises results by visitor location, so the Actor always sends this explicitly to keep runs reproducible.

## `category` (type: `string`):

Restrict to one Built In category. Leave empty for all categories.

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

Ask Built In for its remote job board. Built In treats this as a preference rather than a strict filter, so check the workplaceType field on each row.

## `postedWithinDays` (type: `string`):

Only jobs Built In has updated within this many days.

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

Stop after this many jobs across all searches. A broad US search has more than 5,000 jobs behind it, so this is usually what ends the run rather than Built In running out.

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

Also fetch the full job description from each job page. Off by default: every row already carries Built In's own summary of the role, and full descriptions add one page fetch per job, which makes a run several times slower. Free either way.

## `onlyNewJobs` (type: `boolean`):

Return only jobs that were not returned by a previous run of the same saved task. Use this for scheduled monitoring so you are not billed twice for the same listing.

## Actor input object example

```json
{
  "startUrls": [],
  "searchQueries": [
    "python"
  ],
  "country": "USA",
  "category": "",
  "remoteOnly": false,
  "postedWithinDays": "",
  "maxResults": 200,
  "includeDescription": false,
  "onlyNewJobs": false
}
```

# Actor output Schema

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

One row per Built In job, with its required-skills list, industry tags and full description.

## `overview` (type: `string`):

The same rows, trimmed to the fields most buyers scan first.

## `OUTPUT` (type: `string`):

Counts per search, and why pagination stopped.

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

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

# Run the Actor and wait for it to finish
run = client.actor("webdata_labs/builtin-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 '{
  "searchQueries": [
    "python"
  ]
}' |
apify call webdata_labs/builtin-jobs-scraper --silent --output-dataset

```

## MCP server setup

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