# Changelog of Talabat Scraper — Menus, Prices & Delivery Fees (`redomic/talabat-scraper`) Actor

- **URL**: https://apify.com/redomic/talabat-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/redomic/talabat-scraper.md

## Changelog

### 0.1 (13 Nov, before first publish)

- `area` mode includes menus by default (`includeMenus: true`): one menu row per item with price and currency for each branch delivered to the area (one `menu` charge per branch). Set `includeMenus: false` for branch-only rows.

- `area` mode: every branch delivering to a Talabat area page, 15 per page until `maxItems`, with `deliveryFee`, `deliveryTimeMinutes`, `minimumOrder`, `open`, promotion, coordinates and a `menuUrl` carrying the area. Pages from the canonical area slug (a wrong slug redirects and drops `?page=`).

- `area` mode `includeMenus`: each listed branch's full menu in the same run, one `menu` charge per branch.

- `menu` mode: one row per menu item (`itemName`, `section`, `price`, `oldPrice`, `currency`, `priceFromChoices`), charged once per complete branch menu (`menu` event). Choice-priced items get `price: null`, never 0; a menu URL without `?aid=` fails with a status row that says so.

- First build: reads Talabat's public server-rendered pages over plain HTTP (no proxy, no login, no browser) for eight markets: `uae`, `ksa`, `kuwait`, `qatar`, `bahrain`, `oman`, `egypt`, `jordan`.

- Three modes: `search` (Talabat's own restaurant search with pagination up to `maxItems`), `detail` (full restaurant page per URL/slug: rating, rating count, coordinates, vendor/area ids, payment methods, cash/card flags, top-selling items) and `monitor` (new/changed/removed since the previous run, state kept in the `talabat-scraper-state` key-value store, keyed by str(id) so two unchanged runs bill $0 and end SUCCEEDED).

- Flat data rows with a stable `id`, canonical `url`, normalised `cuisines` + `cuisineCount`, numbers as numbers and booleans as booleans; monitor rows carry `changeType`.

- Never silent: one status row per input (`ok`/`empty`/`failed` with a reason), the summary row is always last, a search or detail run with zero restaurants exits non-zero, and a page that is not the expected shape raises a parse error instead of emitting wrong rows.

- Pay per result: `result` $0.004 per restaurant in search/detail, `change` $0.004 per new or changed restaurant in monitor mode; status, summary and removed rows are free, and delivery stops at the buyer's maximum charge.

### Unreleased

- Search and area modes: added `minRating`, `openNow`, `freeDelivery`, and `cuisines` filters to return only matching branches (filters applied during collection before `maxItems`). In search mode, `openNow` and `freeDelivery` are applied only when a restaurant row exposes that state, so searches still return rows when availability is not provided by the search endpoint.
- Per-input `_status` rows and the run `summary` are stored in the run key-value store (`STATUS` and `SUMMARY`) instead of the dataset, so the dataset and exports contain only restaurant, menu and monitor change rows.
- Quality: added live captured fixtures and tests for UAE search queries `pizza`, `burger` and `sushi` (battery inputs) to ensure they parse and return rows with an ok status.
- Quality: captured a live fixture for the 2026-11-15 failing menu battery input (branch page with zero items) and added parser/run tests asserting it returns no data rows and an explicit per-input `empty` status with a reason (no silent empty success).
