Real Estate Schema: What to Mark Up and What Google Supports
The schema types for a brokerage, an office, an agent and a listing, with JSON-LD to copy, what areaServed and Offer say, and what Google shows for each.
Real estate schema comes down to four types, one for each thing a real estate site describes:
- Organization for the brokerage. Its name, logo and contact details can appear in a knowledge panel.
- RealEstateAgent for each office clients visit. Google reads it as a local business, which needs a name and a street address.
- Person for each agent, on a ProfilePage for the agent’s own page. It says who the page is about and which firm they work for.
- RealEstateListing, with an Offer, for each listing.
Google has no rich result for a property listing, and it shows no stars for reviews of you that sit on your own site, so none of this changes how your listings look in the results. What the markup does is say, in the vocabulary Google reads, which business, which office and which person each page is about, and it may only say what the page already shows.
Despite its name, RealEstateAgent is not the agent. Schema.org defines it as a kind of LocalBusiness, an organization with a place, which is why it goes on an office. The person is a Person, tied to the brokerage with worksFor.
An agent’s page
This gives the brokerage one identity and marks the page as being about Jane Doe, who works for it. Every value should be one a visitor can read on the page.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#brokerage",
"name": "Example Realty",
"url": "https://example.com/",
"logo": "https://example.com/logo.png"
},
{
"@type": "ProfilePage",
"url": "https://example.com/agents/jane-doe/",
"mainEntity": {
"@type": "Person",
"name": "Jane Doe",
"jobTitle": "Real estate agent",
"worksFor": { "@id": "https://example.com/#brokerage" }
}
}
]
}
An office, and where areaServed goes
An office’s markup repeats the name, address and phone on its page, and the towns it serves:
{
"@context": "https://schema.org",
"@type": "RealEstateAgent",
"name": "Example Realty Austin",
"url": "https://example.com/offices/austin/",
"telephone": "+1-512-555-0100",
"address": {
"@type": "PostalAddress",
"streetAddress": "100 Main Street",
"addressLocality": "Austin",
"addressRegion": "TX",
"postalCode": "78701",
"addressCountry": "US"
},
"areaServed": [
{ "@type": "City", "name": "Austin, Texas" },
{ "@type": "City", "name": "Round Rock, Texas" }
],
"parentOrganization": {
"@type": "Organization",
"@id": "https://example.com/#brokerage",
"name": "Example Realty"
}
}
areaServed says where a business, a service or an offer is provided. Schema.org expects it on an organization, which includes RealEstateAgent, on a Service and on an Offer, but not on a Person, so on an agent’s page the towns go on the office or on a service. A value can be a city or a county, a shape drawn on the map, or plain text, and areaServed replaced the older serviceArea. Where different services cover different towns, give each service its own list.
Google’s local business documentation doesn’t mention areaServed at all. The towns Google shows for a business are the service area set in its Business Profile, so the markup should match the profile, and the profile is what counts.
A listing, and its Offer
A listing’s markup describes the home and, in its Offer, the terms it’s offered on:
{
"@context": "https://schema.org",
"@type": "RealEstateListing",
"url": "https://example.com/listings/123-main-st/",
"name": "123 Main Street for rent",
"datePosted": "2026-09-28",
"mainEntity": {
"@type": "SingleFamilyResidence",
"name": "123 Main Street",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main Street",
"addressLocality": "Austin",
"addressRegion": "TX",
"postalCode": "78701",
"addressCountry": "US"
},
"numberOfBedrooms": 3,
"numberOfBathroomsTotal": 2
},
"offers": {
"@type": "Offer",
"price": 2800,
"priceCurrency": "USD",
"businessFunction": "http://purl.org/goodrelations/v1#LeaseOut",
"leaseLength": "P12M"
}
}
The Offer schema carries the terms: the price, its currency, and businessFunction, which says whether the home is for sale or for lease. Sale is the default, so a listing for sale can leave it out and a rental says LeaseOut. datePosted is the day the listing went up on your site, which schema.org defines as the publication date of an online listing; the day it entered the MLS is another date. When a feed changes the price or the status, the markup has to change with it, since a price in the markup that the page no longer shows is markup Google’s rules forbid.
What not to mark up
- Reviews of you. Google gives no review stars to a business that controls the reviews about itself: testimonials on your own site, and a widget showing your Google reviews, earn none whatever the markup says. The stars that matter are the ones on your Business Profile.
- Anything the page doesn’t show. Google’s rule is that markup describes only what a reader can see, so a phone number, an award or a town that appears only in the JSON-LD breaks it.
Check it
Run the Schema Markup Validator for the vocabulary. Use Google’s Rich Results Test only for a type Google has a feature for; a listing shows no items there, which is correct. Then open the live page in Search Console’s URL Inspection to see the markup Google read.
We add the markup last, after the pages it describes, because it can only repeat what they say; our real estate SEO services start with the pages.