Skip to content
ListingrailGet an API key

How to get PadMapper listings in Python

By the end of this guide you have a CSV of Toronto rentals from PadMapper with rent in CAD, bedrooms and the property manager, from one script you can run again tomorrow. Everything below was run on 16 October 2026; the output table is what it returned.

Why scraping PadMapper yourself breaks

  • PadMapper, owned by Zumper, has no public API and no data program. Listings reach it through Zumper's syndication, and there is no official way to read them.
  • The HTML pages are protected against bots. The data comes from the JSON search call the site makes itself, which you have to find and replicate.
  • That call takes PadMapper's own city slug ("toronto-on"), not a free-text place.

None of that is impossible, but each point is code you then maintain. The rest of this guide uses Listingrail, which does the reading and hands back clean JSON. The PadMapper API page has the official options with sources.

1. Get a key

One request with your email returns a key with 100 free listings. It is shown once, so keep it in an environment variable.

curl -X POST https://listingrail.com/v1/signup \
  -H "content-type: application/json" \
  -d '{"email": "you@example.com"}'

export LISTINGRAIL_KEY=re_...

2. Search and save to CSV

Install requests (pip install requests), then run:

import csv
import os

import requests

r = requests.post(
    "https://listingrail.com/v1/listings/search",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={"source":"padmapper","location":"Toronto, ON","type":"rent","limit":50},
    timeout=300,
)
r.raise_for_status()
listings = r.json()["listings"]

fields = ["price", "currency", "beds", "baths", "area", "address", "url"]
with open("padmapper-toronto-on.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(fields)
    for home in listings:
        writer.writerow([home[k] for k in fields])

print(len(listings), "listings saved to padmapper-toronto-on.csv")

The request body, on its own:

{
  "source": "padmapper",
  "location": "Toronto, ON",
  "type": "rent",
  "limit": 50
}

Each listing returned costs one credit. A search that finds nothing, or fails at PadMapper, costs nothing. A request can take up to a minute or two, because PadMapper is read at that moment.

3. What comes back

The first three rows of the run on 16 October 2026:

AddressPriceSizeAgent
950 Lansdowne Ave, Toronto, ON M6H 0E62,099 CAD / month1 bd · 1 baThe Diamond
748 Bathurst St, Toronto, ON M5S 2R62,030 CAD / month0 bd · 1 baPeterson Rentals
980 15 Assembly Lane, Toronto, ON M6H 4B42,675 CAD / month1 bd · 1 baFitzrovia

Every listing has the same keys on all 17 portals, so the code for PadMapper reads the others too. Fields PadMapper does not show come back as null, and the portal's own record sits in raw. With pandas:

import pandas as pd

df = pd.DataFrame(listings)
df["agent"] = df["agent"].str.get("company")
print(df[["price", "beds", "baths", "area", "address", "agent"]].head())

4. Get new listings and price cuts every day

Running the script on a schedule works, but then you compare the files yourself. A monitor stores the search, checks it once a day, and sends only what changed: new listings and price cuts. The free key holds one monitor.

requests.post(
    "https://listingrail.com/v1/monitors",
    headers={"Authorization": f"Bearer {os.environ['LISTINGRAIL_KEY']}"},
    json={
        "source": "padmapper",
        "location": "Toronto, ON",
        "filters": {"type":"rent"},
        "webhook_url": "https://example.com/new-listings",
    },
    timeout=30,
)

Changes can also be read with GET /v1/monitors/{id}/changes or downloaded as CSV. Plans and limits are on the monitors page.

PadMapper quirks worth knowing

  • Pass a city and state or province, e.g. "Toronto, ON". It is sent as the slug toronto-on.
  • Canadian listings come back in CAD, US ones in USD. price_period is "month".
  • price and beds are the lowest of the building's range (raw.price_max and raw.beds_max hold the top). beds 0 is a studio.
  • area was empty on every row of this run. agent.name is the building's name, agent.company the property manager; agent.phone is mostly empty.

Questions

Is there a PadMapper API?

No public one. PadMapper does not publish a developer page, and listings flow in from Zumper, not out.

Is this the same data as Zumper?

PadMapper and Zumper share a backend. Use "source": "zumper" for the US with the same listing format.

Can I filter by rent?

Yes: minPrice, maxPrice and minBeds are sent with the search.

Get 100 free listingsAPI docsOther guides