Avatar

Isaac Levine

Software Engineer

[frontstep.ai] How I Hijacked Zillow.com's Native Chat System

Introduction

In around March or April of 2025, Noah and I already knew based on our many conversations with realtors that prequalifying prospective tenants before scheduling a tour was a huge time-suck and pain point for them. We had decided that this was the problem we were going to solve. What we wrongly assumed however, was that their communication happened over email and text.

While that was true for most of the lifecycle of the realtor-client relationship, it was not the case for the prequalification step specifically (the part beginning with a prospective client clicking "Request a Tour" or "I'm Interested" on a Zillow listing, and ending with that client actually getting scheduled for a tour and meeting the listing agent in person). Was we talked to more and more realtors, it became apparent to us that conversations during the prequalification step happened directly in Zillow.com's chat interface. Realtors would confirm their move-in date, whether or not they had pets, their credit score range, etc., before scheduling the tour. They would even sometimes meet up for the in-person tour without ever taking the conversation off of the Zillow platform to email/text.

It was clear that if we were to build something to automate prequalification, it would have to operate within the native Zillow chat. That lead me to find Zillow's Leads API - which was well-enough documented and seemed relatively straightforward. However, it was not until further conversations with our beta testing clients that I would learn that most real estate agents weren't on a high enough paid tier with Zillow to even have access to this webhook integration for leads. 1

This presented a challenge: realtors were almost exclusively prequalifying their leads directly on Zillow, but Zillow was not allowing us to integrate via API for their free and lower paying customers.

What Zillow did do however for all clients, regardless of what plan they were on, was send them email notifications every single time they received a new lead or message on the platform. I would soon find out that we could use this simple email notification to get our AI-generated responses to populate directly into the Zillow platform, enabling us to build an AI agent that could both read and write to Zillow's native chat interface.

The Idea

I asked some of our early beta testers to forward me a few of these notifications from Zillow, and as soon as I saw the words "You can also reply directly to this email" at the bottom of the email, I had an idea.

2

We could route all of these Zillow notification emails to our own mail server and generate/send responses on behalf of our realtor clients. After some quick testing, I validated that it did not matter what email address the reply came from. As long as it was sent to that randomly generated address (1dbfxvat8vtwuitucbxe0u4nu6@convo.zillow.com in the example below), it would propogate directly into the Zillow.com chat UI. We had everything we needed.

The workaround was so simple that I couldn't believe it actually worked. I remember being amazed at the time that you could build an entire application and AI agent that responded to Zillow leads inside the platform just like the human real estate agent would, all while not even paying enough to use their official API integration.

The possibilities for frontstep.ai were endless at this point, and this is when I really kicked development into high gear and built out the main features of the platform and AI agent.

How it Works

First, we helped our beta testers to add a forwarding rule that would automatically route all emails from the @convo.zillow.com subdomain to our mail server address inbound@leads.frontstep.ai.

That forward email was then received by a mail server that we set up using Mailgun, which received emails and translated them into POST requests to a webhook endpoint that our deployed backend exposed. This webhook was then responsible for normalizing out the contents of the email, extracting the message content, the forwarder (our realtor client's email) and the zillow-generated email address that the server would use to send a response back, before pushing this normalized message onto a queue.

These normalized messages would then be be processed by the MessageProcessor, which did most of the heavy-lifting. Every 30 seconds, it would pop all normalized messages off the queue, group them by Conversation and Lead if they already existed (i.e. this was a message for a pre-existing conversation) or create new ones if necessary, resolve the Property in the database that this Conversation was about or create a new one if necessary, mark qualification questions as answered (more on that below), generate a response based on the remaining unanswered questions, and finally, either generaete and send an appropriate response based on the conversation context and the unanswered qualification questions, or mark the Lead and Conversation as fully qualified and trigger a separate code path to send a notification email over to the realtor that the lead was ready for a tour!

High-Level Architecture

Below is a very high-level view of how this process worked from the Zillow email notification all the way to a response propogating back into Zillow.

Important Components

Here's a more detailed look at how a few of the components above actually work.

Webhook Handler

The webhook handler receives the parsed email data from Mailgun and performs initial processing:

  • Organization Resolving: Extracts the email that forwarded the message to identify which Organization (brokerage client out of ours) this lead/conversation belonged to.
  • Message Extraction: Pulls out the actual inquiry message from the lead
  • Message Queue: Unequeues the normalized, but unprocessed message in a message queue for asynchronous processing.

The handler responds quickly with a 200 OK to Mailgun, ensuring that requests don't hang or timeout, causing a storm of retries from Mailgun. In my design of this architecture, it was crucial for the webhook to respond quickly with a success to Mailgun, because the Mailgun component was completely out of our control, and the platform offered limited observability and insight into how things like timeouts were configured.

Message Queue

The message queue decouples email ingestion from message processing. This design allows:

  • Reliability: If the MessageProcessor were unavailable for some reason, we would build a backlog of messages, but they would not be lost.
  • Scalability: In the future, multiple processors could consume messages in parallel, if we wanted to scale up the process to make it faster.
  • Resilience: Failed processing attempts can be retried without losing the original message.

Message Processor

The message processor polls normalized messages off the queue every 30 seconds and handles the core business logic:

  1. Conversation and Lead Resolution: Determines if this is a new lead or part of an existing conversation by matching contact information
  2. Marking Questions as Answered: Based on the questions that this Organization had configured globally, per-property, or per-lead, it would scan through those unanswered questions and mark certain questions as answered to update qualification progress depending on the content of the normalized message.
  3. Update Conversation State: Saves the incoming message to the database, maintaining conversation history. Also updates the conversation object by recording answeres to specific qualification questions or updating overall status if fully qualified.
  4. AI Integration: Sends the conversation context to the AI service to generate an appropriate response.

AI Service

The AI service is responsible for generating intelligent, context-aware responses:

  • Context Analysis: Reviews the entire conversation history to understand what has been discussed
  • Question Tracking: Identifies which qualification questions have been answered and which remain unanswered
  • Response Generation: Creates a natural, helpful response that either asks the next unanswered question or acknowledges completed information
  • Guardrails: Ensures responses are appropriate, professional, and aligned with the realtor's configured questions. More on this below.

Email Service

Once the AI generates a response, the email service handles delivery:

  • Channel Selection: Determines whether to send via email or SMS based on the lead's preferences and the conversation history (for Zillow leads, this was email).
  • Message Delivery: Sends the response through the appropriate channel (I used Resened for email and Twilio for SMS).
  • Delivery Confirmation: Tracks delivery status and confirms successful transmission

After successful delivery, the processor marks the message as processed in the queue, completing the cycle.

Design Decisions

Asynchronous Processing

By using a message queue, we ensure that email ingestion (which needs to respond quickly to Mailgun) is decoupled from message processing (which involves AI generation and can take longer). This prevents webhook timeouts and allows the system to handle bursts of incoming leads. I was also worried that in the future we would want to scale up the message processor, so decoupling the webhook and the processor by placing a queue between them would allow me to add as many listeners to that queue as I wanted.

AI Guardrails

From the very beginning, Noah and I were thinking about FHA (Fair Housing Act) laws and wanted to make sure that frontstep.ai would never say anything it wasn't supposed to say (e.g. asking about race, income, disability, or any other protected classes that you aren't allowed to ask about in the prequalification process). I found OpenAI's Guardrails to be very effective and easy to use for this purpose. We had several guardrails that every message we generated had to pass through: 1. It could not ask about any protected classes under FHA, 2. It could not make anything up about the property that it did not explicitly know from the property notes stored in the database (e.g. number of bedrooms or bathrooms), and 3. It could not go off the rails and start saying anything it wanted, it had to reply by concisely acknowledging their answer, and asking a new question. I can proudly say that in the 300+ conversations frontstep.ai handled, it never violated any of these 3 important guardrails that I put in place.

Result

This architecture enables Frontstep to process leads 24/7, respond instantly to inquiries, and maintain conversation context across multiple interactions. One in three leads complete the full qualification process without any manual intervention from the realtor. 3 I believe that this high qualification rate can be attributed to the fact that frontstep.ai responds in a matter of seconds, and that response comes through to the Zillow platform, while the prospective tenant is still scrolling on the app.

Takeaways

It makes sense why Zillow built a fence around their data and made it tough to integrate directly - this seems to be especially common in the Real Estate SaaS space. It also makes sense why they allow realtors to reply directly to the email and have those populate in the dashboard, as realtors are always on the go and living out of their inbox. One thing that I still don't understand though, is why Zillow didn't implement a simple step to verify that the email address responding to the lead notification email was the same as the one it was sent to...

I learned that app "integrations" can take many forms under the hood. As developers, we apprecaite and a lot of the times expect that these be made possible via well-documented, clean, and straightforward APIs, but sometimes that isn't an option. At the end of the day, the only thing that really matters is how the customers interact with the app and whether or not it solves their problem in a convenient way. In the case of frontstep.ai, we were able to build a system that was very easy to use and effectively ran on autopilot once set up. I only subjected clients to an unprompted technical deep-dive a few times...

Footnotes

  1. We even had a meeting with a couple people from Zillow Group, where we tried to get some sort of deal or exception to this rule. That unsurprisingly didn't go anywhere. We were two 22 year olds with 0 paying customers and hardly even a working prototype.

  2. This is example Zillow notification email was provided to us by our first beta testing client, JR Associates.

  3. As of January 4 2026, frontstep.ai has fully qualified 118 of the total 336 leads that it saw for an average of 34% qualification across all teams using the platform.