> ## Documentation Index
> Fetch the complete documentation index at: https://docs.telzino.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Listings Search

> Let your agent search your live listings page during a call, read back matching rentals, and text the caller a link.

**Listings Search** lets your agent answer "Do you have a 2-bedroom under \$1,800 that takes dogs?" while the caller is on the line. It reads your public listings page, finds the rentals that match, reads two or three back, and can text the caller the listing or the application link.

There is no integration to connect and no API key. You give it the address of your listings page.

## Supported listings pages

<CardGroup cols={2}>
  <Card title="AppFolio — built in" icon="circle-check">
    Your AppFolio listings page, for example `https://yourcompany.appfolio.com/listings`, works directly, and can also read each listing's own page for its deposit and application fee.
  </Card>

  <Card title="Any other public listings page" icon="magnifying-glass">
    For example a Buildium or ShowMojo listings page, or the rentals page on your own website. Listings are read automatically after you save: on each refresh the page is fetched, and an AI model reads it and returns the listings on it whenever the page text has changed (and at least once a day).
  </Card>
</CardGroup>

The address must start with `https://`. On an AppFolio address, anything after `/listings` (filters, tracking parameters, a trailing `/`) is removed automatically. On any other address the path and query are kept as you typed them; only a `#…` fragment is dropped.

The address must be a public web address. Addresses with a username, password or port, IP addresses, `localhost`, and internal or reserved names (for example names ending in `.local`, `.internal`, `.localdomain`, `.lan` or `.test`) are refused.

<Warning>
  **Pages that load their listings with JavaScript are not supported yet.** Some websites send an empty page and fill in the listings afterwards in the browser. When the first refresh finds no listings on a page like this, the function row shows *"This page loads its listings with JavaScript, which can't be read. Use your listings provider's own page."* Use the listings page your property software hosts instead (for example yourcompany.appfolio.com/listings, or your Buildium or ShowMojo listings page).
</Warning>

<Tip>
  **Your own website shows your AppFolio listings?** Many websites display AppFolio listings through an AppFolio widget. If you save such a page, the first refresh recognizes the widget and the function row shows *"This page shows AppFolio listings. Use this address instead:"* followed by your AppFolio listings address. Open the function, paste that address into **Listings page address**, tick the confirmation again, and save; AppFolio pages work directly.
</Tip>

Your listings page is only read if the site's `robots.txt` allows it. A site that disallows reading its listings page cannot be used. The one exception is **Include deposit and application fee** on an AppFolio page: each listing's own page is read even if `robots.txt` disallows it, on the strength of your confirmation that the site belongs to your business. Those reads still wait the `Crawl-delay` your `robots.txt` sets (up to 30 seconds), and each one is logged.

## What the agent can do

<AccordionGroup>
  <Accordion title="Find matching rentals">
    The agent can search by city, county, state, ZIP code, street, bedrooms, bathrooms, rent, move-in date, whether dogs or cats are allowed, and whether a community is age-restricted. It searches as soon as the caller asks, gets up to three matches (cheapest first), reads two or three, and asks a narrowing question rather than reading a long list.

    At the start of each call the agent is given the places, bedroom counts and other search values your listings actually have, spelled exactly as your listings page spells them (including any misspellings on the page). It searches only with those values. If the caller names a place that is not among them, or it is not clear which one they mean, the agent tells them the places it has and asks, rather than guessing.

    Anything else, such as a pool, parking, a pet size or weight limit, or a pet fee, the agent answers from that listing's own description, amenities and pet wording. It says a rental has something only when the listing says so, and never claims more than the listing's own words: when a caller asks for something more specific, the agent says what the listing says and that your leasing team can confirm the rest. If the listing does not mention it, the agent says so.
  </Accordion>

  <Accordion title="Look up a listing by its street">
    Callers can ask about a specific rental, for example *"Is the one on Main Street still available?"*. The agent looks that rental up by its street alone, without the caller's earlier search requirements, and answers from that listing's own details. The caller's wording does not have to match exactly: when no listed street is written exactly as the caller said it, the agent is given the closest listed streets, each with its listing's reference. If one of them is clearly the rental the caller means, the agent looks that listing up by its reference straight away; otherwise it asks the caller which one they mean, naming at most three, or tells them the street is not listed. Streets are read from your listings; there is nothing to set up.
  </Accordion>

  <Accordion title="Hear more results">
    Each search returns up to three matches, cheapest first. When the caller asks what else there is, the agent fetches the next three from the same search.
  </Accordion>

  <Accordion title="Read accurate details">
    Each rental is read the same way, for example: *"123 Main Street in Springfield — 3 bedroom, 1 bath, \$1,825 a month, available now."* The agent states only facts that appear in your listings and never estimates rent, deposits, fees or availability. A listing with no rent is described as "rent on request".

    A listing that does not state the detail a caller filtered on (for example its pet policy, rent, bedroom count or available date) is left out of that search, and the agent is told how many were left out.
  </Accordion>

  <Accordion title="Text a listing or application link">
    Before texting, the agent says which rental the link is for by its address and asks whether it is okay to text the caller the link. It sends the text only after the caller clearly says yes; an acknowledgement, a thank-you or a goodbye is not a yes. It then texts the link for that rental, for example *"123 Main Street, Springfield: https\://… - sent by Your Company"*. The "sent by" name is the **Business name for texts** you set, or the agent's name if you leave it empty.

    The text names the rental it is for, and the agent tells the caller which rental's link is on its way. It goes to the number the caller is calling from, or to another number the caller gives. If the caller's number is withheld, the agent asks for a mobile number. The agent sends at most three texts per call, and never texts the same link to the same number twice in one call.

    AppFolio listings always have a listing link, and an application link when the listing shows one. Listings from other pages often have no application link; the agent then offers the listing link instead. A listing with no link of its own is texted your listings page address.

    Texting needs a text-message carrier on the agent: **Twilio** (see [Send SMS](/functions/send-sms)) or **NetSapiens** (see [SMS via NetSapiens](/functions/netsapiens-sms)). Without one, the agent does not offer to text and tells callers where to find your listings instead.
  </Accordion>

  <Accordion title="Handle 'nothing matches'">
    The agent offers to loosen one requirement (budget, area or bedrooms), and to take the caller's details for your leasing team.
  </Accordion>
</AccordionGroup>

## How fresh the information is

Your listings page is re-read on the schedule you choose: every 10, 15, 30 or 60 minutes. The agent always answers from the most recent successful read, and never reads your website during a call.

* If the latest successful read is more than 90 minutes old (for example because refreshes are failing), the agent tells the caller roughly how many hours ago the listings were last updated and that they may have changed.
* If the listings cannot be loaded (there has been no successful read for 24 hours, there is no read yet, or the source is disabled), the agent stops quoting listings. It does not say nothing is available: it tells the caller it can't look the listings up right now, gives them your listings page address, for example *yourcompany.appfolio.com/listings*, and offers to take their details.

## Setting it up

<Steps>
  <Step title="Open the agent's functions">
    **Dashboard:** open the agent's settings and, under **Functions**, click **Add function**. **Connect:** open the agent's edit page and, under **Functions**, click **Add**.
  </Step>

  <Step title="Choose Listings Search">
    If **Listings Search** is not in the list, it is not enabled for your organization. Ask your provider (see [Availability controls](#availability-controls)).
  </Step>

  <Step title="Enter your listings page address">
    Type the address in **Listings page address**. The editor notes: *"Works with AppFolio and other public listings pages. Listings are read automatically after you save."* A problem with the address is shown under the field straight away (see [Address messages](#address-messages)).
  </Step>

  <Step title="Confirm you are authorized">
    Tick the confirmation:

    > I confirm this listings site belongs to this business, or the business is authorized to display it, and I authorize Telzino to read it on the business's behalf.

    It is required, and it is recorded with the signed-in user who saved the function and the time. Changing the address clears the tick, because a different page is a different authorization. On an AppFolio page, turning **Include deposit and application fee** back on also needs a fresh tick.
  </Step>

  <Step title="Choose the options">
    **Include deposit and application fee** (AppFolio pages only, on by default) reads each listing's own page, slowly, at most once per listing change, to pick up those amounts. These pages are read even if your site's `robots.txt` disallows them, because of the confirmation you ticked. For other pages, deposit and application fee are used only when the listings page itself shows them. Turning the option off removes deposit and application fee from your listings at the next refresh.

    **Refresh every** sets how often the page is re-read: 10 (default), 15, 30 or 60 minutes.

    **Business name for texts (optional)** is the name listing texts are "sent by", up to 100 characters. Leave it empty to use the agent's name.

    **Instructions** (up to 4,000 characters) tell the agent when to search, for example *"When a caller asks what rentals are available, search listings as soon as they give a location, budget or bedroom count, and read two or three that match."*
  </Step>

  <Step title="Save">
    **Dashboard:** click **Add Function** (or **Save Changes** when editing), then save the agent. **Connect:** click **Save Listings Search** (or **Save Changes** when editing), then save the agent.

    The first read happens within about a minute of saving. The function row then shows its status.
  </Step>
</Steps>

### How listings pages are read

Every refresh fetches the page. When its text has changed since the last read, or the last read was on an earlier day, an AI model (gpt-4.1-mini) returns the listings on it: address, rent, beds, baths, available date, whether dogs and cats are allowed, whether it is an age-restricted community, the page's own pet wording, and the other details the page states. Text such as street and place names is kept exactly as the page writes it; nothing is corrected or merged. Details the page does not state are left empty, never guessed. The county comes from the listing's ZIP code. Text on your page is treated as listing data, never as instructions to your agent.

A listing or application link is kept only if that exact link appears on the page itself. When it does not, the agent texts your listings page address instead of a listing link, and when a caller asks for an application link that the page does not show, the agent offers the listing link.

AppFolio pages are read the same way. For an AppFolio page with **Include deposit and application fee** on, the AI model also reads each listing's own page for its deposit and application fee, including when `robots.txt` disallows those pages. No AI model reads your website during calls: the agent always answers from the most recent refresh.

Each listings page is read once per refresh, and that one copy is shared by every agent that uses the page.

## Fair housing

The agent states listing facts only. It will not describe a neighborhood or who lives there, call an area safe, quiet or family-friendly, or steer a caller toward or away from any rental because of who they are. These rules apply whatever your **Instructions** say.

* **Who qualifies:** the agent never decides or says whether the caller qualifies for a rental. An age-restricted community (for example 55+) is stated only as a listing fact; your leasing team decides who qualifies.
* **Assistance animals:** a service or support animal is not treated as a pet. The agent does not apply a listing's pet rules to it, tells the caller your leasing team handles assistance animal requests, and offers to take their details.

## Recommended model

For agents that use Listings Search we recommend the **GPT-4.1** model rather than **GPT-4.1 Mini**. In testing, the smaller model followed the listing rules less reliably, for example keeping addresses exactly as listed, handling eligibility questions, and stating specific pet limits. The model is set in the agent's **Model** setting (in Connect, under [Advanced Settings](/admin-guide/connect/managing-agents#advanced-settings-detached-only)) or with `model` on [Update Agent](/api-reference/agents/update).

## Cloning an agent

In Connect, cloning an agent **within the same domain** copies its Listings Search function, with the same page and attestation. The clone is refused if the source agent's attestation is missing; open the source agent, fix it as the message says, save, then clone.

Cloning to **another domain** does not copy Listings Search. The clone dialog says *"Answer rules, failover and Listings Search are not copied across domains — configure them on the target after cloning."* Someone in the target organization adds Listings Search and ticks the confirmation themselves.

## Status and troubleshooting

### The function row

The Listings Search row in the agent's function list shows the address and how the last read went.

| Status shown | What it means | What to do |
| - | - | - |
| **Save the agent to start refreshing listings.** | The function was added but the agent has not been saved yet. | Save the agent. |
| **Waiting for the first refresh (usually under a minute after saving).** | The agent was just saved and the page has not been read yet. | Wait a minute and reopen the agent. |
| **Up to date · refreshed** *time* **· N listings** | The last read succeeded. | Nothing. |
| **Refreshed** *time* **· N listings · some listings could not be read** | The read succeeded, but some listings were missing required details and were skipped, the number of listings fell by more than half since the last read, the page showed more than 300 listings (only 300 are used), or some AppFolio listing pages could not be read for deposit and fee. The agent uses what was read. | Check that the listings page looks normal in a browser. If it does and this persists, contact support. |
| **The page shows more listings than were read on the last refresh, so some listings may be missing. The ones that were read are being served. If this keeps happening, the page may have too many listings to read at once. · refreshed** *time* | The page was read, but it showed more listings than the AI model returned, so some listings may be missing. The agent uses the listings that were read. | Usually it recovers on the next refresh. If it persists, use a page that shows fewer listings at once, or the page your property software hosts. |
| **No listings found on the page right now · refreshed** *time* | The page was read but showed no listings. The agent tells callers no listings are posted, points them to your page, and offers to take their details. | If you do have vacancies, open the page in a browser. If the listings are there and this persists, use the listings page your property software hosts, or contact support. |
| **This page shows AppFolio listings. Use this address instead:** *address* **· refreshed** *time* | A non-AppFolio page was read, and it shows your listings through an AppFolio widget, so no listings are read from it. | Open the function, paste the address shown into **Listings page address**, tick the confirmation again, and save. |
| **This page loads its listings with JavaScript, which can't be read. Use your listings provider's own page. · refreshed** *time* | A non-AppFolio page was read, but its listings are filled in by JavaScript in the browser, so none could be read. | Use the listings page your property software hosts. |
| **Most listings on the page could not be read right now · last good copy** *time* | The page was read, but most of its listings could not be read. The agent keeps using the last good copy for up to 24 hours. | Check that the page looks normal in a browser. Usually it recovers on the next refresh; if it persists, contact support. |
| **This listings page is too large to read · last good copy** *time* | The page has more text or more listings than can be read in one refresh. The agent keeps using the last good copy for up to 24 hours. | Use a page that shows fewer listings at once, or the page your property software hosts. |
| **Refresh failing:** *reason* **· last good copy** *time* | The page could not be read. The agent keeps using the last good copy for up to 24 hours. | See the reasons below. |
| **Not refreshing (no agent uses this source).** | The page has not been read for this agent for a day. Callers hear where your listings are instead of listings. | Open the function, check the address and the confirmation, and save the agent. If it persists, contact support. |
| **Listings status is unavailable right now. Reload the page to try again.** | The status could not be loaded. This says nothing about the listings themselves. | Reload the page. |
| An address message | The saved address is no longer accepted. | Correct the address (see [Address messages](#address-messages)), then save. |

#### Refresh failing reasons

| Reason shown | Cause | What to do |
| - | - | - |
| `fetch:timeout`, `fetch:deadline`, `fetch:connection` | Your site did not answer in time, or could not be reached. | Check the page opens in a browser. Usually it recovers on the next refresh. |
| `fetch:http_` followed by a number (for example `fetch:http_404`, `fetch:http_403`) | Your site answered with that error. `404` means the page no longer exists at that address; `403` means the site refused the request. | Check the address. If the page moved, enter the new address. |
| `fetch:rate_limited` | Your site asked us to slow down. | Choose a longer **Refresh every** interval. |
| `fetch:robots_disallowed`, `fetch:robots_unavailable` | The site's `robots.txt` now disallows reading the page, or could not be read. | Allow the page in `robots.txt`, or use the page your property software hosts. |
| `fetch:not_html`, `fetch:too_large` | The address no longer returns a web page, or the page is larger than 2 MB. | Use the listings page your property software hosts. |
| `fetch:redirect_off_site`, `fetch:too_many_redirects`, `fetch:bad_redirect`, `fetch:unsafe_destination` | The page now redirects to another site, redirects in a loop, or points at an address that is not a public website. | Enter the final address of your listings page. |
| `llm:timeout`, `llm:connection`, `llm:rate_limited`, `llm:http_5xx` | The AI model that reads the page did not answer in time, could not be reached, or was busy. | Nothing; it usually recovers on the next refresh. If it persists, contact support. |
| `llm:invalid_output`, `llm:not_configured` | The AI model returned an unusable answer, or page reading is not set up on our side. | Contact support with this reason. |
| `parse_exception` | The page could not be read. | Contact support with this reason. |

Some reasons appear in the function row as a message instead of a code: `rows_unreadable` (*Most listings on the page could not be read right now*), `rows_incomplete` (*The page shows more listings than were read on the last refresh, so some listings may be missing.* …), `page_too_large` and `too_many_listings` (*This listings page is too large to read*), `embedded_appfolio:` followed by an address (*This page shows AppFolio listings. Use this address instead:* …) and `js_rendered` (*This page loads its listings with JavaScript, which can't be read.* …). See the table above.

### Address messages

| Message | Cause |
| - | - |
| *Enter the address of your listings page.* | The field is empty. |
| *That is not a valid web address. It should look like [https://yourcompany.appfolio.com/listings](https://yourcompany.appfolio.com/listings) or [https://www.yourcompany.com/rentals](https://www.yourcompany.com/rentals)* | The address has spaces or unusual characters, has no scheme such as `https://`, or is longer than 2,048 characters. |
| *The listings address must start with https\://* | The address starts with `http://` or another scheme. |
| *The listings address cannot contain a username, password or port.* | The address contains `user@` or a port such as `:8080`. |
| *That web address does not have a valid public host name.* | The address uses an IP address, `localhost`, an internal or reserved name (such as `.local`, `.internal` or `.localdomain`), or a name that is not a public domain. |
| *That AppFolio address is not a company listings page. Use your own, for example [https://yourcompany.appfolio.com/listings](https://yourcompany.appfolio.com/listings)* | An AppFolio address that is not a company's own listings site, such as `www.appfolio.com`. |
| *Use your AppFolio listings page itself, for example [https://yourcompany.appfolio.com/listings](https://yourcompany.appfolio.com/listings)* | An AppFolio address that points at a single listing or another page. |

## Availability controls

Listings Search is a **Capability** in [Feature Administration](/admin-guide/dashboard/feature-administration). It is locked for every organization by default, including organizations created later. A partner unlocks it for an organization in the matrix.

When it is locked for an organization:

* **Listings Search** does not appear in the function list.
* Adding it, changing its listings page, or turning on **Include deposit and application fee** is refused.
* Agents that already have it keep searching listings on calls, and their Listings Search function stays editable and removable.

To set it up through the API, see the `listings_search` tool on [Create Agent](/api-reference/agents/create) and [Update Agent](/api-reference/agents/update).

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Does the agent fill in applications or book showings?">
    No. It texts your own application or listing link. The caller applies or books on your site.
  </Accordion>

  <Accordion title="Can two agents use the same listings page?">
    Yes. Add Listings Search to each agent.
  </Accordion>

  <Accordion title="Can I use a page on a website I don't control?">
    No. Only a page that belongs to your business, or that your business is authorized to display.
  </Accordion>

  <Accordion title="Can an agent search more than one listings page?">
    Not yet. An agent can have one Listings Search function.
  </Accordion>

  <Accordion title="Why are deposit and application fee missing for my non-AppFolio page?">
    For pages that are not on AppFolio, only the listings page itself is read, not each listing's own page. If the listings page doesn't show those amounts, the agent says the listing does not state them.
  </Accordion>

  <Accordion title="I already have a function named search_listings. Why can't I save?">
    Listings Search needs the function names `search_listings` and `send_listing_link`. Saving shows *Another function is named "search\_listings", which Listings Search needs. Rename or remove that function to use Listings Search.* Rename or remove the other function first.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.