Inspiration

Finding a place to live is rarely as simple as finding a listing. Renters often have to search across several websites, compare inconsistent information, calculate commute times, verify policies, and make trade-offs between budget, space, location, and lifestyle.

We wanted to build an agent that could handle this entire decision process instead of acting like a basic chatbot. The idea behind Keys by Friday was to create a rental search partner that remembers what the renter cares about, gathers evidence from multiple sources, and helps them make a confident decision.

What it does

Keys by Friday lets renters describe their needs in natural language, such as their city, budget, bedroom requirements, parking preferences, pets, and commute limits.

The agent then:

  • Searches rental listings across multiple sources.
  • Normalizes and groups listings from different providers.
  • Filters out homes that fail hard requirements.
  • Ranks the remaining options using deterministic criteria.
  • Checks commute requirements using Google Routes when requested.
  • Verifies details for selected listings.
  • Compares homes side by side.
  • Explains trade-offs and clearly identifies information that is still unknown.
  • Lets users save listings to a persistent shortlist.
  • Remembers requirements across follow-up messages.

Instead of simply returning search results, Keys by Friday helps renters understand why a home is a good match and what still needs to be verified.

How we built it

The frontend was built with Next.js and provides the conversational search experience, listing cards, map and commute views, comparison panel, recent searches, and shortlist interactions.

The backend was built with FastAPI. It provides the API boundary between the browser and the rental agent, validates responses, manages authentication, and persists application data.

The core agent was built with Google’s Agent Development Kit and Gemini. We implemented one rental agent with four product tools:

  • search_listings()
  • get_listing_details()
  • get_route_details()
  • compare_candidates()

Gemini handles natural-language requirement parsing, follow-up conversations, tool selection, and explanations. Deterministic Python code remains responsible for provider access, listing normalization, hard filtering, ranking, commute evaluation, detail merging, and structured comparison facts. This separation helps prevent the agent from inventing rental details or overriding hard constraints.

For data and infrastructure, we used:

  • RealtyAPI to search multiple rental sources, including Apartments.com, Zillow, and Realtor.
  • Google Routes for commute evidence.
  • Firebase Authentication for anonymous user identity and ownership protection.
  • Firestore for conversation metadata, recent searches, rate limiting, and saved shortlist data.
  • Cloud SQL for PostgreSQL with Google ADK’s persistent database session service.
  • Cloud Run to deploy and verify the FastAPI backend.
  • Vertex AI / Gemini for the production agent path.

Challenges we ran into

Everyone on our team was using Google ADK for the first time. We had to learn how ADK agents, tools, session state, runners, and persistent sessions fit together while also designing a reliable product around them.

This was also our first time building a complete application on Google Cloud. Setting up Cloud Run, Vertex AI, Firebase Authentication, Firestore, Cloud SQL, Google Routes, Secret Manager, IAM permissions, health checks, and deployment configuration took significant time. We had to learn not only how to make the application work locally, but also how to make the deployed system secure, persistent, observable, and cost-controlled.

Another major challenge was finding a reliable rental listing API. No single provider gave us complete coverage or perfectly consistent data. Different sources returned different fields, formats, prices, policies, and levels of detail. We eventually built a multi-source provider layer that normalizes the results while preserving source-specific information.

We also learned that an agent should not be trusted as the sole source of factual decisions. Gemini is excellent at understanding requests and explaining results, but hard constraints and unknown data need deterministic handling. We designed the system so that missing information remains unknown instead of being guessed.

Accomplishments that we're proud of

We built a complete end-to-end rental decision experience rather than a simple chat interface.

We are especially proud that:

  • The agent can carry out a multi-step search, verification, commute, and comparison workflow.
  • Follow-up messages preserve the renter’s earlier requirements.
  • Search results from multiple providers are normalized and grouped without hiding source differences.
  • Hard constraints are enforced deterministically.
  • Unknown facts remain explicitly unknown.
  • Selected listings can be verified and compared using structured evidence.
  • Shortlists and conversation metadata persist through Firestore.
  • ADK session state can persist through PostgreSQL and Cloud SQL.
  • The backend was deployed and verified on Google Cloud Run.
  • Authentication, ownership checks, rate limiting, health checks, and readiness checks are included.
  • The project has a reproducible local setup and a comprehensive automated test suite.
  • Our final verification included 221 passing Python, backend, and Agent tests, along with 78 passing frontend tests. This gave us confidence in the core search, persistence, comparison, authentication, and user-interface flows.

Most importantly, Keys by Friday demonstrates an agent doing real work: searching external data, applying constraints, checking routes, comparing options, and helping a person move toward a decision.

What we learned

We learned that building a useful agent is as much about system design as it is about prompting.

Google ADK gave us a strong foundation for tool-based agent behavior and session management, but we still needed clear boundaries around what Gemini could decide and what the application had to verify deterministically.

We also learned the importance of treating persistence as separate responsibilities. Firestore stores product data such as conversations and shortlists, while the ADK session database stores the agent’s event history and conversational state. Keeping those responsibilities separate made the architecture easier to reason about.

Working with real rental data taught us how messy external APIs can be. Provider abstraction, canonical data models, evidence tracking, and graceful handling of unknown fields were essential for building a trustworthy experience.

Finally, deploying on Google Cloud taught us that infrastructure is part of the product. Authentication, secrets, database readiness, cost controls, logging, and deployment verification all matter when an agent is expected to operate reliably.

What's next for Keys by Friday

Our next goal is to close the loop from rental discovery to real-world action.

Once a renter decides which home they want, Keys by Friday will run a consent-based agent loop that can contact the landlord by email or supported messaging channel, introduce the renter’s requirements, ask about availability, coordinate possible tour times, and add the confirmed room tour to the renter’s calendar.

The agent will ask for confirmation before sending messages or booking appointments, handle scheduling conflicts and missing responses, and keep the conversation state updated throughout the process. This would transform Keys by Friday from a rental search assistant into an end-to-end moving companion that helps users go from “I like this place” to “my tour is scheduled.”

Built With

Share this project:

Updates

posted an update

Latest Update

  • Added Zillow and Realtor.com alongside Apartments.com for multi-source rental search.
  • Improved result grouping so the same property can be compared across different sources with source links and pricing.
  • Added persistent search filters and cache-first refinements, allowing users to naturally narrow results without unnecessary RealtyAPI calls.
  • Improved Zillow filtering/link handling and added regression tests for the updated search and session flow.
  • The latest version is now available in a new feature branch and has been opened as a PR to dev for review.

Log in or sign up for Devpost to join the conversation.