Realty AI Enricher
Under maintenancePricing
Pay per event
Realty AI Enricher
Under maintenanceDownstream post-processor for the Real Estate Aggregator. Reads a completed listings dataset, extracts structured amenity data (parking, pet policy, laundry, A/C, and more) from each listing's free-text description with an LLM, and re-emits the original items with an added `amenities` field.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Tri⟁angle
Maintained by ApifyActor stats
0
Bookmarked
3
Total users
0
Monthly active users
19 days ago
Last modified
Categories
Share
Real Estate AI Enricher turns messy, free-text real-estate listings into clean, structured amenity data you can filter and analyze. It's a run-and-exit post-processor: point it at a dataset you already scraped, and it re-emits every listing with an added extractedAmenities object — parking, pet policy, laundry, air conditioning, and more.
This is the amenities-context variant. Unlike the description-only build, it feeds each listing's already-tagged amenities into the model alongside the free-text description, so the extraction is grounded in the structured facts the source already provides and refined by what the prose adds.
What does Real Estate AI Enricher do?
It reads a completed dataset produced by the Real Estate Aggregator (or any dataset with the same shape), sends each listing's description and native amenities to a fast, low-cost LLM through the Apify OpenRouter proxy, and writes back a normalized extractedAmenities object. Every original field is passed through untouched — the Actor only adds a field, it never rewrites your data.
Because it runs on the Apify platform, you get API access, scheduling, integrations, automatic retries, and monitoring out of the box. It shares no code with the scraper that produced the data — it only depends on that data's output shape.
Why use Real Estate AI Enricher?
- Make listings filterable. Free-text descriptions can't be queried; a structured
extractedAmenitiesobject can ("dishwasher = true", "parking = garage"). - Higher accuracy than text-only extraction. It combines the source's structured amenity tags with the description, so it confirms and fills gaps rather than guessing from prose alone.
- Enrich listings with weak descriptions. A listing with structured amenities but a thin or missing description still gets enriched — the structured tags alone are enough to extract from.
- Cheap and fast. Defaults to
anthropic/claude-haiku-4.5with tunable batch concurrency. - Non-destructive. Your original
amenitiesfield and every other field survive; the result lands under a distinctextractedAmenitieskey.
How to use Real Estate AI Enricher
- Run the Real Estate Aggregator (or any compatible scraper) and copy the resulting dataset ID from its run's Storage tab.
- Open this Actor, paste the ID into Dataset ID.
- (Optional) Adjust the model, concurrency, and the "skip listings without a usable description" toggle.
- Click Start. The Actor reads the whole dataset, enriches each listing in batches, and streams the results to its own output dataset.
- Download the enriched data, or wire the output into your database or spreadsheet via the API or an integration.
Input
| Field | Type | Default | Description |
|---|---|---|---|
datasetId (required) | string | – | ID of the upstream dataset to enrich. |
model | string | anthropic/claude-haiku-4.5 | OpenRouter model slug used for extraction. Override with a stronger model for tricky listings. |
concurrency | integer | 10 | Listings extracted in parallel per batch (1–50). Higher is faster but more rate-limit prone. |
skipIfNoDescription | boolean | true | When on, descriptions shorter than 20 chars are left out of the prompt. Native amenities are always used when present, regardless of this flag. |
Expected input shape. This Actor is built for Real Estate Aggregator-shaped items. It reads each listing's description and, when present, its structured amenities field; every other field is passed through untouched. You can point it at any dataset with a compatible shape, but items with neither a usable description nor an amenities field come back with extractedAmenities: null. If a run reports that no listing carried a native amenities field, it logs a warning and falls back to description-only extraction — a sign the input dataset may not be aggregator output.
Example input:
{"datasetId": "aBcDeF1234567890","model": "anthropic/claude-haiku-4.5","concurrency": 10,"skipIfNoDescription": true}
Output
Each item is your original listing plus an extractedAmenities object (or null when there was nothing usable to extract). Your source's native amenities field is preserved untouched.
{"id": "listing-42","description": "Sun-drenched 1BR with in-unit washer/dryer, dishwasher, stainless appliances, hardwood floors, a gas fireplace, and a shared roof deck with city views. Cats welcome. Garage parking available.","amenities": { "Building": ["Elevator", "Gym"], "Unit": ["Dishwasher"] },"extractedAmenities": {"parking": "garage","petPolicy": "cats_only","balcony": null,"garden": null,"gym": true,"pool": null,"inUnitLaundry": true,"sharedLaundry": null,"dishwasher": true,"airConditioning": null,"furnished": null,"elevator": true,"concierge": null,"storage": null,"fireplace": true,"patio": null,"walkInCloset": null,"stainlessSteelAppliances": true,"ceilingFan": null,"highSpeedInternet": null,"controlledAccess": null,"highCeilings": null,"countertops": null,"flooring": ["hardwood"],"view": ["city"]}}
You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.
Data table
| Field | Type | Values |
|---|---|---|
parking | string / null | garage, street, lot, carport, covered, driveway, none |
petPolicy | string / null | allowed, cats_only, dogs_only, not_allowed |
countertops | string / null | granite, quartz, marble, laminate, other |
flooring | array / null | any of hardwood, carpet, tile, vinyl, laminate, concrete |
view | array / null | any of water, city, mountain, park, golf, other |
balcony, garden, patio, pool | boolean / null | present or not |
gym, storage, fireplace | boolean / null | present or not |
inUnitLaundry, sharedLaundry, dishwasher | boolean / null | present or not |
stainlessSteelAppliances, walkInCloset | boolean / null | present or not |
airConditioning, ceilingFan | boolean / null | present or not |
furnished, elevator, concierge | boolean / null | present or not |
highSpeedInternet, controlledAccess, highCeilings | boolean / null | present or not |
A field is null when it can't be determined from either the description or the native amenities — the Actor never invents data. Array fields (flooring, view) can list several values.
Pricing / Cost estimation
The Actor charges an actor-start event plus one listing-enriched event per successfully enriched listing (skipped and failed listings are not charged). On top of that, LLM token usage is billed to your Apify account at the OpenRouter proxy's rates. The default model is chosen to keep per-listing cost low; switch to a stronger model only when accuracy on ambiguous listings matters. Listings with no usable description and no native amenities are skipped with no LLM call, so you're not charged for data that has nothing to extract.
Tips and advanced options
- Tune
concurrencyto trade speed against rate limits — start at 10 and raise it if you're not seeing throttling. - Keep
skipIfNoDescriptionon for the cheapest runs; the amenities signal still enriches listings whose description is thin. - Use a stronger model only for datasets with long, ambiguous prose — the default handles structured, tag-backed listings well.
FAQ, disclaimers, and support
Does it modify my original data? No. It only adds extractedAmenities; every other field, including the native amenities, passes through unchanged.
What if a listing has no description? If it also has no native amenities, it's skipped with extractedAmenities: null. If it has amenities, it's still enriched from those.
Why did I get null for a listing? Either it was skipped (no usable signal) or the extraction failed/returned an unusable response — the Actor logs a warning with the item index and moves on, so one bad listing never aborts the run.
Legality. Use this Actor only on data you are permitted to process. You are responsible for complying with the terms of the source you scraped and with applicable law.
Found a bug or want a field added? Open an issue on the Actor's Issues tab — feedback and custom-field requests are welcome.


