Landline
Every voice agent in real estate works for the brokerage. Landline works for the renter.
Inspiration
Renting in Toronto is a phone job. A listing says "available now", "parking included", "pet friendly", and you only find out what is true when you call. So you call. One agent doesn't pick up, one says it's already gone, one tells you parking is another $180 a month, one wants an e-transfer deposit before you have even seen the place. Finding one apartment can mean dozens of calls, made during work hours, often in your second language.
Newcomers get hit hardest. They don't know the neighbourhoods, they may not be comfortable on the phone in English, and they are the easiest target for fake listings.
Meanwhile, every voice AI in real estate we could find works for the other side: it answers the brokerage's phone, qualifies leads and books showings for the landlord. Nobody had built the agent that sits on the renter's side and makes those calls for them. That is Landline.
What it does
Landline is a voice agent for renters. You talk to it, it phones the listing agents for you, and it texts you what it learned.
- You call and say what you want, in your own words and your own language. "A one-bedroom near Bloor under $2,600. I have a dog." You can call a phone number or talk to it in the browser.
- A live map of Toronto re-ranks while you talk. About 1,080 real listings start as faint dots and narrow to a numbered shortlist. Say "natural light matters most" and the pins renumber before you finish the sentence. Say "that one's too dark" and darker units sink. Tap a pin and the agent knows which place you're looking at. Every card says why it ranks where it does: "$310 under budget · 6 min walk to Spadina · bright (14th floor)".
- You pick the places and hang up. "Call the top three. I'm free Saturday afternoon, book one if you can." The agent reads the addresses back and says it will text you.
- Landline phones every listing agent at the same time. Each call opens with "I'm an AI assistant calling for a renter." It asks what listings never say: is it still available, what parking really costs, are dogs allowed, how much light it gets. It reads every number back, and if the landlord asks something it can't answer, it says "I'll check with my client" and brings the question back to you.
- It books a viewing, but only inside the times you gave. If you didn't allow booking, it collects times instead.
- The map updates and you get a text. Each place shows what the agent heard, with the landlord's exact words next to every fact. A place that asks for a deposit before a viewing gets flagged. Then a text arrives:
I booked 650 Briar Hill Avenue for Saturday at 2 pm, inside your Saturday afternoon. 30 Carabob Court is really $2,179 a month with parking. The agent at 30 Carabob Court asked, "Would they sign a 12-month lease?" I said I'd check with you. 701 Don Mills Rd wants a deposit by e-transfer before anyone sees the unit, so I'd skip it. Nobody picked up at 1915 Martin Grove Rd.
Try it
- Call +1 (289) 512-2338 and say what you want.
- Talk in the browser at https://landline-mu.vercel.app/try. Here the listing calls go to simulated landlords, so no phone rings.
- No microphone? https://landline-mu.vercel.app/?dev=1 runs a scripted demo.
For safety, real listing calls only go to our own team's phones (an allowlist), with teammates playing the listing agents, and only during Toronto business hours.
How we built it
Higgs Audio is the core of the product.
- Higgs Realtime (speech to speech over WebSocket) runs every voice in Landline. The Concierge talks to the renter, over the phone (μ-law 8 kHz through Twilio) or in the browser (24 kHz PCM), and moves the live map through six function tools. After the renter hangs up, one Caller per listing, each its own Higgs Realtime session, phones a listing agent in parallel and records facts, questions and bookings through its own tools. In judge mode and in our evals, another Higgs Realtime session plays the landlord.
- Higgs speech-to-text (
higgs-stt-3.1) transcribes both sides of every call. Those transcripts are what we check every fact against. - Higgs text chat with JSON-schema output is one of the text models behind the Auditor, which pulls facts out of call transcripts. It also translates the results text into the renter's language.
- Higgs TTS generates the renter and landlord voices our audio eval streams through the real voice paths.
Two flows that never overlap. First the renter's call (the brief), then the listing calls. The only thing passed between them is a frozen call plan that code writes when the renter hangs up: which listings, which questions, which viewing times, and whether booking is allowed. This removed a whole class of race conditions we had in an earlier prototype, and it means each flow can be tested on its own.
Models do language. Code does everything that must be right every time. Only three parts use a model: the Concierge, the Callers and the Auditor. Everything else is plain, deterministic code:
- An orchestrator routes every event and keeps exactly one writer per session.
- The Matcher ranks listings in memory from typed features (real monthly cost, location, size, floor, natural light, parking, pets, laundry, walk to the nearest TTC subway) in about 1.4 ms, and explains each rank in plain words.
- The Dispatcher dials one call per picked listing, within a concurrency limit and business hours, and only to allowlisted numbers.
- The Narrator fills templates for what the agent says and texts.
A model never supplies an id, a phone number, a time or a price total. When a landlord says "Saturday at two", code turns it into a date and only accepts the booking if it falls inside the renter's window.
Every fact has a source. The Auditor keeps a fact only if its quote appears word for word in what the landlord said, never in the agent's own words. If the quote isn't there, the fact is dropped.
Data. We scraped about 1,080 Toronto listings politely (one page every two seconds), placed each one in one of the City of Toronto's 158 neighbourhoods with PostGIS, matched it to the nearest of 68 TTC subway stations, and gave it a natural-light score from its floor, the listing text and the brightness of its photos.
Stack. Python and FastAPI on one always-on VM, Postgres with PostGIS and pgvector, Twilio for phone calls and texts, and a Next.js web app with MapLibre on Vercel that follows each session live over server-sent events.
Built on earlier work. Landline grows out of Realest, a prototype our team built at Agents, Everywhere in September. We ported a few pieces (the Twilio bridge, SMS sending, some ranking ideas), each in its own commit marked as ported, and made sure 19 known bugs from that prototype didn't come with them. The two-flow design, the Higgs integration, the parallel callers, the map, the data pipeline and the evals were built for this hackathon.
Challenges we ran into
- Calls that never end, or end twice. A phone call can end in many ways: the landlord hangs up, voicemail picks up, nobody answers, the line is busy, the socket drops, the agent says goodbye, or time runs out. All of them now go through one
finalize()function, the first one wins, and every call has a deadline. - Higgs surprises. Higgs follows the newer OpenAI Realtime protocol, not the older one our prototype used, so we rewrote the client. Adding instructions to a single response replaces the whole session's instructions: every goodbye we sent that way came out as "Hello! How can I help you today?" (21 of 21). Higgs also sends about ten seconds of audio in just over one second, so to handle interruptions and line up recordings with transcripts we had to keep our own playback clock.
- Tool calls that looked fine but saved nothing. The model sent numbers where the schema expected text, so "call the top two" failed silently. It sent arguments meant for a different tool, which were quietly dropped while the reply said "saved". Tool replies now say exactly what was not saved and how to fix it.
- The first Caller read every answer back and recorded none of them. It sounded perfect on the phone and saved nothing. It took a strict rule ("tools are the only way anything is saved"), a worked example, and tool replies that name the next question.
- Languages on phone audio. A mixed Farsi and English sentence on 8 kHz phone audio came back garbled, and some languages still get English replies.
- Keeping the agent honest. Making sure a fact only counts when the landlord said it, not when our agent said it, meant tagging every line with its speaker and checking every quote.
- 24 hours, three people, three lanes. We froze shared contracts at kickoff so data, voice and web could be built in parallel without breaking each other.
Accomplishments that we're proud of
- It acts on its own. One conversation turns into parallel phone calls, booked viewings and a results text, with no human in between.
- No fact without a source. On our held-out call transcripts, 0 of 17 facts were shown without a landlord's quote. The Auditor scored 100% precision and 91% recall.
- The Callers do the job. Against simulated landlords on held-out personas, they covered 96% of their checklist, recorded 95% of facts with the right value, said they were an AI assistant first in 10 of 10 calls, and booked inside the renter's times in 14 of 14 bookings.
- It handles interruptions. When someone talks over the agent, it stops and answers what was said: 12 of 12 in our audio eval.
- The map keeps up with your voice. Ranking takes about 1.4 ms on 4,000 listings, so the pins move while you are still talking.
- Real data. 1,082 real Toronto listings, every one placed in a City neighbourhood, matched to a subway station and given a light score.
- We measured instead of guessing. Every number above comes from an eval with separate tune and holdout sets. We tuned prompts on one and reported only the other.
What we learned
- Let the model talk; let code decide. The best results came from giving models only language: understanding speech, choosing a tool, reading a transcript. Ids, money, dates, ranking and who gets called are all code.
- Evals pay off right away. Our first eval run found tool calls that saved nothing and a Caller that recorded nothing, bugs that sounded fine in a live demo. Holdout sets kept us from fooling ourselves.
- Simple architecture beats clever architecture. Splitting the product into two flows joined by one frozen record removed more bugs than any fix we wrote.
- Voice is a different interface. Silence feels broken, numbers have to be read back, and the goodbye has to come before the call ends, not after.
- Read the protocol, then test it. Several things we assumed about Higgs turned out differently live, and we wrote down each one so the next person doesn't trip on it.
What's next for Landline
- Call real listing agents. Today calls only go to our own phones. Next: an opt-in flow with consent and clear disclosure on every call.
- Remember renters between calls. Recognize a returning caller by phone number and open with what changed: "Welcome back, Sara. I booked 412 Markham for Saturday at two."
- Read more from listings. Pull pets, parking and laundry out of listing descriptions, with a quote for each, and join the City of Toronto's building records so renters see a building's inspection history.
- Better language support. Reply in every language the renter speaks, including on phone audio, and send the results text in that language.
- More cities, starting with the rest of the GTA.
- More for the renter after the calls: listen back to any call, follow up with a landlord on the renter's answer to their question, and compare places side by side.
Built With
- docker
- fastapi
- github-actions
- higgs-realtime
- higgs-speech-to-text
- higgs-tts
- maplibre-gl
- next.js
- nginx
- openfreemap
- pgvector
- postgis
- postgresql
- pydantic
- python
- react
- server-sent-events
- tailwind-css
- toronto-open-data
- twilio
- typescript
- vercel
- websockets
Log in or sign up for Devpost to join the conversation.