Built In Jobs Scraper
Pricing
from $0.48 / 1,000 job listing extracteds
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
Maintained by CommunityActor 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 engineerordata 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:
maxItemscaps 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?
| Field | Type | Description |
|---|---|---|
jobId | string | Stable Built In job ID |
title | string | Published job title |
company | string | Hiring employer |
companyUrl | string or null | Employer profile or website URL |
location | string | Readable combined location |
locations | array | Structured city, region, and country values |
workplaceType | string or null | Published Remote, Hybrid, or On-site label (source In-Office becomes On-site); structured Remote takes precedence |
seniority | string or null | Explicit current-job experience label, such as Entry level |
employmentType | array | Values such as FULL_TIME |
salaryMin | number or null | Published salary minimum |
salaryMax | number or null | Published salary maximum |
salaryCurrency | string or null | Currency code, such as USD |
salaryPeriod | string or null | Period, such as YEAR or HOUR |
datePosted | string or null | Source posting date |
validThrough | string or null | Source expiry timestamp |
description | string or null | Normalized full description when enabled |
skills | array | Structured skills, or explicit labels from the current job's Skills Required section |
industries | array | Published industry labels |
applyUrl | string or null | Public direct application URL when available |
url | string | Canonical Built In posting URL |
scrapedAt | string | UTC 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
- Open the Actor in Apify Console.
- Enter a
query, such assoftware engineer. - Optionally add
location,company, or a Built Incategoryslug. - Alternatively, paste one or more Built In job or search URLs into
startUrls. - Choose
maxItemsand whether full descriptions should be included. - Click Start.
- Open the Dataset tab to inspect or export the results.
A useful first run is:
{"query": "software engineer","maxItems": 25,"includeDescription": true}
Input parameters
| Input | Type | Default | Meaning |
|---|---|---|---|
startUrls | array | empty | Built In /jobs search/category URLs or /job/... detail URLs |
query | string | empty | Title, skill, or keyword search |
location | string | empty | City or region resolved through Built In, for example New York, NY |
company | string | empty | Employer resolved through Built In, for example Smartly |
category | string | empty | Built In category slug, such as developer-engineer |
maxItems | integer | 100 | Maximum records, from 1 to 5,000 |
includeDescription | boolean | true | Include normalized full descriptions |
maxRequestRetries | integer | 2 | Retries 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
- Save a focused Actor input.
- Create an Apify Schedule for the desired interval.
- Use
jobIdorurlas the stable comparison key. - Store the previous result set in your own database or key-value record.
- Compare fields such as
datePosted,validThrough, salary, or description. - 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
jobIdin 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 osfrom apify_client import ApifyClientclient = 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().itemsprint(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
- Discover a stable subset. Use the Actor-specific endpoint above and read-only
tools/listto discover actual names and argument schemas. Actor selection also addsget-actor-run,get-dataset-items,get-key-value-store-record, andabort-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. - Start once after authorization. Retain the returned run ID, status and storage IDs: these are metadata, not job rows.
call-actorwaits at mostwaitSecs0–45 seconds (default 30), so do not assume completion. For a nonterminal run, check that same run withget-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. - Fetch bounded job rows. After success, use
get-dataset-itemswith the returned dataset ID (defaultDatasetIdin the run API), explicitlimit=20,offset=0initially, and fields such asjobId,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. - 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
maxItemswhile validating a new search. - Use specific location text when autocomplete could return several places.
- Use an exact company name when possible.
- Turn off
includeDescriptionwhen 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.
Responsible and legal use
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.
Related automation-lab Actors
- Company Career Page Jobs Scraper — normalize jobs from supplied employer career pages.
- StepStone Jobs & Employer Contacts Scraper — search StepStone and enrich employer context.
- iCIMS Jobs Scraper — collect public jobs from iCIMS-powered career sites.
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.