# Airbnb License Check, US & Canada Short-Term Rental Licenses (`wellbuilt_zythem/airbnb-license-check`) Actor

Check Airbnb listings against the official short-term rental register: active, expired, unknown or no license shown (Austin, Denver, Seattle, Toronto, Vancouver, Quebec). Plus the STR registers of 10 US cities and 3 Canadian ones: status, expiry, address, holder, phone and email where published

- **URL**: https://apify.com/wellbuilt_zythem/airbnb-license-check.md
- **Developed by:** [Carlos Escanez](https://apify.com/wellbuilt_zythem) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 licenses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Airbnb License Check & Short-Term Rental Licenses, US & Canada

Check Airbnb listings against the **official short-term rental register of their city or province**. For every listing you get the license number it shows and what the register says about it: **active, expired, not in the register, or no license shown at all**.

Measured on the first Airbnb search page of each place on 2026-10-15:

| Place | Listings checked | Active license | Expired | Not in the register | No license shown |
|---|---|---|---|---|---|
| Austin, TX | 30 | 8 | 0 | 1 | 21 |
| Denver, CO | 30 | 12 | 2 | 3 | 13 |
| Toronto, ON | 30 | 19 | 0 | 0 | 11 (all hotel rooms, which need no registration) |
| Vancouver, BC | 20 | 11 | 2 | 1 | 6 |
| Mont-Tremblant, QC | 20 | 19 | 0 | 1 (Airbnb itself shows its number expired in 2025) | 0 |

The same run exports the **short-term rental registers of ten US cities and three Canadian ones**, read live from each government's open-data portal: license number, type, status, issue and expiry dates, address, holder and owner, and the **phone and email the register publishes** (six of the thirteen do). Pick the licenses issued in the last N days for a feed of new hosts, or export a whole register.

Who uses it: cities and compliance teams (listings without a valid license), property managers, cleaners, photographers and insurers (newly licensed hosts with a phone and email), and investors sizing how regulated a market is.

More Airbnb data from the same publisher: [Airbnb Multi-Listing Hosts by City](https://apify.com/wellbuilt_zythem/airbnb-host-portfolio), [Airbnb New Listings & Price Drops by City](https://apify.com/wellbuilt_zythem/airbnb-new-listings) and [Airbnb Reviews Scraper by City or Listing, Translated](https://apify.com/wellbuilt_zythem/airbnb-reviews).

### Registers, measured on 2026-10-15

| Code | Place | Register rows | New per month | Phone | Email | Airbnb check |
|---|---|---|---|---|---|---|
| `austin` | Austin, TX | 3,210 | no issue date | no | no | **yes** (5 of 6 listings show the number) |
| `denver` | Denver, CO | 2,363 | ~75 | no | no | **yes** (5 of 6) |
| `seattle` | Seattle, WA | 5,561 active | no issue date | no | no | partial (1 of 6) |
| `toronto` | Toronto, ON | 8,722 | ~250 (month in the number) | no | no | **yes** (8 of 8 homes) |
| `vancouver` | Vancouver, BC | 13,551 (2024 to 2026) | ~40 | no | no | **yes** (6 of 8) |
| `quebec` | Quebec province | 13,719 | no issue date | 94 % | 92 % | **yes** (8 of 8), checked in Mont-Tremblant |
| `nashville` | Nashville, TN | 17,612 | ~50 | no | no | no |
| `new_orleans` | New Orleans, LA | 4,318 active | ~300 | 54 % | 54 % | no |
| `louisville` | Louisville, KY | 1,227 | ~70 | 99 % | 98 % | no |
| `atlanta` | Atlanta, GA | 1,747 | no issue date | 100 % | 100 % | no |
| `orlando` | Orlando, FL | 531 | ~4 | 97 % | 94 % | no |
| `chicago` | Chicago, IL | 3,767 approved | n/a | no | no | no |
| `sacramento` | Sacramento, CA | 530 active | no issue date | 100 % | no | no |

"Phone" and "email" are the share of register rows that carry them. A place marked "no" does not publish that field, so the column is empty there on purpose. Places with no issue date always return their full register (up to **Max licenses per city**). Austin publishes the address at block level only ("BLOCK OF 1500 HOLLY ST").

#### Canada, what each register gives

- **Toronto**: registration number, address with unit, first three characters of the postal code, property type and ward. No status or expiry date. The number carries the month of registration (`STR-2610-…` = October 2026), delivered as `registeredMonth`.
- **Vancouver**: business licence number, status (`Issued`, `Pending`, `Cancelled`, `Gone Out of Business`, `Inactive`), issue and expiry dates and the neighborhood. **No address and no holder name**: the city does not publish them for short-term rentals. Licences are renewed every year with a new number (`25-…` in 2025, `26-…` in 2026), so a listing still showing last year's number is shown as expired.
- **Quebec**: the province's tourist accommodation register for cottages, apartments and tourist residences. Registration number, establishment name, street address (89 %), municipality, tourist region, postal code prefix, coordinates, capacity, **phone (94 %) and email (92 %)**. Mont-Tremblant alone has 1,024 entries.
- **Quebec does not publish principal-residence registrations**, which are most short-term rentals in Montreal (272 entries in the register). A Quebec number missing from the register is reported as `license_not_in_published_registry`, not as an unknown license. Airbnb shows the expiry date next to Quebec numbers; it is delivered as `licenseExpiryOnListing`, with `listingShowsExpiredLicense`.

#### Where the Airbnb check works, and why not everywhere

The check needs the license number on the Airbnb listing page. Austin and Denver hosts show it on 5 of 6 listings, Seattle hosts on 1 of 6, Toronto on every home, Vancouver on 6 of 8, Quebec on 8 of 8 (measured). In New Orleans, Chicago, Nashville, Orlando and the other US cities the number is not in the page Airbnb serves, so the check is skipped with a note in the log instead of being guessed from an address. Airbnb blurs listing locations by a few hundred meters, so matching by address would be wrong too often to sell.

### What you get

**Airbnb check rows** (`listing_check` event): `roomId`, `url`, `name`, `price`, `rating`, `reviews`, `hostName`, `isSuperhost`, `propertyType` (as Airbnb names it: "Entire condo", "Room in hotel"...), `licenseOnListing`, `licenseExpiryOnListing` (Quebec), `listingShowsExpiredLicense` (Quebec), `match` (`license_active`, `license_expired`, `license_not_in_registry`, `license_not_in_published_registry`, `no_license_shown`) and, when matched, the register's `registryLicenseNumber`, `registryStatus`, `registryExpirationDate`, `registryAddress`, `registryMunicipality`, `registryBusinessName`, `registryHolderName`, `registryOwnerName`, `registryPhone`, `registryEmail`.

**License rows** (`license` event): `city`, `state` (state or province), `country` (`US`, `CA`), `licenseNumber`, `licenseType`, `status`, `isExpired`, `issuedDate`, `registeredMonth` (Toronto), `licenseYear` (Vancouver), `expirationDate`, `address`, `unit`, `municipality`, `neighborhood`, `region`, `zip`, `latitude`, `longitude`, `businessName`, `holderName`, `operatorName`, `ownerName`, `ownerAddress`, `phone` (E.164), `email`, `website`, `propertyType`, `bedrooms`, `guests`, `units`, `parcel`, `ward`, `register`, `sourceUrl`, `scrapedAt`. Fields a register does not publish are absent.

The dataset has two views in the Console: **Licenses** and **Airbnb check**.

### Input

| Field | What it does |
|---|---|
| **Cities** | Codes from the table above: `austin`, `denver`, `seattle`, `toronto`, `vancouver`, `quebec`, `nashville`, `new_orleans`, `louisville`, `atlanta`, `orlando`, `chicago`, `sacramento`. Empty for all. |
| **Check Airbnb listings** | Austin, Denver, Seattle, Toronto, Vancouver and Quebec (Mont-Tremblant listings). **Airbnb pages per city** 1 to 10 (about 18 listings each). |
| **Licenses issued in the last N days** | Default 30. Or give **Issued from / to**. |
| **Every license** | Export the whole register instead of recent ones. |
| **Only licenses with a phone or email** | Keep the contactable ones. |
| **Max licenses per city** | Default 1,000. |
| **Socrata app token** | Optional, your own quota on the Socrata portals. |

```json
{
  "cities": ["toronto", "vancouver", "quebec"],
  "checkAirbnb": true,
  "airbnbPages": 3
}
```

```json
{
  "cities": ["quebec", "new_orleans", "louisville", "atlanta"],
  "allLicenses": true,
  "onlyWithContact": true
}
```

### Speed and limits

- A register answers in 1 to 5 seconds per 1,000 rows; Quebec's is a single 9 MB file, read once per run. The Airbnb check adds about 2 seconds per listing, three at a time, through Apify proxy.
- The run stops 45 seconds before its timeout and delivers what it read.
- No login, no CAPTCHA: official open-data APIs (Socrata, ArcGIS, CKAN, OpenDataSoft, Données Québec) and Airbnb's public pages. Scottsdale publishes a register too, but behind Cloudflare, so it is not included.

### Pricing

Per license row (`license`) and per Airbnb listing checked (`listing_check`), plus the platform's start fee. Rows filtered out cost nothing.

# Actor input Schema

## `cities` (type: `array`):

One per line: austin, denver, seattle, toronto, vancouver, quebec (these six support the Airbnb check), nashville, new_orleans, louisville, atlanta, orlando, chicago, sacramento. Empty for all thirteen.

## `checkAirbnb` (type: `boolean`):

Reads the Airbnb search pages and each listing page, takes the license number the listing shows and looks it up in the register: active, expired, not in the register, or no license shown. Works in Austin and Denver (5 of 6 listings show the number, measured), Toronto (every home), Vancouver (6 of 8), Quebec (8 of 8, checked on Mont-Tremblant listings) and Seattle (1 of 6); other cities are skipped with a note.

## `airbnbPages` (type: `integer`):

Search pages to read when checking Airbnb (about 18 listings each, 30 on the first). 1 to 10.

## `issuedWithinDays` (type: `integer`):

Default 30. Seattle, Austin, Sacramento and Atlanta publish no issue date, so they always return their full register (up to "Max per city").

## `issuedFrom` (type: `string`):

Date like 2026-09-01. Overrides the N days.

## `issuedTo` (type: `string`):

Date like 2026-09-30. Empty: today.

## `allLicenses` (type: `boolean`):

Ignore the dates and export the whole register of each city (up to "Max per city").

## `onlyWithContact` (type: `boolean`):

New Orleans publishes contact on 54 % of licenses, Quebec 94 %, Orlando 97 %, Louisville 99 %, Atlanta and Sacramento 100 %; the other places none.

## `maxPerCity` (type: `integer`):

License rows to deliver per city. The Airbnb check always compares against the whole register, whatever this says.

## `socrataAppToken` (type: `string`):

Optional. Gives the run its own quota on the Socrata portals (New Orleans, Denver, Orlando, Chicago, Seattle, Austin).

## `proxyConfiguration` (type: `object`):

Only used by the Airbnb check. City registers need no proxy.

## Actor input object example

```json
{
  "cities": [
    "austin",
    "denver"
  ],
  "checkAirbnb": true,
  "airbnbPages": 1,
  "issuedWithinDays": 30,
  "allLicenses": false,
  "onlyWithContact": false,
  "maxPerCity": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "cities": [
        "austin",
        "denver"
    ],
    "checkAirbnb": true,
    "airbnbPages": 1,
    "maxPerCity": 200,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("wellbuilt_zythem/airbnb-license-check").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "cities": [
        "austin",
        "denver",
    ],
    "checkAirbnb": True,
    "airbnbPages": 1,
    "maxPerCity": 200,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("wellbuilt_zythem/airbnb-license-check").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "cities": [
    "austin",
    "denver"
  ],
  "checkAirbnb": true,
  "airbnbPages": 1,
  "maxPerCity": 200,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call wellbuilt_zythem/airbnb-license-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,wellbuilt_zythem/airbnb-license-check"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/6GbW8hZnm2q1JYq0Y/builds/vjhc51BldB2LZqJ0j/openapi.json
