Jobsite UK $1.5π° Jobs, Details & Company Scraper
Pricing
from $1.00 / 1,000 results
Jobsite UK $1.5π° Jobs, Details & Company Scraper
From $1/1K. Collect UK job listings from Jobsite.co.uk at scale. Search by keyword, location, filters, or paste search URLs. Returns 35+ clean fields per job from search pages. Optional detail mode adds full description, GPS coordinates, employment type, and company profile.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
8 days ago
Last modified
Categories
Share
Jobsite.co.uk Scraper: UK Job Listings with Salary, Employer and Skills Data
Jobsite.co.uk Scraper turns Jobsite.co.uk search results into a clean UK jobs dataset. Get 35+ fields per listing straight from the search page, including parsed salary (minimum, maximum, currency, period), employer details, skills, posting source, and sponsorship flags, at no extra cost. Search by keyword, location, and filters, or paste search-result URLs directly, then switch on full detail enrichment for the complete job description, GPS coordinates, employment type, valid-through date, and a company profile. Export the dataset as JSON, CSV, or Excel, or read it straight through the API.
Why This Scraper?
- 35+ listing fields per job, straight from the search page: parsed salary (min, max, currency, period), employer, skills, cross-post count, and sponsorship flags, with no extra cost.
- Optional full-detail enrichment. Turn on
fetchDetailsto add the complete job description, GPS coordinates, employment type, valid-through date, apply type, and a company profile (benefits, industries, jobs count). - Two ways to find jobs. Build a search from keyword, location, and filters, or paste one or more Jobsite.co.uk search-result URLs and let the run paginate them.
- Server-side filters that match the site's own facets. Keyword, location, job type, advertiser type, minimum salary with its own period, posted-within window, and sort order.
- One cap that matters.
maxListingsis the sole limit on job count (default20,0for unlimited);maxPagesis an optional extra safety ceiling, off by default. - Resumable and checkpointed. Point
resumeFromRunIdat a previous run to collect only the delta, and a long unlimited run checkpoints its own progress so a platform restart continues instead of starting over. - Built for schedules. Turn on
incrementalModeto get only new and changed jobs on a recurring run, and a fully blocked run fails loudly instead of returning an empty dataset.
Use Cases
- Job board aggregators: mirror Jobsite.co.uk listings into your own site or app alongside other sources.
- Salary and market researchers: build a dataset of parsed salary ranges by role, location, and job type.
- Recruitment agencies and sales teams: track which companies are hiring, and for what, to prioritize outreach.
- Compliance and brand teams: monitor a company's own postings for accuracy and recruitment marketing.
- Job alert products: schedule the actor with Incremental mode on and pipe only new matching roles into your app.
Data You Get
Sample shape: values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
jobId | 500000001 |
title | Assistant Warehouse Operative |
jobUrl | https://www.jobsite.co.uk/job/assistant-warehouse-operative/sample-company-job500000001 |
sourceSite | Totaljobs.com |
employer.name | Sample Company |
employer.url | https://www.jobsite.co.uk/jobs/sample-company?cmpId=1000001&cmp=1 |
location.text | Sample Town, Sample County (BA0), BA0 0AA |
location.postalCode | BA0 0AA |
salary.rawText | Β£26,000 - Β£29,500 per annum |
salary.min / salary.max | 26000 / 29500 |
salary.currency / salary.period | GBP / year |
datePosted | 2026-08-14T09:00:00.000Z |
workFromHome | Hybrid |
skills | ["Sample Skill A", "Sample Skill B"] |
textSnippet | Short preview text pulled from the listing appears here. |
crossPostedCount | 1 |
isSponsored | false |
description (fetchDetails only) | <p>Full HTML job description...</p> |
employmentType (fetchDetails only) | ["FULL_TIME"] |
validThrough (fetchDetails only) | 2026-09-14T00:00:00.000Z |
location.latitude / location.longitude (fetchDetails only) | 51.1500 / -2.3300 |
company.jobsCount (fetchDetails only) | 6 |
contactPhones / contactEmails (fetchDetails only) | ["+44 7700 900123"] / [] |
Every record also carries a rowType, a harmonisedId, publishFromDate/publishToDate, the employer's id and isAnonymous flag, location.region/country/streetAddress, the isHighlighted/isTopJob/isTrafficFromPartner flags, a partnership block (isBackfilled, isCrossPosted, isPartnershipJob, sourceSiteFriendlyName), and travelTime when the search included a distance. With fetchDetails on, a job can also carry applicantLocationRequirements, externalId, contractType, workType, a detailFetched flag, and a company object (name, founded, size, industries, benefits, videos, images, description). contactPhones and contactEmails are a best-effort harvest of any contact details a recruiter typed into the job description or exposed as a click-to-call/email link; the platform does not publish structured company contact details, so most records return empty arrays. In Incremental mode, every record also carries changeType, changedFields, firstSeenAt, and lastSeenAt.
How to Use
- Pick a mode:
search(build from filters) orurl(paste one or more search-result URLs). - Fill in your filters, and switch on
fetchDetailsif you need the full job description and company profile. - Set Max jobs to control run size and cost, then click Start.
- Download the dataset as JSON, CSV, or Excel, or read it through the API.
Basic search by location:
{"mode": "search","locations": ["London"],"maxListings": 20}
Keyword search with filters:
{"mode": "search","locations": ["Manchester"],"keywords": "nurse","jobType": "permanent","minSalary": 30000,"salaryType": "annual","postedWithin": "7","sortBy": "date","maxListings": 100}
Full details:
{"mode": "search","locations": ["London"],"keywords": "nurse","fetchDetails": true,"maxListings": 50,"proxy": { "useApifyProxy": true }}
Leave proxy at its default here; the actor sets up its own Residential GB/IE connection for detail fetches automatically, and setting apifyProxyGroups yourself instead changes which connection your listing pages use, not the detail pages.
Paginate search URLs directly (multiple supported):
{"mode": "url","urls": ["https://www.jobsite.co.uk/jobs/in-london","https://www.jobsite.co.uk/jobs/in-leeds"],"maxListings": 50}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/jobsite-co-uk-scraper").call(run_input={"mode": "search", "locations": ["London"], "maxListings": 20})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["title"], job["employer"]["name"], job["salary"]["rawText"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/jobsite-co-uk-scraper').call({ mode: 'search', locations: ['London'], maxListings: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How maxListings and maxPages shape a run
maxListings is the one cap that matters for job count (default 20; set 0 for unlimited), and is split evenly across every location or URL in the run. maxPages is an optional extra safety ceiling on pages walked per search or URL (25 jobs per page); left at its default of 0 it does not limit the walk at all, the run instead stops on its own once the site's own reported page count is reached, a page comes back empty, or a page returns nothing that hasn't already been collected earlier in this same run. There is no artificial page-number ceiling built in, so raise or lower maxPages only when you want an extra stop of your own.
That last stop condition, a page returning nothing new, is shared across the whole run, not scoped to one search: the ids it checks against include everything any location or URL in this same run has already collected, not just this search's own earlier pages. With more than one location or URL configured, a later search whose page happens to overlap entirely with an earlier search's already-collected jobs can stop there, before reaching its own genuinely new jobs further down. Keep a run to a single location or URL if you need a guarantee of reaching every result.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted or capped run: paste its run or dataset id and this run skips every job already in that dataset, returning only the new ones (a delta); combine both datasets for the full set. This works cleanly when the search's result order hasn't shifted since the interrupted run. If new jobs pushed older ones down the page order in the meantime, the resumed walk can hit a page made entirely of already-collected jobs and stop there before reaching genuinely new jobs further down, the same early-stop condition described under "How maxListings and maxPages shape a run" above, so a resumed run is not guaranteed to reach every remaining job. A long unlimited run also checkpoints its own progress, so a platform restart or a manual retry of a failed run picks up where it left off; if that checkpoint restart happens with Incremental mode andemitExpiredboth on, be aware that jobs from searches the restarted run skips entirely (because the checkpoint had already finished them) can be markedEXPIREDeven though they were never re-read this run, since the run's completeness check does not currently distinguish "skipped because already done" from "genuinely scanned." - Incremental mode (
incrementalMode) is for a search you run on a recurring schedule. Each job is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED. A job is only ever marked no-longer-present (the state that makes a later sightingREAPPEARED) once an earlier run hademitExpiredon and completed a full, uncapped scan of every search in scope; short of that, a job simply not reached this run keeps its last known state instead of being guessed at.EXPIREDrows themselves are only emitted, and billed, on a run that reaches that same natural, uncapped end, is not aresumeFromRunIdrun, and hasemitExpiredon. When you configure more than one location or URL in the same Incremental run, the shared early-stop condition described above means one search can occasionally end early because it overlapped with another search's results in this same run, and that early end is still counted as reaching the natural end, which can produce an incorrectEXPIREDrow for a job that was simply never reached rather than actually gone; keep each tracked scope to its own run if you rely onemitExpired.stateKeynames or shares the stored baseline; leave it empty to derive one automatically from your search filters. This is a separate mechanism from Resume: Resume finishes one specific run by id, Incremental mode tracks the same recurring search on its own between runs. Combining both is only meaningful once, to bootstrap a brand-new Incremental baseline from an existing Resume dataset; after that, astateKeywith saved state rejects a run that also setsresumeFromRunId, since resuming would prevent a full scan and make laterEXPIREDdetection unreliable. Note that a bootstrapped job from that first combined run has no prior fingerprint to compare against, so the very next ordinary Incremental run reports it asUPDATED(with every field listed as changed) rather thanUNCHANGED, and bills it again that once.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify β Settings β Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search builds a URL from filters; url paginates pasted search-result URLs. |
locations | array | prefill ["London"] | Towns, cities, counties, or regions (search mode). One search per location. Leaving it empty falls back to London, not all of the UK. |
keywords | string | (empty) | Job title, skill, or company to search for. Leave empty to list all jobs in the location. |
jobType | string | any | permanent, contract, temporary, part-time, or work-from-home. |
companyType | string | any | employer (direct) or agency. |
minSalary | integer | (empty) | Lowest salary to include, paired with salaryType. Leave empty for no minimum. |
salaryType | string | annual | Unit for minSalary: annual, daily, or hourly. |
postedWithin | string | "0" | Only jobs posted within 1, 3, 7, or 14 days. "0" = any time. |
sortBy | string | relevance | relevance, date, salary-desc, salary-asc, or distance. |
urls | array | prefill (one sample URL) | Search-result URLs to paginate (URL mode). Multiple supported; filter fields above are ignored. Pagination starts at the page in the URL and walks forward. |
fetchDetails | boolean | false | Open each job page for the full description, GPS coordinates, employment type, valid-through date, and company profile. Needs an Apify Residential GB connection. |
maxPages | integer | 0 | Optional safety limit on pages walked per location/URL (25 jobs per page). 0 = walk until the run's own stop conditions are met (see "How maxListings and maxPages shape a run" above). |
maxListings | integer | 20 | Total jobs to collect across all searches. The main limit. 0 = unlimited (still bounded by maxPages if set). |
maxResidentialRequests | integer | 0 | Cap on Residential connection requests this run may use, counted only for the actor's own automatic detail-page and listing-escalation connections, not for a Residential group you set yourself under proxy. 0 = unlimited. Once reached, listing falls back to the default connection and detail enrichment stops. |
resumeFromRunId | string | (empty) | Optional id of a previous run (or dataset) of this actor. Jobs already in that dataset are skipped, so this run returns only new jobs (a delta). |
incrementalMode | boolean | false | Track a recurring search across runs; only NEW/UPDATED jobs are returned by default. See "Resume and recurring updates" above. |
stateKey | string | (empty) | Optional label for the Incremental mode baseline. Leave empty to derive it automatically from the search filters. |
emitUnchanged | boolean | false | Incremental mode only. Also return (and bill) jobs with no change (changeType: UNCHANGED). |
emitExpired | boolean | false | Incremental mode only. Emit changeType: EXPIRED rows for jobs no longer found, only when this run reaches a natural, uncapped end. |
proxy | object | prefill (Apify proxy on) | Connection settings. Listing pages work on the default connection; fetchDetails needs Apify Residential with country GB. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live listing.
{"rowType": "job","sourceSearchUrl": "https://www.jobsite.co.uk/jobs/in-bristol","jobId": 500000001,"harmonisedId": "00000000-0000-0000-0000-000000000000","jobUrl": "https://www.jobsite.co.uk/job/assistant-warehouse-operative/sample-company-job500000001","sourceSite": "Totaljobs.com","title": "Assistant Warehouse Operative","datePosted": "2026-08-14T09:00:00.000Z","publishFromDate": "2026-08-14T09:00:00.000Z","publishToDate": "2026-09-11T09:00:00.000Z","employer": {"id": 1000001,"name": "Sample Company","url": "https://www.jobsite.co.uk/jobs/sample-company?cmpId=1000001&cmp=1","logoUrl": "https://www.jobsite.co.uk/CompanyLogos/00000000000000000000000000000000.png","isAnonymous": false},"location": {"text": "Sample Town, Sample County (BA0), BA0 0AA","postalCode": "BA0 0AA","locality": null,"region": null,"country": null,"latitude": null,"longitude": null,"streetAddress": null},"salary": { "rawText": "Β£26,000 - Β£29,500 per annum", "min": 26000, "max": 29500, "currency": "GBP", "period": "year" },"workFromHome": null,"skills": ["Sample Skill A", "Sample Skill B"],"textSnippet": "Short preview text pulled from the listing appears here.","crossPostedCount": 1,"isSponsored": false,"isHighlighted": false,"isTopJob": false,"isTrafficFromPartner": false,"partnership": { "isBackfilled": true, "isCrossPosted": false, "isPartnershipJob": true, "sourceSiteFriendlyName": "Totaljobs.com" },"travelTime": null,"description": null,"descriptionText": null,"validThrough": null,"employmentType": null,"industry": null,"directApply": null,"applyType": null,"jobLocationType": null,"applicantLocationRequirements": null,"externalId": "00000000-0000-0000-0000-000000000000","contractType": null,"workType": null,"company": null,"contactPhones": [],"contactEmails": [],"detailFetched": false}
Plan Requirement
The default listing run works using the default connection setting, proxy: { "useApifyProxy": true }. Full details (fetchDetails) need an Apify Residential connection with country GB, which the actor sets up for itself automatically for detail-page requests only, whatever your own proxy setting says (unless you supply your own proxy URLs); if the account has no residential access, the run logs a warning, skips detail enrichment automatically, and still returns the listing fields. Setting a Residential group yourself under proxy changes which connection your listing pages use instead, and that usage is not counted by maxResidentialRequests, which only caps the actor's own automatic residential requests for detail pages and listing escalation.
FAQ
How much does it cost?
You pay per record returned, plus a surcharge only for jobs whose detail page was actually fetched and pushed with fetchDetails on. The Pricing tab shows the current rates. Use Max jobs to cap the cost of any run.
Is it legal to scrape Jobsite.co.uk?
This actor collects only publicly available job listings. You are responsible for how you use the data: follow Jobsite.co.uk's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution, especially for any personal or contact details a posting happens to include.
Can I get only new or changed jobs on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated jobs, and unchanged ones are not billed.
Why did my fetchDetails run only return listing fields?
fetchDetails needs an Apify Residential connection with country GB, which the actor sets up for itself automatically for detail-page requests, regardless of your own proxy setting (unless you supply your own proxy URLs). If your account has no residential access, the run logs a warning, turns detail enrichment off for that run, and returns the listing fields only, instead of failing. Leave proxy at its default; setting proxy.apifyProxyGroups: ["RESIDENTIAL"] yourself does not enable detail fetching, it changes which connection your listing pages use instead.
Why did my run fail instead of returning an empty dataset?
If every request is refused, the run stops with a clear connection-problem message instead of looking like "no jobs matched". A search that genuinely matches nothing still succeeds, with a status message saying so. Retry a failed run in a few minutes, or with an Apify Residential GB connection.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear, or Airtable.
π Want more jobs data?
Pair this actor with these related scrapers from the same team:
| πΌ Totaljobs Scraper Scrape UK job listings from Totaljobs.com by keyword, location, filters, or URL. Extract... | πΌ Reed.co.uk Scraper Scrape Reed.co.uk jobs, companies, courses, and reviews. Search by keyword, location... |
| π¨ Caterer.com Scraper Scrape UK hospitality jobs from Caterer.com, including chef, hotel, restaurant, bar, and... | π BizQuest Scraper From $1/1K. Extract business-for-sale, franchise, and asset listings from BizQuest... |
| πΌ Nofluffjobs From $1/1K. Extract IT jobs from NoFluffJobs.com across Poland, Czechia, Slovakia... | πΌ NHS UK From $0.8/1k. Scrape nhs.uk Jobs listings into a flat dataset. Extract 50+ fields... |
π Browse all abotapi scrapers
π¬ Support & custom scrapers
- π Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- π οΈ Need another site, extra fields or a private build? Email contact@abotapi.com or message Telegram @abotapi.
- β Enjoying it? A quick review on the actor page helps other users find it.