Vexaloom Labs

Fotocasa Spain Sale & Rental Listings Scraper

Search Fotocasa listings for sale or rent across Spain by city, property type, price range, and bedrooms. Each result includes price, size, bedrooms, bathrooms, location, images, and the listing URL.

Input schema

Input fields, types, required flags, descriptions, defaults, and prefills come from the published definition. Prefill examples are distinct from defaults.

FieldTypeRequiredDescription
modestringrequiredHow to find listings: search by location, scrape Fotocasa search URLs, or scrape individual property URLs/IDs.
locationstringoptionalCity, province, district, neighborhood, street or ZIP code, e.g. Madrid, Barcelona, Sitges, 28001. Used in Search by location mode.
locationTypestringoptionalNarrow ambiguous place names to a level. Auto picks the best match (usually the municipality).
Show all input fields
FieldTypeRequiredDescription
modestringrequiredHow to find listings: search by location, scrape Fotocasa search URLs, or scrape individual property URLs/IDs.
locationstringoptionalCity, province, district, neighborhood, street or ZIP code, e.g. Madrid, Barcelona, Sitges, 28001. Used in Search by location mode.
locationTypestringoptionalNarrow ambiguous place names to a level. Auto picks the best match (usually the municipality).
operationstringoptionalSale, rent, room share, rent-to-buy or business transfer.
propertyTypestringoptionalProperty category. Subtypes such as penthouses, studios and duplex are preserved instead of being collapsed into homes.
minPriceintegeroptionalServer-side minimum sale price or monthly rent.
maxPriceintegeroptionalServer-side maximum sale price or monthly rent.
minRoomsintegeroptionalServer-side minimum number of bedrooms.
maxRoomsintegeroptionalServer-side maximum number of bedrooms.
minBathroomsintegeroptionalServer-side minimum number of bathrooms.
maxBathroomsintegeroptionalServer-side maximum number of bathrooms.
minSurfaceintegeroptionalServer-side minimum built surface.
maxSurfaceintegeroptionalServer-side maximum built surface.
featuresarrayoptionalOnly listings with these features. Multiple selections are combined (AND). Leave empty for no feature filter.
publishedSincestringoptionalOnly keep listings published inside this window. Searches newest-first and stops at the cutoff.
rentalTypestringoptionalFor rent searches only: long-term or temporary rental. Uses Fotocasa's rental path filter.
ownerTypestringoptionalPrivate owners or professional agencies. Private-only uses Fotocasa's particulares path.
onlyPriceDropsbooleanoptionalOnly emit listings that show a price reduction.
sortBystringoptionalVerified Fotocasa sort orders.
maxItemsintegeroptionalHard cap on emitted listings (1–10,000). Above ~9,900 rows the actor automatically splits the search into price buckets.
startUrlsarrayoptionalFotocasa search URLs to scrape. Filters in each URL win over the form fields. Property URLs found here are routed to detail mode.
propertyUrlsarrayoptionalIndividual Fotocasa detail URLs, new-construction project URLs, or numeric property IDs.
fetchDetailsbooleanoptionalFetch each listing's detail page to add energy certificate, agency phone and registrations, exact street, ground surface and extra features. Slower and more requests.
maxDetailsintegeroptionalLimit detail requests when Fetch details is on. 0 means all emitted listings.
monitorModebooleanoptionalEmit only new listings and listings whose price changed, using Actor state between runs. The state key is namespaced by monitorKey or the search filters.
monitorKeystringoptionalOptional namespace for monitor state. Leave empty to derive it from the search filters.

Download the published input schema

View complete JSON
{
  "description": "Search Fotocasa by location or paste search/property URLs. Get full listing records with price, surface, rooms, location, agency, media, new-construction projects and optional detail enrichment.",
  "properties": {
    "features": {
      "default": [],
      "description": "Only listings with these features. Multiple selections are combined (AND). Leave empty for no feature filter.",
      "editor": "select",
      "items": {
        "enum": [
          "elevator",
          "terrace",
          "balcony",
          "pool",
          "garden",
          "parking",
          "storageRoom",
          "airConditioning",
          "heating",
          "furnished",
          "notFurnished",
          "internet",
          "petsAllowed",
          "bankOwned",
          "subsidised"
        ],
        "enumTitles": [
          "Lift",
          "Terrace",
          "Balcony",
          "Pool",
          "Garden",
          "Parking",
          "Storage room",
          "Air conditioning",
          "Heating",
          "Furnished",
          "Not furnished",
          "Internet",
          "Pets allowed",
          "Bank-owned",
          "Subsidised housing"
        ],
        "type": "string"
      },
      "prefill": [],
      "title": "Features",
      "type": "array",
      "uniqueItems": true
    },
    "fetchDetails": {
      "default": false,
      "description": "Fetch each listing's detail page to add energy certificate, agency phone and registrations, exact street, ground surface and extra features. Slower and more requests.",
      "prefill": false,
      "sectionCaption": "Details and monitoring",
      "title": "Fetch details",
      "type": "boolean"
    },
    "location": {
      "default": "",
      "description": "City, province, district, neighborhood, street or ZIP code, e.g. Madrid, Barcelona, Sitges, 28001. Used in Search by location mode.",
      "editor": "textfield",
      "prefill": "madrid",
      "title": "Location",
      "type": "string"
    },
    "locationType": {
      "default": "auto",
      "description": "Narrow ambiguous place names to a level. Auto picks the best match (usually the municipality).",
      "editor": "select",
      "enum": [
        "auto",
        "country",
        "autonomousCommunity",
        "province",
        "municipality",
        "district",
        "neighborhood",
        "locality",
        "street",
        "zipCode"
      ],
      "enumTitles": [
        "Auto",
        "Country",
        "Autonomous community",
        "Province",
        "Municipality",
        "District",
        "Neighborhood",
        "Locality",
        "Street",
        "ZIP code"
      ],
      "prefill": "auto",
      "title": "Location type",
      "type": "string"
    },
    "maxBathrooms": {
      "description": "Server-side maximum number of bathrooms.",
      "maximum": 20,
      "minimum": 0,
      "title": "Maximum bathrooms",
      "type": "integer"
    },
    "maxDetails": {
      "default": 100,
      "description": "Limit detail requests when Fetch details is on. 0 means all emitted listings.",
      "maximum": 10000,
      "minimum": 0,
      "prefill": 0,
      "title": "Maximum detail pages",
      "type": "integer"
    },
    "maxItems": {
      "default": 100,
      "description": "Hard cap on emitted listings (1–10,000). Above ~9,900 rows the actor automatically splits the search into price buckets.",
      "maximum": 10000,
      "minimum": 1,
      "prefill": 3,
      "sectionCaption": "Volume",
      "title": "Maximum listings",
      "type": "integer"
    },
    "maxPrice": {
      "description": "Server-side maximum sale price or monthly rent.",
      "maximum": 100000000,
      "minimum": 0,
      "title": "Maximum price (EUR)",
      "type": "integer"
    },
    "maxRooms": {
      "description": "Server-side maximum number of bedrooms.",
      "maximum": 20,
      "minimum": 0,
      "title": "Maximum bedrooms",
      "type": "integer"
    },
    "maxSurface": {
      "description": "Server-side maximum built surface.",
      "maximum": 100000,
      "minimum": 0,
      "title": "Maximum surface (m²)",
      "type": "integer"
    },
    "minBathrooms": {
      "description": "Server-side minimum number of bathrooms.",
      "maximum": 20,
      "minimum": 0,
      "title": "Minimum bathrooms",
      "type": "integer"
    },
    "minPrice": {
      "description": "Server-side minimum sale price or monthly rent.",
      "maximum": 100000000,
      "minimum": 0,
      "title": "Minimum price (EUR)",
      "type": "integer"
    },
    "minRooms": {
      "description": "Server-side minimum number of bedrooms.",
      "maximum": 20,
      "minimum": 0,
      "title": "Minimum bedrooms",
      "type": "integer"
    },
    "minSurface": {
      "description": "Server-side minimum built surface.",
      "maximum": 100000,
      "minimum": 0,
      "title": "Minimum surface (m²)",
      "type": "integer"
    },
    "mode": {
      "default": "search",
      "description": "How to find listings: search by location, scrape Fotocasa search URLs, or scrape individual property URLs/IDs.",
      "editor": "select",
      "enum": [
        "search",
        "startUrls",
        "propertyUrls"
      ],
      "enumTitles": [
        "Search by location",
        "Search URLs",
        "Property URLs / IDs"
      ],
      "prefill": "search",
      "sectionCaption": "Mode",
      "title": "Mode",
      "type": "string"
    },
    "monitorKey": {
      "default": "",
      "description": "Optional namespace for monitor state. Leave empty to derive it from the search filters.",
      "editor": "textfield",
      "prefill": "",
      "title": "Monitor key",
      "type": "string"
    },
    "monitorMode": {
      "default": false,
      "description": "Emit only new listings and listings whose price changed, using Actor state between runs. The state key is namespaced by monitorKey or the search filters.",
      "prefill": false,
      "title": "Monitor mode",
      "type": "boolean"
    },
    "onlyPriceDrops": {
      "default": false,
      "description": "Only emit listings that show a price reduction.",
      "prefill": false,
      "title": "Only price drops",
      "type": "boolean"
    },
    "operation": {
      "default": "sale",
      "description": "Sale, rent, room share, rent-to-buy or business transfer.",
      "editor": "select",
      "enum": [
        "sale",
        "rent",
        "share",
        "rentToBuy",
        "transfer"
      ],
      "enumTitles": [
        "For sale",
        "For rent",
        "Shared rent",
        "Rent to buy",
        "Business transfer"
      ],
      "prefill": "sale",
      "sectionCaption": "Search filters",
      "title": "Operation",
      "type": "string"
    },
    "ownerType": {
      "default": "any",
      "description": "Private owners or professional agencies. Private-only uses Fotocasa's particulares path.",
      "editor": "select",
      "enum": [
        "any",
        "private",
        "agency"
      ],
      "enumTitles": [
        "Any",
        "Private owner",
        "Agency"
      ],
      "prefill": "any",
      "title": "Owner type",
      "type": "string"
    },
    "propertyType": {
      "default": "homes",
      "description": "Property category. Subtypes such as penthouses, studios and duplex are preserved instead of being collapsed into homes.",
      "editor": "select",
      "enum": [
        "all",
        "homes",
        "flats",
        "penthouses",
        "studios",
        "duplex",
        "lofts",
        "chalets",
        "garages",
        "land",
        "premises",
        "offices",
        "storageRooms",
        "buildings",
        "newConstruction"
      ],
      "enumTitles": [
        "All types",
        "Homes",
        "Flats / apartments",
        "Penthouses",
        "Studios",
        "Duplex",
        "Lofts",
        "Chalets",
        "Garages",
        "Land",
        "Commercial premises",
        "Offices",
        "Storage rooms",
        "Buildings",
        "New construction"
      ],
      "prefill": "homes",
      "title": "Property type",
      "type": "string"
    },
    "propertyUrls": {
      "description": "Individual Fotocasa detail URLs, new-construction project URLs, or numeric property IDs.",
      "editor": "stringList",
      "title": "Property URLs or IDs",
      "type": "array"
    },
    "publishedSince": {
      "default": "any",
      "description": "Only keep listings published inside this window. Searches newest-first and stops at the cutoff.",
      "editor": "select",
      "enum": [
        "any",
        "last24h",
        "last48h",
        "last7d",
        "last30d"
      ],
      "enumTitles": [
        "Any time",
        "Last 24 hours",
        "Last 48 hours",
        "Last 7 days",
        "Last 30 days"
      ],
      "prefill": "any",
      "title": "Published since",
      "type": "string"
    },
    "rentalType": {
      "default": "any",
      "description": "For rent searches only: long-term or temporary rental. Uses Fotocasa's rental path filter.",
      "editor": "select",
      "enum": [
        "any",
        "longTerm",
        "temporary"
      ],
      "enumTitles": [
        "Any",
        "Long term",
        "Temporary"
      ],
      "prefill": "any",
      "title": "Rental duration",
      "type": "string"
    },
    "sortBy": {
      "default": "relevance",
      "description": "Verified Fotocasa sort orders.",
      "editor": "select",
      "enum": [
        "relevance",
        "newest",
        "oldest",
        "priceAsc",
        "priceDesc",
        "surfaceAsc",
        "surfaceDesc"
      ],
      "enumTitles": [
        "Relevance",
        "Newest first",
        "Oldest first",
        "Price: low to high",
        "Price: high to low",
        "Surface: low to high",
        "Surface: high to low"
      ],
      "prefill": "relevance",
      "title": "Sort by",
      "type": "string"
    },
    "startUrls": {
      "description": "Fotocasa search URLs to scrape. Filters in each URL win over the form fields. Property URLs found here are routed to detail mode.",
      "editor": "requestListSources",
      "sectionCaption": "URLs",
      "title": "Search URLs",
      "type": "array"
    }
  },
  "required": [
    "mode"
  ],
  "schemaVersion": 1,
  "title": "Fotocasa Spain Sale & Rental Listings Scraper",
  "type": "object"
}

Output schema

Published result links and storage locations. This schema is not an exhaustive contract for every field in a dataset record.

FieldTypeRequiredDescription
listingsstringoptionalDataset containing all scraped property listings, new-construction projects and monitor changes from Fotocasa.

Download the published output schema

View complete JSON
{
  "actorOutputSchemaVersion": 1,
  "description": "Fotocasa property and new-construction project records with transaction, price, surface, rooms, features, location hierarchy, coordinates, agency, media, dates, optional detail enrichment (energy certificate, exact street, agency phone/registrations) and optional monitor changes.",
  "properties": {
    "listings": {
      "description": "Dataset containing all scraped property listings, new-construction projects and monitor changes from Fotocasa.",
      "template": "{{links.apiDefaultDatasetUrl}}/items",
      "title": "Property Listings",
      "type": "string"
    }
  },
  "title": "Fotocasa Spain Sale & Rental Listings Scraper Output"
}

Dataset schema

Published dataset views and any declared field definitions. A view can select only a subset of the returned record fields.

Download the published dataset schema

View complete JSON
{
  "actorSpecification": 1,
  "views": {
    "overview": {
      "display": {
        "component": "table",
        "properties": {}
      },
      "title": "Properties",
      "transformation": {
        "fields": [
          "title",
          "price",
          "surface",
          "bedrooms",
          "bathrooms",
          "propertySubtype",
          "city",
          "neighborhood",
          "agencyName",
          "propertyUrl"
        ]
      }
    }
  }
}

Key-value schema

Published key-value store definitions, when provided by this build.

This definition is not present in the default published build. See the published README for available documentation.

Published README

Read the full published documentation

Fotocasa Spain Sale & Rental Listings Scraper

Scrape Fotocasa, one of Spain's largest real-estate portals, without cookies, login, API keys or a proxy. Search any Spanish city, district, neighborhood, street or ZIP code, paste Fotocasa search URLs, or fetch individual property and new-construction project pages.

What this actor does

  • Search by location — resolve city, province, autonomous community, district, neighborhood, locality, street or ZIP code through Fotocasa's own suggestion service.
  • Paste search URLs — every filter already in the URL (operation, property type, price, rooms, surface, features, sort) is preserved.
  • Paste property URLs or IDs — fetch individual listings and new-construction project pages directly.
  • Five operations — sale, rent, shared rent, rent-to-buy and business transfer.
  • Fifteen property categories — homes, flats, penthouses, studios, duplex, lofts, chalets, garages, land, commercial premises, offices, storage rooms, buildings and new construction. Subtypes are preserved, not collapsed into "homes".
  • Server-side filters — price, bedrooms, bathrooms, surface, features and verified sort orders.
  • Special filters — published in the last 24/48 hours, last 7/30 days, rental duration, private-owner-only, bank-owned, subsidised housing and price drops.
  • New-construction projects — project name, URL, delivery date, promoter, price/room/bath/surface ranges, images and every unit.
  • Optional detail enrichment — energy certificate, exact street, ground surface, agency phone and official registrations, extra features and reference.
  • Optional monitor mode — emit only new listings and price changes using persisted Actor state.
  • Up to 10,000 rows — searches above Fotocasa's ~9,900-row API window are automatically split into price buckets and deduplicated.

Input

Field Type Default Description
mode select search search, startUrls or propertyUrls
location string – City, province, district, neighborhood, street or ZIP code
locationType select auto Country, autonomous community, province, municipality, district, neighborhood, locality, street or ZIP code
operation select sale sale, rent, share, rentToBuy, transfer
propertyType select homes All / homes / flats / penthouses / studios / duplex / lofts / chalets / garages / land / premises / offices / storageRooms / buildings / newConstruction
minPrice, maxPrice integer – EUR (monthly rent for rentals)
minRooms, maxRooms integer – Bedrooms
minBathrooms, maxBathrooms integer – Bathrooms
minSurface, maxSurface integer – Built surface in m²
features multi-select – elevator, terrace, balcony, pool, garden, parking, storageRoom, airConditioning, heating, furnished, notFurnished, internet, petsAllowed, bankOwned, subsidised
publishedSince select any last24h, last48h, last7d, last30d
rentalType select any longTerm or temporary (rent only)
ownerType select any private or agency
onlyPriceDrops boolean false Only listings with a price reduction
sortBy select relevance relevance, newest, oldest, priceAsc, priceDesc, surfaceAsc, surfaceDesc
maxItems integer 100 1–10,000
startUrls array of { "url": ... } – Fotocasa search URLs (or paste URLs in the UI)
propertyUrls array – Detail URLs, project URLs or numeric IDs
fetchDetails boolean false Enrich with detail-page fields
maxDetails integer 100 0 = all emitted listings
monitorMode boolean false Emit new/price-changed listings only
monitorKey string – Optional state namespace

Examples

Sale listings in Madrid

{
  "mode": "search",
  "location": "madrid",
  "operation": "sale",
  "propertyType": "flats",
  "minRooms": 2,
  "maxPrice": 450000,
  "sortBy": "priceAsc",
  "maxItems": 200
}

Rentals under €1,500 with detail enrichment

{
  "mode": "search",
  "location": "barcelona",
  "operation": "rent",
  "maxPrice": 1500,
  "rentalType": "longTerm",
  "fetchDetails": true,
  "maxDetails": 50,
  "maxItems": 50
}

Paste a Fotocasa search URL

{
  "mode": "startUrls",
  "startUrls": [
    {"url": "https://www.fotocasa.es/es/comprar/viviendas/madrid/todas-las-zonas/l"}
  ],
  "maxItems": 100
}

Individual property or project URLs

{
  "mode": "propertyUrls",
  "propertyUrls": [
    "https://www.fotocasa.es/es/comprar/vivienda/madrid/x/190909371/d",
    "https://www.fotocasa.es/es/comprar/obra-nueva/barcelona-capital/20517030"
  ]
}

Monitor new listings

{
  "mode": "search",
  "location": "valencia",
  "operation": "rent",
  "monitorMode": true,
  "monitorKey": "valencia-rentals",
  "maxItems": 100
}

Output

Keep all legacy fields (recordType, listingId, title, price, currency, area, bedrooms, bathrooms, propertyType, city, neighborhood, province, postalCode, address, imageUrl, propertyUrl, description, isNewDevelopment, mode, scrapedAt) and add:

  • Identity — recordType (property or newConstructionProject), propertyId, realEstateAdId, detailUrl, operation, transactionTypeId, propertySubtype, propertyTypeId, subtypeId.
  • Price — priceOnRequest, priceDropAmount, previousPrice, priceDropPercent, pricePerSquareMeter, pricePeriod.
  • Property — surface, plotArea, floor, floorType, orientation, orientationName, antiquity, antiquityName, condition, hotWater, heating, features, featureIds, amenities, hasLift, hasTerrace, hasBalcony, hasPool, hasGarden, hasParking, hasStorageRoom, hasAirConditioning, hasHeating, isFurnished, hasInternet, hasPetsAllowed.
  • Media — images, photoCount, videos, hasVideo, hasVirtualTour, hasFloorPlans, hasOnlineGuidedTour, media.
  • Location — street, streetNumber, municipality, district, region, country, locationText, latitude, longitude, coordinatesAccuracy, locationIds, addressVisibilityMode.
  • Agency — agencyName, agencyAlias, agencyId, agencyType, agencyUrl, agencyLogo, agencyPhone, agencyReference, agencyRegistrations, publisherId, isPrivateOwner, isBank, phone, hasPhoneVisibility.
  • Dates and flags — publishedAt, updatedAt, bumpedAt, isNewConstruction, isPromotion, isOpportunity, isAuctioned, isOccupied, isRentedWithTenants, isBareOwnership, isTemporaryRental, isTop, isPremium, hasSubsidies, isPhotoReport.
  • Detail enrichment — energyRating, energyConsumption, energyEmissions, energyCertificateStatus, groundSurface, extraFeatures, reference, keyDeliveryDate, constructionType, qualityRate, rentReferenceIndex.
  • Projects — projectId, projectName, projectUrl, projectKeyDeliveryDate, projectPromoterName, projectPromoterPhone, projectUnitCount, projectPriceMin, projectPriceMax, projectRoomsMin, projectRoomsMax, projectBathroomsMin, projectBathroomsMax, projectSurfaceMin, projectSurfaceMax, projectImages, projectUnits, promotionTypologies.
  • Monitor — changeType, previousPrice, firstSeenAt, lastSeenAt.

Empty fields are omitted at every level. Price 999999999 is treated as "price on request", never as a real price.

Use cases

  • Buyer research — compare asking prices and surfaces across neighborhoods.
  • Rental tracking — watch long-term or temporary rental supply and rents.
  • Investor screening — filter by price, surface, rooms and features, then enrich energy and agency data.
  • Lead generation — agency name, phone, reference and registrations, private-vs-agency flags.
  • New-build monitoring — project names, promoters, delivery dates and unit inventories.
  • Market change alerts — schedule monitor mode to get only new and re-priced listings.

FAQ

Do I need a Fotocasa account, cookie, API key or proxy? No. The actor uses Fotocasa's public search and SSR JSON endpoints directly, with no login, cookie, key or proxy input.

Which locations can I use? Any place Fotocasa recognizes: Spain, autonomous communities, provinces, municipalities, districts, neighborhoods, localities, streets and ZIP codes. Try Madrid, Barcelona, Sitges, Eixample, 28001 or a street name.

Can I paste a normal Fotocasa search URL? Yes. Use startUrls mode and paste the URL; the operation, property type, location and filters are read from the path and query string.

Why did I get fewer than maxItems? Three reasons: the search genuinely has fewer matches, Fotocasa's public API window is about 9,900 rows per query (the actor partitions above that only when maxItems is above 9,900), or a client-side filter such as price drops or private owners scanned its safety limit. The run status message always reports delivered vs reported counts.

How does detail enrichment work? With fetchDetails: true the actor fetches the listing detail page to add fields the search API does not carry: energy certificate, exact street, ground surface, agency phone/registrations and extra features. It is off by default because it adds one request per listing. maxDetails: 0 enriches every emitted listing.

What happens with more than 10,000 results? maxItems is a hard cap at 10,000. For large searches the actor splits the query into the price buckets shown in the status message and deduplicates by property ID. To go deeper than the API window on a smaller request, add price or location filters yourself.

Does monitor mode need extra setup? No. It stores a compact map of property IDs and prices in Actor state, keyed by monitorKey (or a hash of your filters). The first run emits everything as new; later runs emit only new and priceChanged records.

Are rental duration, published date and private-owner filters server-side? Fotocasa's JSON search body ignores them. The actor applies them through Fotocasa's own path filters or client-side cutoffs, and says so in the run status when a scan limit is reached.

Why is price missing on some records? Fotocasa sometimes publishes "price on request" as 999999999 or a null. The actor omits price and sets priceOnRequest: true instead of inventing a value.

Why do private-owner searches return fewer listings? Fotocasa's /particulares page shows 15 private-owner listings per page and ignores extra query filters. The actor paginates that page, applies price/room/surface and price-drop filters client-side, and reports when the private page is exhausted; use a narrower location or price range to see different private listings. Rental-duration filtering is unavailable on the private page.

Is this affiliated with Fotocasa? No. It is an independent actor that reads publicly available Fotocasa data and is not affiliated with or endorsed by Fotocasa.

Python quickstart

Use a schema-derived input and the Python standard library to start a run. An Apify account and token are required for execution.

Open the step-by-step Python guide →

Source build 5VP42leRffobQEC1N. Documentation is regenerated from the default published build; private drafts are not included.