Property Data and AI Enrichment Validating AI-Generated Property Types

When enriching property data using AI, the raw output isn't always perfectly aligned with your database requirements or real estate legal definitions. This guide shows you how to apply business logic "guardrails" to AI responses, ensuring that property types, lot sizes, and square footage are accurate and properly formatted before they ever reach your Monday.com board.

flowchart LR
  A["Property Address"] --> B["Gemini AI"]
  B --> C{"Code Guardrails"}
  C --> D["Monday.com Board"]

How the guardrails work

AI models (like Gemini 2.5 Flash) are great at extracting data from tax assessor or GIS databases, but they can sometimes misclassify property types based on marketing descriptions.

To fix this, we use a code step in the automation to intercept the AI's response and apply strict real estate rules based on Lot Acreage and Square Footage.

Rule NameConditionEnforcement
The Condo RuleLot Size is exactly 0Forces the type to Condo (or keeps Townhome). Legally, detached homes on 0 acres are "Site Condos".
The Townhome RuleLot Size is between 0 and 0.10If the AI says "Detached" but the house is under 2,400 sqft, it is reclassified as a Townhome.
The Flexible RuleLot Size is >= 0.10Trusts the AI's research for Detached, Multi-Family, or Commercial properties.

We also standardize terminology before applying rules. For example, if the AI outputs "Single Family", the script automatically converts it to "Detached" to match your Monday.com status labels.

Setting up the validation flow

Follow these steps to implement the AI extraction and validation script in your automation platform (such as Zapier or Make).

  1. 1

    Configure the AI Prompt

    First, prompt your AI model to return a strict JSON object. Instruct it to bypass marketing descriptions and prioritize official government records.

    {
      "sqft": [number],
      "lot_acres": [number],
      "type": "Detached/Townhome/Condo/Multi-Family/Commercial/Land",
      "neighborhood": [string]
    }
  2. 2

    Add the Guardrail Script

    Add a Code step immediately after your AI action. This JavaScript snippet cleans the AI output, parses the JSON, and applies your property type rules.

    // Assume inputData contains the raw AI text and location coordinates
    const aiResponse = inputData.rawText;
    const cleanLat = inputData.googleLat;
    const cleanLng = inputData.googleLng;
    
    if (!aiResponse) return { error: "No AI data", lat: cleanLat, lng: cleanLng };
    
    try {
      // 1. Clean and parse the JSON
      let cleaned = aiResponse.replace(/```json|```/gi, "").trim();
      const start = cleaned.indexOf('{');
      let end = cleaned.lastIndexOf('}');
      const data = JSON.parse(cleaned.substring(start, end + 1));
    
      const validTypes = ["Detached", "Townhome", "Condo", "Multi-Family", "Commercial", "Land"];
      let lotSize = data.lot_acres ? parseFloat(data.lot_acres) : 0;
      let houseSize = parseInt(data.sqft) || 0;
      
      // 2. Standardize terminology
      let aiType = data.type === "Townhouse" ? "Townhome" : data.type;
      if (aiType === "Single Family") aiType = "Detached";
      
      let finalType = aiType;
    
      // 3. Apply Guardrails
      if (lotSize === 0) {
          finalType = (aiType === "Townhome") ? "Townhome" : "Condo";
      } else if (lotSize > 0 && lotSize < 0.10) {
          if (aiType === "Detached" && houseSize < 2400) {
              finalType = "Townhome";
          }
      } else if (lotSize >= 0.10) {
          finalType = aiType;
      }
    
      // 4. Fallback validation
      if (!validTypes.includes(finalType)) finalType = "Detached";
    
      // 5. Format text (Title Case for neighborhoods)
      const toTitleCase = (str) => {
        if (!str || str === "N/A") return "N/A";
        return str.toLowerCase().split(' ').map(word => 
          word.charAt(0).toUpperCase() + word.slice(1)
        ).join(' ');
      };
    
      // Return the validated payload
      output = {
        sqft: houseSize,
        type: finalType,
        neighborhood: toTitleCase(data.neighborhood),
        lot_acres: lotSize.toFixed(3),
        lat: cleanLat || null,
        lng: cleanLng || null
      };
    
    } catch (error) {
      output = { error: "Logic Error", details: error.message, lat: cleanLat, lng: cleanLng };
    }
  3. 3

    Update Monday.com

    Finally, map the output variables from your Code step to your Monday.com "API Realtor Data" board. Because the data has been validated, you can safely map the type directly to your Status column and update the item to "Done".

Always include a try/catch block in your code step (as shown above). If the AI hallucinates a completely invalid format that breaks the JSON parser, the automation will gracefully fail and return an error object rather than crashing your workflow.

Frequently Asked Questions

Why override the AI if it says 'Detached' on 0 acres?

In real estate data, a detached structure sitting on exactly 0 acres of owned land is legally classified as a "Site Condo." Overriding the AI ensures your database reflects the legal zoning rather than the architectural style.

What happens if the AI returns an unknown property type?

The script includes a fallback check against a validTypes array. If the AI returns something unexpected (like "Treehouse"), the script automatically defaults the type to "Detached" so the Monday.com update doesn't fail.

Next Steps

Monday.com Integrations

Learn more about mapping complex data types, like Location columns, into Monday.com.

Advanced Prompt Engineering

Discover techniques for forcing LLMs to return reliable, perfectly formatted JSON every time.