Savills Scraper [From $1💰] | Property Listings | Prices
Pricing
from $0.80 / 1,000 results
Savills Scraper [From $1💰] | Property Listings | Prices
Extract Savills property listings worldwide with local-currency prices, tenure, EPC rating, bedrooms, size, coordinates, agent contacts, photos and floor plans. Optional detail pages add full property data for market research.
Pricing
from $0.80 / 1,000 results
Rating
0.0
(0)
Developer
Ahmed Jasarevic
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Savills Scraper — Scrape Worldwide Savills Property Listings Data
Scrape residential, luxury, new-build, farm and commercial listings from Savills' global search site into JSON — ~90 mapped fields per listing: price in local currency, tenure, EPC rating, status tags, coordinates, photos and agent contacts. Built for luxury-market analysts, cross-border investors, proptech dashboards and relocation / buyer agencies who need structured Savills listings data on a schedule.
What You Can Build With Savills Property Data
- A UK property listings database with EPC rating data, tenure, council tax band, service charge and ground rent on every row.
- Property price monitoring UK workflows —
status,originalPrice,priceQualifier,lastUpdated,_scrapedAtare your diff inputs between runs. - International coverage — verified Savills pages carry Europe 13,173 listings, France 1,047, Italy 317 and a Spain desk: cross-border property investment data.
- New homes listings data from
/list/new-homes-for-sale/and/list/new-homes-to-rent/, flaggedisNewDevelopment,isHelpToBuy,isSharedOwnership. - Commercial property listings API-style feeds — office, retail, industrial, leisure, investment and hotel paths with
isCommercial,isFarm,clearHeight. - Real estate market intelligence pipelines — lat/lng, size in sqm/sqft/acres/hectares, images, floor plans, brochures, agent phone numbers.
How The Savills Scraper Works
Savills' search application (search.savills.com) server-renders every listing into a Next.js __NEXT_DATA__ JSON blob. This Actor fetches those pages with plain HTTP through a CheerioCrawler — no browser, no headless Chrome — parses the blob, and maps it to one dataset item per listing. Detail pages are small JSON requests too, so runs stay fast and need no paid anti-bot service.
Input Parameters
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
searchUrls | array | No (prefilled) | England sale | Full or partial URLs (https://search.savills.com/list/property-for-sale/england) or bare paths like /list/property-for-sale/italy, expanded against search.savills.com; a /page/N suffix is stripped so crawls restart at page 1. |
maxListings | integer | No | 100 | Stop condition: the run ends once this many listings are collected (min 1, max 5000). Free plans cap at 10. |
scrapeDetailPages | boolean | No | false | Also open each /property-detail/<id> page and merge it — adds the detail-only fields listed under Output Fields plus a complete size block. One extra request per listing, billed as one property-detail-page event. |
proxy | object | No | { "useApifyProxy": false } | Standard Apify proxy picker; select group/country in the UI — the only likely extra cost. |
How a run stops — no page cap; maxListings drives everything:
- a listing slot is reserved when a search card is seen, so the cap is exact;
- pagination stops at the cap, at a page with no new listings, or when the page budget
ceil(maxListings / 16) + 3per search URL is spent — whichever comes first; maxRequestsPerCrawlbounds the run:search URLs × page budget + maxListings detail requests + 40.
Supported search URL shapes:
/list/property-for-sale/<location> e.g. england, scotland, wales, italy, france, spain, australia/list/property-to-rent/<location>/list/new-homes-for-sale/<location>/list/new-homes-to-rent/<location>/list/farms/<sub-category>/<location>/list/commercial/property-for-sale/<type>/<location> office, retail, industrial, leisure, investment, hotel/list/commercial/property-to-let/<type>/<location>/list/<location>/<region>/... deeper paths such as england/london/london/ec3n
Output Fields
One dataset item per listing (~90 mapped fields); two table views ship with it: Listing overview and Listing table.
- Identity —
listingId,internalId,externalIdFormatted,url,seoTitle,description,longDescription,locationNotes,features - Price —
price,displayPrice,originalPrice,priceQualifier,currency,otherFees,priceDisclaimer,yield - Location —
countryCode,regionOrTown,addressLine1,addressLine2,fullAddress,latitude,longitude,openHouse - Type —
propertyTypes,propertyTypeTag,propertyTypeSlug,marketTypes,isCommercial,isFarm,isNewDevelopment,newDevelopmentType,isHelpToBuy,isSharedOwnership,furnished,sizeDescription - Status tags —
status,statusCode,statusTag,isSold,isLet,isConfidential,isFeatured,launchingDate - Rooms & size —
bedrooms/bedroomsText,bathrooms/bathroomsText,receptions/receptionsText,carSpaces/carSpacesText,sizeFormatted,size(sqm,sqft,sqYd,acres,hectares),clearHeight - Tenure / compliance —
tenure,tenureTypeCode,leaseType,leaseExpiry,leaseRemaining,serviceCharge,groundRent,councilTaxBand,epcRating,energyText - Agents —
primaryAgent,secondaryAgent(name,phone,office,photo,licenceNumber,whatsapp) - Media —
images,imageCount,imageCaptions,floorPlans,brochureUrls,epcGraphUrls,floorPlanPdfUrl,videoUrl,video360Url,externalWebsiteUrl,agentQuote - Detail-page extras —
lastUpdated,fullPriceText,shortDisplayPrice,hasFloorplan,fluxProBrochureUrl,additionalAgents,areaGuide,sizeMaximum,saleableArea - Meta —
_source(search-list,search-list+property-detail,property-detail),_scrapedAt
EPC rating, tenure, service charge, ground rent and council tax band are parsed from Savills' free-text AdditionalInformation array; status tags plus originalPrice and priceQualifier drive change detection.
Example Input And Output
{"searchUrls": [{ "url": "https://search.savills.com/list/property-for-sale/england" },{ "url": "/list/property-to-rent/italy" }],"maxListings": 100,"scrapeDetailPages": false,"proxy": { "useApifyProxy": false }}
{"listingId": "GBCSRSCIS260102","url": "https://search.savills.com/property-detail/GBCSRSCIS260102","price": 850000,"displayPrice": "£850,000","priceQualifier": "Guide price","currency": "GBP","fullAddress": "City of London, London EC3N","latitude": 51.512,"longitude": -0.083,"status": "Under offer","bedrooms": 2,"sizeFormatted": "1,179 sq ft","tenure": "Share of freehold","councilTaxBand": "D","epcRating": "C","primaryAgent": { "name": "Jane Smith", "phone": "+44 20 7000 0000", "office": "Savills City" },"_source": "search-list","_scrapedAt": "2026-10-07T09:15:00.000Z"}
Build Savills Listings Data Without An Official API
There is no public Savills API — api.savills.com 404s every probed route, no developer portal. This Actor reads the surface Savills' own frontend consumes.
| What | Value |
|---|---|
| Host | https://search.savills.com |
| Search / list URL | https://search.savills.com/list/<path> |
| Pagination | https://search.savills.com/list/<path>/page/<n> |
| Property detail URL | https://search.savills.com/property-detail/<externalPropertyId> |
| Data blob | <script id="__NEXT_DATA__" type="application/json"> |
| JSON path used | props.initialReduxState.properties (lists), props.initialReduxState.propertyDetail.property (details) |
| Pagination metadata | props.initialReduxState.listPage.{currentPage,totalItems,pageMap} + pageMap.<n>.metaData.NextUrl |
Marketing pages on www.savills.com / www.savills.co.uk carry no listing data; results live in a separate application whose config, published at https://search.savills.com/js/endpoints.js, exposes dataEndpoint: https://livev6-searchapi.savills.com (plus livev6-profile, livev6-authentication and assets.savills.com) — the fallback surface if the SSR blob ever disappears.
Instead of guessing undocumented paths on the private livev6-searchapi host, the SSR blob was chosen because it is:
- The richest source — one 89-field object per listing (price, tenure, EPC, service charge, agent, floor plans, brochures, coordinates); no equivalent public REST shape.
- Authenticated and stable — the exact payload the frontend consumes, so it cannot drift behind an internal API contract.
- Free — plain HTTP via the standard Apify proxy; no paid anti-bot API for residential pages.
- Server-rendered — listings sit in the first byte range; JavaScript never runs.
Parse gotcha: the blob can hold a literal </script> inside a string (descriptions embed HTML), so naive indexOf('</script>') truncates the JSON mid-string — the Actor slices generously and lets JSON.parse find the real end. curl also needs --compressed, or Savills' gzip stream arrives truncated.
Complete Property Detail Pages With scrapeDetailPages
Measured against search.savills.com (residential, England):
- card and detail page share 86 identical fields — price, description, agents, galleries, coordinates and
AdditionalInformationmatch byte for byte, so detail never corrects a card value; - detail carries 47 extra fields, the useful ones mapped into the output (listed under Output Fields);
sizeis completed there: the card leavesAvailableSizeall-zero and renders only"1,179 sq ft", while detail carries the numericSizeblock with acres, hectares, square yards and ping — unrecoverable from card text;- detail responses cost 60–240 ms vs 300–900 ms for a list page. At
maxConcurrency: 5: 40 listings without detail pages = 3 requests in 2.7 s; the same 40 with detail pages = 43 requests in 9 s.
Because the dataset is append-only, scrapeDetailPages: true defers each row until its detail page lands, then writes it once with both sources merged; a failed detail page always falls back to search-card data.
Scrape Savills At Scale: AWS WAF Limits, Rate Control And Running Cost
Savills serves search.savills.com behind AWS WAF — the awsWafCookieDomainList challenge returned as HTTP 202 with a JS body instead of the page. The Actor:
- retries a 202 up to 3 times with escalating backoff 8s / 16s / 24s;
- crawls at
maxConcurrency: 5withuseSessionPooland no keep-alive — 12 parallel detail requests passed untouched, but sustained single-IP volume eventually triggers the challenge; - stops globally the moment
maxListingsis reserved.
Residential pages work from ordinary IPs. The WAF is rate-based, not path-based: a burst from one IP challenges every path, including ones that worked seconds earlier. Commercial and farm paths challenge sooner.
Running cost: no paid anti-bot API (Scrapfly/Zyte) is required; sustained volume may need the Apify proxy input with a residential group — the only likely extra cost. Code limits: maxRequestsPerCrawl, maxConcurrency: 5, maxRequestRetries: 3, 60s handler timeout, page budget, listing cap.
Pricing, Free Tier And Pay-Per-Event Billing
| Event | Price |
|---|---|
result | $0.0009 (FREE), stepping down to $0.0008 |
Details | $0.0009 → $0.0008 |
Actor Start | $0.00005 per run |
Free plans are capped at 10 listings (APIFY_USER_IS_PAYING gate); paid plans run up to maxListings.
Detail work is billed as property-detail-page, once per detail page fetched — only with scrapeDetailPages: true:
- billed whether the page merges or falls back to search-card data;
- nothing is billed with
scrapeDetailPages: false, and on a non-pay-per-event ActorActor.charge()is a documented no-op; - the charge lands the moment the page is fetched (never batched); at the spending limit the crawl stops via
crawler.autoscaledPool.abort()and held rows flush as search-card rows; - on
aborting, waiting rows are pushed inside the 30-second window.
Define the event in Monetization (Console → Actor → Monetization → pricing) with a price and discount tiers — undefined events are free. Test locally with ACTOR_TEST_PAY_PER_EVENT=true ACTOR_USE_CHARGING_LOG_DATASET=true apify run (charges log to storage/datasets/charging_log).
Savills vs Rightmove vs Zoopla: Which Source For UK Property Listings
Savills is an agency site — its own instructions with agency-level depth (EPC, tenure, service charge, agent, brochures) but only Savills stock. Rightmove, Zoopla and OnTheMarket are portals with far broader UK volume and normalised records. Claims are from each actor's Store page:
| Actor | Store-page claim |
|---|---|
| epctex/rightmove-scraper | 4.98★, 167 users, 51 fields, $0.40/1,000 properties |
| tri_angle/fast-zoopla-properties-scraper | Apify-published, 4.85★, 194 users, $0.001/result |
| one-api/zoopla-property-scraper | sold-price history, sale/rent estimates, tenure, $0.003/result |
| fatihtahta/onthemarket-scraper | $1.99 per 1,000 results |
Direct Savills rivals: stealth_mode/savills-property-search-scraper (130+ fields, bulk URLs), shahidirfan/savills-property-scraper (commercial, ~33 fields), nocodeventure/savills-property-scraper (UK detail mode), rigelbytes/savills-scraper ($2/1,000). Land registry alternative for transactions: GOV.UK Land Registry API, Homedata, Propalt. Southern Europe: igolaizola/idealista-scraper (2,422 users), memo23/idealista-scraper (80+ fields). Unified UK: jungle_synthesizer/rightmove-zoopla-onthemarket-uk-scraper ($0.001/record).
Run Savills Scraper From The Apify API, Console Or Schedule
Start runs from the Console (fill the four fields, press Start) or through the API:
curl -X POST https://api.apify.com/v2/acts/YcKKGzgNPHHgwny0O/runs \-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \-d '{"searchUrls":[{"url":"https://search.savills.com/list/property-for-sale/england"}]}'
Then poll GET /v2/actor-runs/<runId> and read rows from GET /v2/datasets/<datasetId>/items?format=json.
Integrations & Automation
- Webhooks — fire on
actor.succeeded/actor.failedto push rows into a warehouse, Google Sheets or Slack. - Zapier / Make — supported by Apify, so a new dataset item can become a CRM record or deal-alert email without code.
- Schedules — run daily (price cuts, sales alerts) or weekly (dashboards), e.g. cron
0 6 * * *; keepmaxListingsstable so dataset diffs stay meaningful.
Related Actors
- savills-property-search-scraper
- savills-property-scraper
- rightmove-scraper
- fast-zoopla-properties-scraper
- onthemarket-scraper
FAQ
Is there an official Savills API?
No. api.savills.com 404s every probed route and there is no developer portal; this Actor reads the public server-rendered __NEXT_DATA__ payload from search.savills.com instead.
What's the best way to scrape Savills listings programmatically?
Fetch /list/<path> over plain HTTP, extract the <script id="__NEXT_DATA__"> blob and read props.initialReduxState.properties — an 89-field object per row, no JavaScript. That is this Actor's approach.
Savills vs Rightmove vs Zoopla — which should I scrape for UK coverage?
Savills gives agency-level depth on prime, new-build, farm and commercial stock; the portals give raw volume across many agencies. Many teams run both, or a unified cross-portal actor.
How can I get UK property listings data via API?
Homedata, Propalt or the GOV.UK Land Registry API (price-paid transactions), or actors like this one via the Apify API. As a land registry alternative, Homodata layers transactions with listings and EPC.
How do I monitor UK property price changes automatically?
Schedule daily or weekly, hold maxListings constant and diff datasets on listingId; webhooks alert you when a run finishes.
What are the alternatives to Savills Scraper?
stealth_mode/savills-property-search-scraper (130+ fields), nocodeventure/savills-property-scraper (UK detail mode), rigelbytes/savills-scraper ($2/1,000), plus the Rightmove, Zoopla, OnTheMarket and Idealista scrapers.
SEO Keywords
savills scraper, savills api, savills listings data, savills property data, savills property scraper, savills alternative, uk property listings database, uk property data, luxury property market data, property price monitoring uk, new homes listings data, commercial property listings api, cross-border property investment data, real estate market intelligence, epc rating data, property tenure data, land registry alternative, savills vs rightmove, rightmove scraper, zoopla scraper, onthemarket scraper, knight frank scraper, savills france property listings, savills italy property listings, savills spain property listings
For AI Agents & LLM Apps
Purpose: fetch Savills search pages → one JSON dataset row per listing, ~90 fields: price + local currency, tenure, EPC, status, size, coordinates, agent contacts, media.
Minimal input:
{ "searchUrls": [{ "url": "https://search.savills.com/list/property-for-sale/england" }] }
Variant with detail pages:
{ "searchUrls": [{ "url": "https://search.savills.com/list/property-for-sale/england" }], "maxListings": 50, "scrapeDetailPages": true }
Output fields: listingId, internalId, externalIdFormatted, url, seoTitle, description, longDescription, locationNotes, features, price, displayPrice, originalPrice, priceQualifier, currency, otherFees, priceDisclaimer, yield, countryCode, regionOrTown, addressLine1, addressLine2, fullAddress, latitude, longitude, openHouse, propertyTypes, propertyTypeTag, propertyTypeSlug, marketTypes, isCommercial, isFarm, isNewDevelopment, newDevelopmentType, isHelpToBuy, isSharedOwnership, furnished, sizeDescription, status, statusCode, statusTag, isSold, isLet, isConfidential, isFeatured, launchingDate, bedrooms, bedroomsText, bathrooms, bathroomsText, receptions, receptionsText, carSpaces, carSpacesText, sizeFormatted, size, clearHeight, tenure, tenureTypeCode, leaseType, leaseExpiry, leaseRemaining, serviceCharge, groundRent, councilTaxBand, epcRating, energyText, primaryAgent, secondaryAgent, images, imageCount, imageCaptions, floorPlans, brochureUrls, epcGraphUrls, floorPlanPdfUrl, videoUrl, video360Url, externalWebsiteUrl, agentQuote, lastUpdated, fullPriceText, shortDisplayPrice, hasFloorplan, fluxProBrochureUrl, additionalAgents, areaGuide, sizeMaximum, saleableArea, _source, _scrapedAt.
Behaviors an agent should know:
maxListingsis the only stop condition (default 100, max 5000); free plans cap at 10 listings regardless of input.scrapeDetailPagesdefaults tofalse; bare paths expand tosearch.savills.comand/page/Nis stripped so pagination restarts at page 1.- With detail pages on, a row is withheld until its detail page lands; failures fall back to search-card data and are still written (
_sourcerecords the source). - Detail charges land on fetch even on fallback; the spending limit calls
crawler.autoscaledPool.abort()and pending rows flush as search-card rows (onaborting, within 30 s). - A 202 WAF challenge is retried 3 times (8s/16s/24s) at
maxConcurrency: 5; commercial and farm paths challenge sooner.
Billing: pay-per-event — result ($0.0009 FREE → $0.0008), Details ($0.0009 → $0.0008), Actor Start ($0.00005/run); property-detail-page fires once per fetched detail page.
Legal & Compliance Disclaimer
This Actor is an independent project and is not affiliated with, endorsed by or sponsored by Savills plc or any Savills group company.
It accesses only publicly served pages on search.savills.com — server-rendered HTML any ordinary browser receives; no login, no authentication bypass, no paid anti-bot bypass.
search.savills.com/robots.txt allows / for generic crawlers and disallows /contact/, /forms/ and /_inc/ (plus Crawl-Delay: 5 for named bots like ClaudeBot, Bingbot, AhrefsBot) — this Actor requests only listing paths. Output is for personal, non-commercial use in respect of Savills' terms; you are responsible for compliance with those terms and with applicable data-protection law (GDPR/CCPA where relevant).
The dataset includes agent names and phone numbers — public business contact details published on listing pages — which must not be used for unsolicited commercial outreach in violation of applicable law.