---
id: imobiliario/catalogo-imoveis-agente-ia
industry: Real estate
usage: specific
effort: medium
grain: Eligible property, one row per reference code and purpose
---

# Property catalog for an AI agent

A table with only the properties that can be offered, with prices in Brazilian format, features as readable text, public photos and a link, ready for the support agent, the website and the listing portal feed.

## Executive summary

**For:** Brokerages that want an AI agent answering about properties or that publish their catalog to listing portals from the CRM.

**What it solves**

- The agent only offers properties that are for sale or rent and cleared for advertising.
- The client gets readable price, features and photos, not a raw CRM field.
- Website, portals and agent show the same property at the same price.

**Why it matters:** An agent that offers a sold property or a wrong price loses the client on the first message and exposes the brokerage. The CRM stores everything, including what cannot be disclosed: properties off the website, owners, zeroed values and internal photos. The consumption table is the boundary between the record and what the client sees.

**Business questions it answers**

- How many properties are available for the agent to offer today, by purpose?
- Which properties are flagged for the website in the CRM and do not appear in the catalog?
- How many available properties have no photo or no price?
- When was the catalog last updated?
- Which launches are in the CRM and not yet on the website?

**What you need**

- Property CRM connected to Nekt, with photos and amenities
- The eligible property rule by purpose, approved by management
- A public domain for photos, if the feed goes to portals

**What you get**

- A consumption table with one property per row, eligible ones only
- Text or JSON per property ready for the agent and for semantic search
- XML feed in the portals' standard
- Last load date on every row

## Detailed

### The problem

The CRM's property record has hundreds of columns, nested amenity and photo fields, values stored as text and properties that cannot be disclosed. An agent reading the raw record offers sold properties, shows 'R$ 0' and sends links to internal photos. Launches, resales and rentals have different rules for available and for price, and each channel needs the property in its own format.

### Business rules

1. **Eligible depends on the purpose.** Resale: flagged to show on the website and with status Sale, Sale and Rent or In Negotiation, excluding the project category and inactive land. Launch: project category, condition other than used, and flagged for the website. Rental: total rent above zero and below a sanity ceiling (for example, R$ 50 thousand). Each purpose becomes a table or a purpose column. (Avoid: Sending every CRM property to the agent.)
2. **In negotiation shows with a warning.** A property in negotiation stays eligible so the client is not lost, but the agent says it is in negotiation and offers similar ones. Sold, rented, reserved or suspended never enters. A property that does not exist in the catalog is a different answer from an unavailable property. (Avoid: Offering a property in negotiation as available.)
3. **Price in Brazilian format, never zero.** Values arrive as numbers, as text with a decimal comma or as 'value|BRL' (in Bitrix24). Convert, round and format as R$ 1.250.000,00. A zero or null value becomes a fixed sentence, for example 'Entre em contato para informações de valores.' (contact us for pricing). Launches show 'from'; resales show the value. Condo fee and IPTU (property tax) go in their own fields. (Avoid: Sending the client 'Valor: 0' or '1916900|BRL'.)
4. **Nested fields become readable text.** Amenities and features arrive as a structure with dozens of Yes, No or empty fields. Generate a list with only what is Yes or has a value, each item with its Portuguese label ('Piscina', 'Churrasqueira', 'Água: poço artesiano'). Empty fields disappear from the text instead of becoming 'Label:' with no value. (Avoid: Converting the whole structure to JSON and sending it to the agent.)
5. **Only cleared photos, with a public address.** Use only photos flagged to show on the website, with the featured photo first. The URL must be public: photos from a new CRM usually need a base domain for the portal feed. Website links with localhost or from a test environment stay out. (Avoid: Using every photo on the record, including internal ones.)
6. **One format per channel, the same rule.** For the agent, one text per property with 'Label: value' separated by commas, starting with the code. For semantic search, one JSON per property with readable keys and the same content as metadata, with a stable property id for updates and deletes. For portals, one row per property already in the VrSync standard. All three come from the same eligible table. (Avoid: One availability rule in the agent and another in the feed.)
7. **Portal feed with the standard's types and limits.** Map the CRM property type to the VrSync PropertyType through a dictionary (apartment, house, townhouse, penthouse, land, office). Title up to 100 characters, description without HTML and without the CDATA closing sequence, up to 3000 characters. Empty transaction becomes sale. Empty bedrooms use rooms plus suites. Year built outside 1800 to 2100 becomes null. Listing highlight comes from the property's portals field. (Avoid: Sending the portal a description with HTML and the type as a CRM code.)
8. **No owner or internal data.** The agent table never carries the owner's or listing agent's name, phone or document, commission or internal notes. It only holds what can be told to the end client. Expanding what the agent can say is a management decision, recorded. (Avoid: Exposing the owner because the column was in the table.)
9. **tenant_id on every row and separate caches.** When the same agent serves more than one brokerage or brand, each row carries the tenant_id and the agent always filters by it. The property cache and the contact cache live in separate tables. (Avoid: A single cache of properties and contacts for several brands.)
10. **Freshness is part of the answer.** The table runs by event right after the CRM sync, and each row stores the load date. If the load is late beyond the agreed limit, the agent does not confirm availability: it says it will check with a broker. (Avoid: Catalog updated by hand, with no date.)

### Who enters the catalog

Real eligibility rules, by purpose, from the CRM record.

- **Show on website = Yes and status Sale, Sale and Rent** → Resale
- **Status In Negotiation, flagged for the website** → Sale, with negotiation warning
- **Project category, condition other than used** → Launch, price 'from'
- **Total rent > 0 and below the ceiling** → Rental
- **Sold, rented, reserved, suspended or off the website** → Out of the catalog
- **Link with localhost or inactive land** → Out of the catalog

### Definitions

| Metric | Definition |
|---|---|
| Eligible property | property that passes the rule for its purpose (sale, launch or rental) at load time |
| Displayed price | sale or rent value converted from text, rounded and formatted in R$; fixed sentence when zero or null; 'from' for launches |
| Main photo | first photo flagged to show on the website, with a public URL |
| Catalog coverage | eligible properties in the catalog / properties flagged for the website in the CRM with sale or rental status |
| Incomplete property | eligible with no photo, no price or no public link |
| Freshness | now minus the date of the last catalog load, in hours |

### Pitfalls

- **Property off the website offered.** The agent read the whole record and offered properties that were not cleared for advertising or had already been sold. How to avoid: The agent reads only the eligible table.
- **Forgotten test filter.** A catalog transformation kept the single property code filter used in testing and published a one-property catalog. How to avoid: Acceptance test with the eligible count against the CRM on every load.
- **Row limit in production.** The query feeding the AI shipped with a 10-row limit used during exploration. How to avoid: Review limits and filters before connecting the table to the agent.
- **Availability column without a filter.** The agent cache carried the active property column but did not filter on it, and the agent offered inactive properties when the instruction failed. How to avoid: Filter in the table, not in the agent's instruction.
- **Launch only in the CRM.** Projects registered in the CRM and not yet published on the website were left out of the catalog while brokers were already selling them. How to avoid: Union website launches with CRM launches cleared for advertising that are not on the website yet.
- **Absurd rent.** Without a ceiling, unrealistic rent values caused by data entry errors entered the rental catalog next to real properties. How to avoid: Sanity ceiling on the value and a list of blocked properties for correction.

### Acceptance test

- [ ] The number of eligible properties by purpose matches the CRM count applying the same rule (zero difference).
- [ ] No sold, rented, reserved, suspended or off-website property appears in the catalog.
- [ ] No row has price 'R$ 0', a value with '|BRL' or a link with localhost.
- [ ] Every row has the last load date and it is less than 24 hours old.
- [ ] No column in the agent table contains an owner's name, phone or document.

### Context document

```text
Property catalog for the agent
- Offer only properties from the eligible table. If the property is not in it, it cannot be offered.
- Eligible: resale with show on website = Yes and status Sale, Sale and Rent or In Negotiation; launch with project category and condition other than used; rental with rent above zero and below the ceiling.
- Property in negotiation: say it is in negotiation and offer similar ones.
- Property not found is different from unavailable. Not found: say you did not find it and offer similar ones. Unavailable: say it is no longer available.
- Price: use the formatted price from the table. If it comes with the contact-us sentence, do not invent a value. Launches are 'from'.
- Never share owner, listing agent, commission or internal note data.
- If the last load date is more than <hours> hours old, do not confirm availability: say a broker will confirm.
- Always filter by the tenant_id of the brokerage being served.
- Price negotiation, offers, documents and scheduled viewings go to a broker.
Client exceptions:
- <client>: rent ceiling of R$ <value> for rentals.
- <client>: properties in category <category> do not enter the agent catalog.
```

### Variations

- **Developer units:** Catalog per available unit from the sales map, with unit type, area and current price table, without reserved units.
- **Contacts for the agent:** A separate contact cache, with the best phone from the single customer base, so the agent recognizes existing clients.
- **Listing data gaps:** Daily list of properties flagged for the website that were left out of the catalog for lack of photo, price or link, for the listing agent to fix.
