Built In Jobs Scraper avatar

Built In Jobs Scraper

Pricing

from $0.48 / 1,000 job listing extracteds

Go to Apify Store
Built In Jobs Scraper

Built In Jobs Scraper

Search Built In jobs by keyword, location, employer, category, or URL and export normalized vacancy records with salary, dates, descriptions, and application links.

Pricing

from $0.48 / 1,000 job listing extracteds

Rating

0.0

(0)

Developer

Automation Lab

Automation Lab

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

3

Monthly active users

17 days ago

Last modified

Categories

Share

Extract built in jobs into a clean dataset for recruiting research, hiring-market analysis, and recurring vacancy monitoring. Search Built In by keyword, location, company, category, or a real Built In URL, then receive one normalized record per public job posting.

The Actor follows Built In's server-rendered job search and structured posting data. It returns stable job IDs, titles, employers, locations, salary metadata, dates, full descriptions, and application URLs without requiring a browser or login.

What can you do with this Built In jobs scraper?

  • Search Built In for roles such as software engineer or data engineer.
  • Resolve a city or region through Built In's own public location search.
  • Resolve an employer name to Built In's company filter.
  • Process a Built In category, filtered search URL, or individual job URL.
  • Build scheduled snapshots for vacancy and hiring-market monitoring.
  • Export current records to JSON, CSV, Excel, Google Sheets, a database, or another workflow.
  • Use stable job IDs and canonical URLs to compare runs in your own pipeline.

This Actor returns current public records. It does not send alerts or maintain a historical database by itself; use an Apify Schedule and compare datasets downstream for those workflows.

Who is this Actor for?

Recruiters and talent teams

Build focused candidate-market and employer-vacancy feeds without manually copying Built In careers pages.

Labor-market analysts

Collect consistent job identity, location, employer, salary, and posting-date fields for trend analysis.

Sales and lead researchers

Track organizations that are actively hiring for relevant technologies or functions.

Data engineers

Feed normalized Built In job records into a warehouse, spreadsheet, webhook, or recurring ETL job.

Job-board and career-product teams

Research current public vacancy supply while retaining the canonical source and application links.

Why use this Actor?

  • Search and source URLs: start from structured filters or a Built In URL.
  • Full job details: detail pages provide richer fields than listing cards alone.
  • Typed output: salary numbers, dates, arrays, nulls, and URLs have predictable types.
  • Location and company resolution: user-friendly names are translated to Built In's supported search filters.
  • Bounded pagination: maxItems caps saved unique jobs; discovery can continue past removed or rejected records within finite guards.
  • No paid proxy fallback: the current implementation uses direct public HTTP only.
  • Pay per result: only validated jobs saved to the dataset trigger the item event.

What Built In job data is extracted?

FieldTypeDescription
jobIdstringStable Built In job ID
titlestringPublished job title
companystringHiring employer
companyUrlstring or nullEmployer profile or website URL
locationstringReadable combined location
locationsarrayStructured city, region, and country values
workplaceTypestring or nullPublished Remote, Hybrid, or On-site label (source In-Office becomes On-site); structured Remote takes precedence
senioritystring or nullExplicit current-job experience label, such as Entry level
employmentTypearrayValues such as FULL_TIME
salaryMinnumber or nullPublished salary minimum
salaryMaxnumber or nullPublished salary maximum
salaryCurrencystring or nullCurrency code, such as USD
salaryPeriodstring or nullPeriod, such as YEAR or HOUR
datePostedstring or nullSource posting date
validThroughstring or nullSource expiry timestamp
descriptionstring or nullNormalized full description when enabled
skillsarrayStructured skills, or explicit labels from the current job's Skills Required section
industriesarrayPublished industry labels
applyUrlstring or nullPublic direct application URL when available
urlstringCanonical Built In posting URL
scrapedAtstringUTC extraction timestamp

Source fields that are not published remain null or an empty array. The Actor does not infer missing salary, work mode, skills, seniority, or expiry values. Skills Required labels may be technologies or complete qualification statements, depending on the source. Application URLs must be absolute HTTP(S); absent links and Built In easy-apply routes remain null.

How to scrape Built In jobs

  1. Open the Actor in Apify Console.
  2. Enter a query, such as software engineer.
  3. Optionally add location, company, or a Built In category slug.
  4. Alternatively, paste one or more Built In job or search URLs into startUrls.
  5. Choose maxItems and whether full descriptions should be included.
  6. Click Start.
  7. Open the Dataset tab to inspect or export the results.

A useful first run is:

{
"query": "software engineer",
"maxItems": 25,
"includeDescription": true
}

Input parameters

InputTypeDefaultMeaning
startUrlsarrayemptyBuilt In /jobs search/category URLs or /job/... detail URLs
querystringemptyTitle, skill, or keyword search
locationstringemptyCity or region resolved through Built In, for example New York, NY
companystringemptyEmployer resolved through Built In, for example Smartly
categorystringemptyBuilt In category slug, such as developer-engineer
maxItemsinteger100Maximum records, from 1 to 5,000
includeDescriptionbooleantrueInclude normalized full descriptions
maxRequestRetriesinteger2Retries for temporary network, 429, or server errors

Provide startUrls or at least one search filter. Only builtin.com URLs are accepted. Filters supplied alongside a listing URL are applied to that listing search. Filters supplied with an individual job URL are checked against the extracted record.

Search by location

Use the place a Built In visitor would recognize:

{
"query": "data engineer",
"location": "New York, NY",
"maxItems": 50
}

The Actor asks Built In's public location autocomplete for matches and uses the exact text match when available. Otherwise it uses the first result. An unrecognized location fails clearly instead of silently returning an unrelated global search.

Search by company

{
"company": "Smartly",
"maxItems": 25,
"includeDescription": false
}

The Actor prefers an exact employer-name match. When there is no exact result, it uses Built In's first company-search result. Be specific when several employers have similar names.

Scrape a Built In URL

Use a filtered page or individual posting:

{
"startUrls": [
{ "url": "https://builtin.com/jobs/remote" }
],
"maxItems": 20,
"includeDescription": false
}

For an individual job URL, the Actor emits at most one record and still applies any provided query, company, or location scope. Query matching uses source title, employer, description and skills even when includeDescription is false. Location matching uses resolved city/state/country components, including US state abbreviations. Listing URLs use Built In's search semantics, independently of direct-job seeds; mixing seed types does not impose direct-record filters on listing results. Category is a listing-route filter, not a direct-job classification.

Output example

A current result has this shape:

{
"jobId": "9354553",
"title": "C++ Market Data Engineer",
"company": "Citadel Securities",
"companyUrl": "https://builtin.com/company/citadel-securities",
"location": "Miami, Florida, USA / New York, New York, USA",
"locations": [
{ "city": "Miami", "region": "Florida", "country": "USA" },
{ "city": "New York", "region": "New York", "country": "USA" }
],
"workplaceType": null,
"seniority": null,
"employmentType": ["FULL_TIME"],
"salaryMin": 125000,
"salaryMax": 350000,
"salaryCurrency": "USD",
"salaryPeriod": "YEAR",
"datePosted": "2026-08-24",
"validThrough": "2026-09-23T00:18:40+00:00",
"description": "Job Description About the Role ...",
"skills": [],
"industries": ["Information Technology", "Software", "Financial Services"],
"applyUrl": "https://www.citadelsecurities.com/careers/details/c-market-data-engineer/",
"url": "https://builtin.com/job/c-market-data-engineer/9354553",
"scrapedAt": "2026-08-24T06:09:32.620Z"
}

The record illustrates the output shape. Listings change and may omit optional fields; seniority and skills are populated only from explicit source labels.

How much does it cost to extract Built In job listings?

The Actor uses pay-per-event pricing:

  • a $0.005 start event once per run;
  • an item event for each validated job saved to the dataset;
  • no item charge for duplicate, invalid, filtered-out, or failed records.

The BRONZE item price is $0.0008 per job, with lower per-item prices on higher Apify tiers. At that tier, 10 jobs cost about $0.013, 100 jobs about $0.085, and 1,000 jobs about $0.805, before any platform-specific taxes or plan effects.

These examples combine the start and item events. Check the pricing panel for the active tier that applies to your Apify account.

Monitoring new and changed Built In jobs

  1. Save a focused Actor input.
  2. Create an Apify Schedule for the desired interval.
  3. Use jobId or url as the stable comparison key.
  4. Store the previous result set in your own database or key-value record.
  5. Compare fields such as datePosted, validThrough, salary, or description.
  6. Send new or changed records through a webhook, Make, Zapier, or another Actor.

Each run is a current snapshot. The Actor does not claim that Built In retains historical versions of a listing.

Export Built In jobs to a spreadsheet or pipeline

The default dataset can be downloaded as JSON, CSV, Excel, XML, or RSS from Apify Console. For recurring ETL:

  • call the Actor through the API;
  • wait for the run to finish;
  • fetch defaultDatasetId;
  • request the dataset in the format your destination accepts;
  • deduplicate on jobId in the destination.

Optional nested arrays are easiest to preserve in JSON. CSV and spreadsheet exports may serialize arrays into cells.

Run with the Apify API

Replace APIFY_TOKEN with your token in a secure environment variable. Do not put tokens in source control.

cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~builtin-job-listings-scraper/runs?waitForFinish=300" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"software engineer","location":"New York, NY","maxItems":25}'

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/builtin-job-listings-scraper').call({
query: 'data engineer',
location: 'New York, NY',
maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/builtin-job-listings-scraper').call(run_input={
'query': 'software engineer',
'maxItems': 25,
'includeDescription': True,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

Use with Apify MCP

Add the Actor to Claude Code:

claude mcp add --transport http apify \
"https://mcp.apify.com?tools=automation-lab/builtin-job-listings-scraper"

Use this same JSON configuration in Claude Desktop, Cursor, or VS Code:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/builtin-job-listings-scraper"
}
}
}

Example prompts:

  • “Run the Built In Jobs Scraper for 25 data engineer jobs in New York and summarize the employers.”
  • “Extract 20 remote Built In jobs without descriptions and return a CSV-ready table.”
  • “Collect current software engineer jobs and group the output by salary currency.”

Follow one run and read bounded results

  1. Discover a stable subset. Use the Actor-specific endpoint above and read-only tools/list to discover actual names and argument schemas. Actor selection also adds get-actor-run, get-dataset-items, get-key-value-store-record, and abort-actor-run; it does not expose exactly one tool. Use only the needed Actor/run/data subset. Discovery does not authorize execution or aborting a run.
  2. Start once after authorization. Retain the returned run ID, status and storage IDs: these are metadata, not job rows. call-actor waits at most waitSecs 0–45 seconds (default 30), so do not assume completion. For a nonterminal run, check that same run with get-actor-run, using bounded backoff such as 2, 4, 8 seconds capped at 10, and a total deadline such as 120 seconds. Set the client request timeout above the chosen server wait plus transport margin, within the deadline. On client timeout, recover/check the known run rather than restart it; if the ID is unknown, report uncertainty instead of blindly rerunning. At deadline, report pending with the run ID and stop polling. Report terminal failure honestly; any available rows are partial, not a successful full result.
  3. Fetch bounded job rows. After success, use get-dataset-items with the returned dataset ID (defaultDatasetId in the run API), explicit limit=20, offset=0 initially, and fields such as jobId,title,company,location,workplaceType,seniority,skills,url, according to the discovered schema. Prefer untransformed JSON. For example, admit at most 100 source rows and 64 KiB of serialized UTF-8 result content cumulatively across all pages, whichever comes first, to model context. Advance source offsets using pagination metadata, not transformed row counts; filtering/unwinding may change returned counts. Process pages host-side before model injection and enforce the byte ceiling even for an oversized row/page: omit or summarize it with disclosure. If the client cannot intercept oversized responses, do not claim a hard byte guarantee or request unbounded results. Stop at exhaustion or budget and report returned rows, continuation offset and partial/truncated status when incomplete. Keep full exports/downloads in storage or downstream processing outside model context.
  4. Keep the collection contract. These are example consumer context limits, not Actor collection limits: they do not reduce maxItems, defaults, features or output fields. Discovery transport bytes are not model-visible context. Client discovery/caching, progressive loading and prompt caching depend on client capabilities; no universal or numeric token-saving guarantee is made.

Integrations

Apify Schedules

Run the same search daily or weekly for consistent hiring snapshots.

Webhooks

Notify a service when the run succeeds, then fetch and compare its dataset.

Google Sheets

Export a bounded result set for collaborative recruiting or market research.

Make and Zapier

Trigger downstream enrichment, routing, or notification workflows after a successful run.

Warehouses and databases

Load typed JSON into BigQuery, Snowflake, PostgreSQL, or another analytics store and deduplicate on jobId.

Reliability, retries, and failure behavior

The Actor retries only temporary network failures, rate limits, and selected 5xx responses with bounded backoff. It does not blindly retry malformed inputs, unsupported URLs, or deterministic 4xx responses.

A recognizable search page with no cards ends pagination normally. Supplied page offsets are preserved, and explicit next-page links are followed even after short pages. Repeated pages or pages with no new job IDs terminate safely. maxItems is a hard saved-record ceiling, not a candidate-URL quota. Replacement crawling is bounded to at most min(25000, max(100, maxItems × 5)) detail candidates and min(1000, max(10, maxItems × 2)) pages per listing seed, with five concurrent detail requests. Duplicate job IDs are saved and charged once even across URL variants.

HTTP 404/410 details and explicitly removed/expired postings are skipped without item charges. A current posting without valid JobPosting data is a parsing failure, not an expired record. All technical detail failures produce a failed run; genuine empty searches, expired postings and direct-filter exclusions remain valid empty outcomes. Partial failures produce warnings and useful available rows.

The Output tab links RUN_SUMMARY in this run's key-value store: discovered counts detail candidates attempted, saved, duplicates (repeated candidate encounters), filtered, expired, failed, listingPages, and counted paginationStopReasons. The finite guards can return fewer rows than requested. No customer input or full failed HTML is stored in the summary.

The source can change its HTML, public endpoints, filters, or structured data. Review failed-run logs before rerunning a large task.

Failed operations send sanitized diagnostic input, exceptions and actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; reports are retained for 30 days.

Tips and limitations

  • Start with a small maxItems while validating a new search.
  • Use specific location text when autocomplete could return several places.
  • Use an exact company name when possible.
  • Turn off includeDescription when descriptions are not needed in downstream output; detail pages are still fetched for normalized metadata.
  • Category values are Built In URL slugs, not arbitrary labels.
  • Salary and workplace fields are returned only when the source publishes them.
  • Built In search ranking can change between runs.
  • Direct HTTP is currently sufficient; there is no configurable or automatic residential proxy mode.
  • The Actor extracts public listings and does not bypass login, CAPTCHA, or private application systems.

Data handling and support

This Actor does not call an AI model or send input to an AI provider. It extracts published source material, which may itself contain source-generated content. Runtime dependencies are public Built In HTTP endpoints, Apify storage and billing, and private GlitchTip error diagnostics. The operator owns required service costs; there are no additional paid API keys or surprise dependency fees.

Dataset records may include names or contact details that an employer put in its public description; includeDescription=false omits that output text. No applicant accounts, resumes or private application data are collected. The Actor keeps no cross-run cache. Apify retains run datasets, inputs, logs and the summary under your account's storage settings until expiry or deletion; delete the run and its datasets/key-value store in Console or the API when no longer needed. Private diagnostic retention is 30 days. For support, open an issue on this Actor's Apify page with a run link and a minimal non-secret reproduction.

Built In is named only to identify the source. This independent automation-lab Actor is not affiliated with or endorsed by Built In.

Use the Actor only for lawful purposes and respect Built In's terms, robots guidance, intellectual-property rights, privacy requirements, and applicable employment-data rules. Public availability does not remove contractual or regulatory obligations.

Avoid republishing full descriptions without permission. Do not use the output for unlawful discrimination, unsolicited spam, or decisions that require protected personal information. Keep request volume proportionate, retain source URLs, and apply appropriate retention and security controls.

You are responsible for deciding whether your use case and jurisdiction permit collection and downstream processing.

Frequently asked questions

Does the Actor require a Built In account?

No. It extracts public job search and detail pages and does not log in.

Can it search remote jobs?

Yes. Supply https://builtin.com/jobs/remote in startUrls, or use another real Built In filtered URL.

Can it monitor changes automatically?

Use an Apify Schedule to create recurring snapshots, then compare records by jobId in your workflow. The Actor itself does not store historical versions or send alerts.

Why is salary null for some jobs?

Built In or the employer did not publish structured salary data for that posting. The Actor does not estimate missing salary.

Why did my company or location resolve unexpectedly?

Built In may return several similarly named matches. Use the exact public company name and a specific city/region string. The Actor prefers an exact match and otherwise uses the first Built In result.

Why did a run return fewer jobs than maxItems?

maxItems is a ceiling, not a guarantee. The search can have fewer current listings, duplicate URLs, removed details, or records that do not match filters on a supplied direct job URL.

What happens when a job expires during a run?

HTTP 404/410 or an explicit removed/expired notice is skipped without an item charge. A current posting whose structured data cannot be parsed is reported as a technical failure rather than silently treated as expired.

Use this Actor when Built In is the required source; use the related Actors when you need a different job-board or employer-career-page workflow.