# Changelog of Airbnb Experiences · Host Emails by City (`corent1robert/airbnb-experiences-scraper`) Actor

- **URL**: https://apify.com/corent1robert/airbnb-experiences-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/corent1robert/airbnb-experiences-scraper.md

## Changelog

All notable changes to this project will be documented in this file.

Format: [Keep a Changelog](https://keepachangelog.com/) — `MAJOR.MINOR` for Apify actor versions.

***

### \[1.8] — 2026-08-24

#### Changed

- Store suite: README and listing copy name Airbnb Pro Host for home-rental emails. Dropped “Store does not cross-sell”.

### \[1.7] — 2026-08-23

#### Changed

- Store listing, Console copy, and dataset views brought to current marketplace standard (Overview + Outreach / CRM).
- Default run **1024 MB** (HTTP-only). Default max experiences **10**. Platform proxy on by default.
- **Email enrichment** PPE fires only when a host email is actually found (listing rows still use the Experience event).
- Unit tests for parsers, city currency, and empty-field omit.

#### Fixed

- Empty dataset fields omitted. Retry on failed search/detail fetches.

### \[1.6] — 2026-08-19

#### Changed

- Store categories: `TRAVEL`, `LEAD_GENERATION`. README **Also available** (Airbnb suite) at the top.

### \[1.5] — 2026-08-19

#### Changed

- **Free plan cap:** 20 experiences per run (`APIFY_USER_IS_PAYING`). Status: `Free plan: 20 experiences. Upgrade for bulk.`
- Anonymous Try-without-account runs disabled (`isAnonymouslyRunnable: false`).

### \[1.4] — 2026-06-01

#### Added

- **Phone number extraction** — `host_phone` field populated from website crawl and Google snippets using a multi-format regex (French local, French international, international E.164).

#### Changed

- `crawlForEmail` replaced by `crawlForEmailAndPhone` — a single page fetch now extracts both email and phone simultaneously.
- Log summary line now includes phone when found alongside email.

***

### \[1.3] — 2026-06-01

#### Added

- **Host deduplication** — `contactCache` Map in `main.js` prevents redundant `enrichContact` calls when the same host appears across multiple experiences. Run log now reports unique hosts queried.

#### Changed

- Enrichment log summary: one concise line per host (`[contact] HostName — domain | email (source, score:N)`), replacing verbose per-step logs.

***

### \[1.2] — 2026-06-01

#### Added

- `_logResult` helper — single-line enrichment summary per host at the end of the cascade.

#### Fixed

- `tryEmail` now filters snippet emails by `websiteDomain` once a host website is identified, preventing false positives from unrelated domains (e.g. `contact@moncoco.paris` rejected when `ptitcoco.paris` is the confirmed site).
- `verifyWebsiteRelevance` — unconditional `domainInTitle` trust restored; new concat-name match in `titleNorm`; `return true` when no significant keywords can be derived.
- `scoreDomain` concat bonus now requires `>= 2` significant tokens (prevents single first-name matches like "Adrian" or "Matt" from inflating unrelated domain scores).
- `buildSearchQueries` business-name queries now use `acceptAny: true` to avoid over-filtering legitimate business sites.
- `SCORING_STOP_WORDS` expanded with common first names (adrian, felix, matt, gregory…).
- `SKIP_DOMAINS` expanded to block OTAs, media/news sites, and aggregators.

***

### \[1.1] — 2026-05-31

#### Added

- **Contact enrichment** (`enrichContact: true`) — multi-stage cascade to find the host's external website and email:
  - Google search via `autom.dev` API (website discovery + email snippet extraction).
  - Content verification (`verifyWebsiteRelevance`) — fetches candidate site and checks for host keywords.
  - Domain scoring (`scoreDomain`) — ranks domains by relevance to host name and meeting point.
  - Website crawl — homepage + `/contact`, `/about`, and localised equivalents.
  - GPT-4o mini validation — confidence score 0–100; emails below `minEmailScore` threshold are dropped.
  - Trusted-source bypass — emails found by crawling a verified official website skip GPT scoring.
- **Pay-Per-Event pricing** — `Actor.charge({ eventName: 'contact-enrichment' })` at $0.03 per unique host enriched.
- `host_website`, `host_email`, `host_email_source`, `host_email_score` output fields.
- `deploy.sh` — automates `apify push --force` followed by Apify API injection of `AUTOM_DEV_API_KEY` and `OPENAI_API_KEY` as Actor version environment variables.
- Unified `targets` input field — accepts city names (`Paris, France`) or Airbnb Experience URLs on the same line, auto-detected.
- Currency auto-detection from city country (France → EUR, UK → GBP, USA → USD, etc.).

#### Changed

- `maxExperiences` default changed from `50` to `0` (no cap).
- `minEmailScore` hidden from Console UI (defaults to `70`; overridable via raw JSON input).
- `scrapeDetails` is now always enabled implicitly — detail page enrichment (meeting point, address, next date) runs for all experiences.
- Input schema simplified: removed proxy config, minimum rating, language, and API key fields from Console UI.

#### Fixed

- `environmentVariables` block removed from `actor.json` — `@secretName` syntax does not work for private actors.

***

### \[1.0] — 2026-05-30

#### Added

- Initial release.
- City search mode: extract Airbnb Experiences by `City, Country` query.
- Direct URL mode: enrich specific Airbnb Experience URLs.
- `niobeClientData` parser for Airbnb's embedded JSON (plain HTTP, no browser).
- Pagination support via cursor extraction.
- Base fields: title, host name, price, currency, duration, rating, review count, badges, cover photo, URL.
- Optional detail enrichment: meeting point, address (locality, region, country), next available date, full description.
- `maxExperiences` cap with `0` = no limit.
- Dataset views: `overview` and `full export`.
- `RUN_LOG` key-value store output with phase progress and summary.
- `.apifyignore` — excludes `storage/`, `output.csv`, local inputs.
