# Trendyol Scraper - Products, Sellers, Reviews & Q\&A (`abotapi/trendyol-scraper`) Actor

From $0.80/1K. Scrape Trendyol products, prices, ratings, badges, sellers, full reviews and Q\&A. Search by keyword with filters, paste search, category, store or product URLs, or use reviews-only mode for a list of products.

- **URL**: https://apify.com/abotapi/trendyol-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 89 total users, 14 monthly users, 76.3% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.80 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Trendyol Scraper: Products, Prices, Reviews & Q\&A

Trendyol Scraper turns Trendyol, Turkey's largest online marketplace, into structured data. Search by keyword, browse Trendyol's own Red, Orange and Yellow campaign tiers plus the rotating flash-sale pool, or paste any Trendyol URL (search, category, store or product page), and get back product listings with prices, discounts, ratings, badges and seller details. Switch on review summaries or Q\&A per product, or run reviews-only mode for full review streams against a list of products. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **Three modes in one actor.** Keyword search with filters, paste-any-URL (search, category, store or single product), or reviews-only for one row per review.
- **Trendyol's own campaign tiers as a first-class picker.** Red, Orange and Yellow discount tiers plus the rotating Flash sale pool, combinable with a keyword search for the color tiers.
- **Deep product records.** Roughly 75 fields per product with detail fetching on (the default), or around 50 with `fetchDetails` off: full attribute list, merchant info, category tree, English category translations and the winning variant's barcode and stock.
- **Rich filters.** Price range and sort order are sent to Trendyol's own search; minimum rating, free shipping, fast delivery, official seller, collectable coupon and in-stock are applied to every fetched page.
- **Reviews and Q\&A on demand.** Attach a rating breakdown and review text, or answered Q\&A pairs, to each product, or pull reviews for a list of products on their own.
- **Built for schedules.** Incremental mode returns only new and changed products on recurring runs, and a run that gets blocked fails loudly with a clear message instead of quietly returning an empty dataset.

### Use Cases

- **E-commerce and pricing teams:** track competitor prices, discount percentages and stock levels across a category or a list of stores.
- **Deal hunters and content creators:** pull the Red, Orange and Yellow campaign tiers and the flash-sale pool to publish daily deal roundups.
- **Marketplace sellers:** monitor rival sellers' badges (official seller, free shipping, fast delivery), coupons and pricing in a given category.
- **Review and reputation analysts:** harvest full review streams and Q\&A pairs for sentiment analysis or customer research.
- **Market researchers:** build historical pricing, discount and rating datasets for Turkish e-commerce trend analysis.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `kind` | `"product"` (also `"review"` in reviews-only mode) |
| `contentId` / `groupId` | `100000001` / `100000000` |
| `url` | `"https://www.trendyol.com/apple/apple-iphone-15-128-gb-mavi-cep-telefonu-p-100000001"` |
| `name` | `"Apple iPhone 15 128 GB Mavi Cep Telefonu"` |
| `brand` | `"Apple"` |
| `category` | `{ "id": 103498, "name": "Cep Telefonu" }` |
| `price.current` / `price.original` | `27999.0` / `32999.0` |
| `price.discountPercent` | `15.2` |
| `price.currency` | `"TL"` |
| `rating.score` / `rating.totalRatings` | `4.6` / `18342` |
| `seller.name` | `"ABC Teknoloji Mağazası"` |
| `image` / `images` | Trendyol CDN thumbnail URL(s) |
| `stock` / `inStock` | `120` / `true` |
| `freeCargo` / `fastDelivery` / `officialSeller` | `true` / `false` / `true` |
| `hasCoupon` / `hasFlashSale` | `false` / `false` |
| `isOnSpecial` / `savingsAmount` | `true` / `5000.0` (real strikethrough discount, never fabricated) |
| `specialsCategory` | `"red-deals"` when the record came from the specials picker, else `null` |
| `reviews` | first batch of up to 50 reviews (only when `fetchReviews=true`, which also fills `rating.breakdown`) |
| `qna` | answered Q\&A pairs (only when `fetchQna=true`) |
| `scrapedAt` | `"2026-01-01T00:00:00.000Z"` |
| `changeType` | `"NEW"` (only when `incrementalMode=true`: also `UPDATED`, `UNCHANGED`, `REAPPEARED`, `EXPIRED`) |

Reviews-only mode returns one row per review instead, with `kind: "review"`, `productContentId`, `rate` (1 to 5), `comment` (Turkish review text), `userFullName` (mostly redacted by the site itself), `likesCount`, `language` (`"tr"`) and `createdAt`. With `fetchDetails` on (the default), or when you paste a direct product URL, each record carries roughly 25 more fields: the full attribute spec list, merchant details (name, city, tax number, seller score), the four-level category tree, English category translations and the winning variant's barcode, stock and tags.

#### Output views

The dataset has six views: **Results** (all rows), **Overview**, **Reviews**, **Product detail**, **Q\&A** (one row per question) and **Changes** (incremental `changeType` and `changedFields`). A run summary is saved under the `OUTPUT` key of the key-value store.

#### Extra filters and input aliases

- `lowestPriceDays` (10 / 14 / 30), `influencerPreferredOnly` and `specialOffersOnly` narrow results using the listing's own markers (lowest-price-in-N-days label, influencer badge, real strikethrough discount). They apply to search and URL modes; each record now carries `lowestPriceDays`.
- Alternative input names are accepted: `startUrls` (as `urls`), `getReviews`, `getQna`, `maxReviews`, `maxQna`, `limit` (as `maxListings`) and `minimumStarRating` (as `minRating`). An alias is applied only while your own field is still at its own default (`maxListings` 20, `maxReviewsPerProduct` 200, `maxQnaPerProduct` 20, `minRating` 0, `fetchReviews`/`fetchQna` off); any other value of your own field wins over the alias, even a value that is another field's default (for example `maxReviewsPerProduct` 20 stays 20).

### How to Use

1. Pick a **mode**: `search` (keyword plus filters), `url` (paste any Trendyol URL), or `reviews` (pull reviews for a list of products).
2. In search mode, add a keyword, price/rating/badge filters, a sort order, or pick a campaign tier instead of (or with) a keyword.
3. Switch on `fetchReviews` and/or `fetchQna` for extra fields (turn off `fetchDetails` for a leaner, cheaper run), and set **Max products** and **Max pages** to bound cost.
4. Click **Start**, then download the dataset as JSON, CSV or Excel, or read it through the API.

**Search by keyword with filters:**

```json
{
  "mode": "search",
  "queries": ["iphone 15"],
  "minPrice": 5000,
  "maxPrice": 50000,
  "minRating": "4",
  "sortBy": "PRICE_BY_ASC",
  "freeCargoOnly": true,
  "maxListings": 50
}
```

**Browse a campaign tier instead of a keyword:**

```json
{
  "mode": "search",
  "specialsCategory": "red-deals",
  "maxListings": 30
}
```

**Paste a Trendyol URL:**

```json
{
  "mode": "url",
  "urls": [
    "https://www.trendyol.com/cep-telefonu-x-c103498",
    "https://www.trendyol.com/magaza/ornek-magaza-m-100000"
  ],
  "maxPages": 3,
  "maxListings": 100,
  "fetchReviews": true
}
```

**URL mode shapes and default.** If you run url mode without touching the `urls` field, it now scrapes one example of each shape below (previously it had no default). Pagination starts at the `pi=` page in the URL, and `siralama=` / `sst=` sort orders are honoured.

| Shape | Example |
|---|---|
| Keyword search | `https://www.trendyol.com/sr?q=iphone+15&pi=1` |
| Paginated and sorted search | `https://www.trendyol.com/sr?q=iphone+15&pi=2&siralama=PRICE_BY_ASC` |
| Search with culture param | `https://www.trendyol.com/sr?q=iphone+15&pi=1&culture=tr-TR` |
| Campaign-tier search | `https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu` |
| Flash-sale hub | `https://www.trendyol.com/flas-indirimler` |
| Category | `https://www.trendyol.com/cep-telefonu-x-c103498?pi=1` |
| Category, paginated and sorted | `https://www.trendyol.com/cep-telefonu-x-c103498?pi=2&sst=PRICE_BY_ASC` |
| Seller store | `https://www.trendyol.com/magaza/apple-m-968` |
| Merchant-filtered search | `https://www.trendyol.com/sr?mid=968` |
| Product detail | `https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114` |
| Product reviews link | `https://www.trendyol.com/apple/x-p-356251114/yorumlar` |

Bare `/p-<id>` links, brand pages (`-x-b<id>`) and `ty.gl` short links are not served by Trendyol, so they are skipped with a warning in the log. `m.trendyol.com` links are mapped to `www.trendyol.com`.

**Reviews-only, for a list of products:**

```json
{
  "mode": "reviews",
  "productInputs": [
    "356251114",
    "https://www.trendyol.com/apple/ornek-urun-p-100000001"
  ],
  "maxReviewsPerProduct": 200
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/trendyol-scraper").call(run_input={"mode": "search", "queries": ["iphone 15"]})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(product["name"], product["price"]["current"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/trendyol-scraper').call({ mode: 'search', queries: ['iphone 15'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### Campaign tiers explained

Red, Orange and Yellow are Trendyol's own color-coded discount-severity tiers (kırmızı, turuncu, sarı kampanya, red is deepest), reachable with `specialsCategory` in search mode, or by pasting a tier URL in url mode (`https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu` and its orange/yellow equivalents). Flash sale is a separate, rotating hourly deal pool (`https://www.trendyol.com/flas-indirimler`); it is browse-only and does not combine with a keyword. Not every item in a tier carries an actual markdown, some are simply featured, so `isOnSpecial` and `savingsAmount` always reflect the real per-listing price comparison rather than tier membership.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one interrupted crawl: paste its run or dataset ID and this run skips every product already collected there, so you don't pay twice.
- **Incremental mode** (`incrementalMode`) is for scheduling the same search or URL set again and again. Each product is classified `NEW`, `UPDATED` (with `changedFields`), `UNCHANGED` (suppressed and not billed unless `emitUnchanged` is on), `REAPPEARED`, or `EXPIRED` (only after a run that scanned every tracked query/URL to a natural end, not when Max products capped it or Resume was used). `stateKey` names or shares the stored state. Change detection compares price, name, brand, seller, in-stock status, images, badges, promotions, categories and attributes; it ignores `scrapedAt`, the raw stock count, rating/review counters, `socialProof` counters, the order of attributes and badges, and the CDN host of image URLs (all stay in the output). Add more with `ignoreFieldsForChanges`. A partial scope (a pasted URL starting at page 2 or later, a capped or budget-trimmed walk) never marks products `EXPIRED`. One-time upgrade note: review and Q\&A fetching was repaired (they used to come back empty), so the first incremental run after the upgrade fills in `reviews`, `qna` and `lowestPriceDays` on already-tracked products without marking them `UPDATED` or billing them again; this applies once per tracked product, on the first run where its reviews and Q\&A were fetched successfully (a run where either fetch failed does not use it up), so afterwards a change to any of them (for example a first answered question arriving) is reported normally as `UPDATED`. A review or Q\&A fetch that fails during a run is not treated as a change: the stored value is kept, the product is not billed for it, and its row shows an empty value for that run. A product with no answered questions shows an empty `qna` list. With incremental mode off, output is unchanged.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search`, `url`, or `reviews`. |
| `queries` | array | (none) | Keywords for search mode; each runs as a separate search. |
| `specialsCategory` | string | (empty, no filter) | Browse `red-deals`, `orange-deals`, `yellow-deals`, or `flash-sale` instead of, or with, a keyword. |
| `sortBy` | string | `BEST_SCORE` | `BEST_SELLER`, `NEWEST`, `PRICE_BY_ASC`, `PRICE_BY_DESC`, `MOST_RATED`, or `MOST_FAVOURITE`. |
| `urls` | array | one example of each URL shape | Trendyol URLs to paste in url mode. |
| `productInputs` | array | (none) | Product URLs or numeric content IDs for reviews mode. |
| `maxReviewsPerProduct` | integer | `200` | Cap per product in reviews mode only (maximum 100000; the `reviews` list nested on product rows by `fetchReviews` is always one page of up to 50 and ignores this cap; default kept at 200 so saved tasks are unchanged). Reviews are billed as ordinary result rows, nothing extra. |
| `reviewSort` | string | `recommended` | Review order for reviews mode and for the reviews nested on product rows: `recommended` (Trendyol's default order), `newest`, `oldest`, `rating_desc`, `rating_asc`. Verified live against the review service (newest returns the latest dated reviews first, `rating_asc` starts with 1-star reviews). |
| `minPrice` | integer | (none) | Minimum price in storefront currency. Search and url modes. |
| `maxPrice` | integer | (none) | Maximum price in storefront currency. Search and url modes. |
| `lowestPriceDays` | string\[] | `[]` (none) | Keep listings carrying the lowest-price-in-N-days label (values `"10"`, `"14"`, `"30"`). Search and url modes. |
| `influencerPreferredOnly` | boolean | `false` | Keep only listings with the influencer-preferred badge. |
| `specialOffersOnly` | boolean | `false` | Keep only listings with a real strikethrough discount. |
| `minRating` | string | `0` | Drop products rated below this threshold. |
| `freeCargoOnly` | boolean | `false` | Keep only products with free shipping. |
| `fastDeliveryOnly` | boolean | `false` | Keep only products with the fast-delivery tag. |
| `officialSellerOnly` | boolean | `false` | Keep only products from verified-official sellers. |
| `couponsOnly` | boolean | `false` | Keep only products with a collectable coupon. |
| `inStockOnly` | boolean | `true` | Drop out-of-stock products. |
| `maxPages` | integer | `0` | Max SERP pages per query/URL (`0` = no per-search cap). |
| `maxListings` | integer | `20` | Total cap across all queries/URLs (`0` = unlimited). |
| `fetchDetails` | boolean | `true` | Fetch each product's detail page for roughly 25 extra fields. Each delivered product whose enrichment reads served is charged as one detail-page event (plus one more unit per started block of 10 review items attached). |
| `fetchReviews` | boolean | `false` | Attach a rating breakdown and review text to each product. |
| `fetchQna` | boolean | `false` | Attach answered Q\&A pairs to each product. |
| `maxQnaPerProduct` | integer | `20` | Cap on Q\&A pairs per product when `fetchQna=true` (maximum 1000; at most 50 are fetched per product). |
| `proxyConfiguration` | object | Residential, country TR | Connection settings. |
| `resumeFromRunId` | string | (none) | Continue one interrupted crawl (search/url modes). |
| `incrementalMode` | boolean | `false` | Return only new and changed products on scheduled runs (search/url modes). |
| `stateKey` | string | (none) | Name or share an incremental-mode state. |
| `ignoreFieldsForChanges` | string\[] | (none) | Incremental mode only: top-level fields or dotted nested paths (e.g. `badges`, `price.original`) that never make a product `UPDATED`. They stay in the output. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) unchanged products. |
| `emitExpired` | boolean | `false` | Also return (and bill) expired products. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which records are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "kind": "product",
  "contentId": 100000001,
  "id": 100000001,
  "groupId": 100000000,
  "url": "https://www.trendyol.com/apple/apple-iphone-15-128-gb-mavi-cep-telefonu-p-100000001",
  "name": "Apple iPhone 15 128 GB Mavi Cep Telefonu",
  "brand": "Apple",
  "brandId": 1000,
  "category": { "id": 103498, "name": "Cep Telefonu" },
  "price": {
    "current": 27999.0,
    "original": 32999.0,
    "discountPercent": 15.2,
    "currency": "TL"
  },
  "rating": { "score": 4.6, "totalRatings": 18342, "totalComments": 4210 },
  "seller": { "id": 100000, "name": "ABC Teknoloji Mağazası" },
  "image": "https://cdn.dsmcdn.com/mnresize/400/-/sample/100000001-800x600.jpeg",
  "stock": 120,
  "inStock": true,
  "freeCargo": true,
  "fastDelivery": false,
  "officialSeller": true,
  "hasCoupon": false,
  "hasFlashSale": false,
  "isOnSpecial": true,
  "savingsAmount": 5000.0,
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### Plan Requirement

This actor requires the Apify Residential proxy group with country set to Turkey (the prefilled default), available on paid Apify plans; keep it under Connection. Trendyol's protection challenges datacenter exits and redirects non-Turkish connections to a country-select page, so Datacenter does not work and there is no no-setup option. Apify free plans do not include residential proxies. On a free plan the run logs "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." and, if a page is served that way, "Served over the backup connection (the default connection was unavailable)." If nothing can be read, the run fails with one of: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required", "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Trendyol pages", or "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."

### FAQ

#### How much does it cost?

You pay per product or review returned, plus a one-time Actor start event, on the pay per event model. With the enrichment toggles on, each delivered product whose enrichment reads served is also charged as one detail-page event: the detail, review and Q\&A reads fold into the first unit, plus one more unit for every started block of 10 review items attached to the product; in reviews-only mode the charge is one unit per started block of 10 delivered review rows (that mode reads no detail pages). Products whose reads all fail, and products incremental mode suppresses as unchanged, are never charged. The **Pricing** tab always shows the current rates for every event. Use **Max products** and **Max pages** to cap the cost of any run.

#### Is it legal to scrape Trendyol?

This actor collects only publicly available product and review data. You are responsible for how you use it: follow Trendyol's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product listings and prices are generally facts, but review text, images and seller branding may be subject to third-party rights.

#### Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Each run then returns only new, updated and reappeared products, and unchanged ones are not billed unless you turn on **Emit unchanged**.

#### Why does search mode return fewer products than I expected?

Search mode stops once **Max products** or **Max pages** is reached, whichever comes first. Raise either (or set it to `0`) to walk further into the result set. Filters such as price range, rating or free shipping are applied after fetching, so a narrow filter combination can also shrink the count.

#### Why did my run fail instead of returning an empty dataset?

If Trendyol refuses every request the run makes, it stops with a clear error message, almost always because the proxy configuration is missing Residential access with country Turkey, so "no products matched" is never confused with "nothing could be read". If the site was reachable but genuinely had no matches for your search or filters, the run succeeds with 0 items and a status message instead.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more e-commerce data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🛒 <a href="https://apify.com/abotapi/tokopedia-scraper"><b>Tokopedia Scraper</b></a><br>Extract product data from Tokopedia, Indonesia’s largest marketplace. Search by keyword...</td><td>🛒 <a href="https://apify.com/abotapi/thegioididong-scraper"><b>Thegioididong Scraper</b></a><br>Scrape thegioididong.com products with full specifications, current &amp; original price...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/naver-brand-store-scraper"><b>Naver Shopping Scraper</b></a><br>Scrape Naver Shopping products by Korean or English keyword, or by URL. Returns 190+...</td><td>🛒 <a href="https://apify.com/abotapi/mercari-jp-scraper"><b>Mercari Japan Scraper</b></a><br>Scrape Mercari Japan listings, sellers and reviews at scale. Extract names, prices...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/lazada-scraper"><b>Lazada Scraper</b></a><br>Scrape Lazada products and reviews across SEA markets, including Malaysia, Singapore...</td><td>🛒 <a href="https://apify.com/abotapi/coupang-scraper"><b>Coupang Scraper</b></a><br>Scrape Coupang.com products by keyword, category or URL. Extract 20+ fields including...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/trendyol-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

search = discover products by keyword + filters. url = paste Trendyol URLs (search, category, store or product page). reviews = take a list of product URLs / IDs and dump their reviews only.

## `queries` (type: `array`):

One or more keywords. Each runs as a separate search; the per-query budget is split evenly across them.

## `specialsCategory` (type: `string`):

Browse one of Trendyol's own campaign tiers instead of (or combined with) a keyword search. Red/Orange/Yellow are the site's own discount-severity color tiers (kırmızı/turuncu/sarı kampanya — red is deepest); Flash sale is the site's rotating hourly deal pool (browse-only, does not combine with a keyword). Leave as 'No filter' for a plain keyword search.

## `sortBy` (type: `string`):

Site-native sort. BEST_SCORE is the default Trendyol relevance ranking.

## `urls` (type: `array`):

Paste any Trendyol URLs. Supported page types: search results (/sr?q=…), category (/<slug>-x-c<id>), seller store (/magaza/<slug>-m-<id>), single product (/<brand>/<slug>-p-<contentId>), a campaign-tier search (/sr?tag=…), the flash-sale hub (/flas-indirimler), a merchant-filtered search (/sr?mid=<id>) or a product reviews link (…-p-<id>/yorumlar). Sort with siralama= or sst=, start page with pi=. Left untouched, one example of each shape is scraped. Bare /p-<id>, brand (-x-b<id>) pages and ty.gl links are not served by Trendyol and are skipped with a warning; m.trendyol.com is mapped to www. Pagination walks forward from the page number embedded in the URL (default page 1).

## `productInputs` (type: `array`):

Either a full Trendyol product URL ending in /…-p-<contentId>, or just the numeric content ID. One row per review. Use maxReviewsPerProduct to cap how many you pull from each. Reviews mode is charged one detail-page unit for every started block of 10 delivered review rows (no detail-page base unit - this mode reads no detail pages).

## `maxReviewsPerProduct` (type: `integer`):

Reviews mode only: hard cap on how many reviews are pulled per product (the site exposes thousands for popular products, so a cap keeps cost and runtime predictable). Does not apply to the reviews attached to product rows by Fetch reviews, which always hold one page of up to 50.

## `reviewSort` (type: `string`):

Order of the reviews you get, in reviews mode and in the reviews attached to product rows (Fetch reviews). Recommended keeps Trendyol's own default order.

## `minPrice` (type: `integer`):

Minimum price in storefront currency (TL for TR, EUR/USD for international).

## `maxPrice` (type: `integer`):

Maximum price in storefront currency.

## `minRating` (type: `string`):

Drop products rated below this threshold.

## `freeCargoOnly` (type: `boolean`):

Drop products that don't include free shipping.

## `fastDeliveryOnly` (type: `boolean`):

Keep only products with the fast-delivery tag.

## `officialSellerOnly` (type: `boolean`):

Keep only products from sellers with the verified-official badge.

## `couponsOnly` (type: `boolean`):

Keep only products that currently offer a collectable coupon at checkout.

## `lowestPriceDays` (type: `array`):

Keep only products Trendyol flags as 'lowest price in the last N days'. Pick one or more of 10, 14, 30. Matched on the listing's own marker; empty = no filter.

## `influencerPreferredOnly` (type: `boolean`):

Keep only products carrying Trendyol's influencer-recommends badge.

## `specialOffersOnly` (type: `boolean`):

Keep only products with a real strikethrough discount (original price above current price).

## `inStockOnly` (type: `boolean`):

Drop products that are currently out of stock.

## `maxPages` (type: `integer`):

Maximum SERP pages to walk per query in search mode, or per URL in URL mode. 0 = no per-search cap (use maxListings to bound the total).

## `maxListings` (type: `integer`):

Total cap across all queries / URLs. 0 = unlimited (still bounded by maxPages). Ignored in reviews-only mode.

## `fetchDetails` (type: `boolean`):

When ON in search or URL mode, fetch each product's detail page and add ~25 extra fields: full attribute list, merchant info (name, official name, city, score), category tree, web brand, favorite count, max installment, tax %, refundable flag, merchandising group, English category translations, full promotions, winner variant with barcode + stock + tags. Costs roughly +1 fetch per product. Each delivered product whose enrichment reads served is charged as one detail-page event (plus one more unit for every started block of 10 review items attached); products whose reads all fail, and products incremental mode suppresses as unchanged, are not charged.

## `fetchReviews` (type: `boolean`):

When ON in search or URL mode, attach the rating breakdown + the first batch of review text to each product record. Costs roughly +1 API call per product.

## `fetchQna` (type: `boolean`):

When ON in search or URL mode, attach the answered Q\&A pairs to each product record. Costs roughly +1 API call per product. The Q\&A read folds into the per-product detail-page event unit (see Fetch detail-page fields).

## `maxQnaPerProduct` (type: `integer`):

Cap on Q\&A pairs per product when fetchQna = true.

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

Trendyol requires Apify Residential proxy with country = TR (the prefilled default) — Starter plan and above include Residential. On Datacenter or non-TR exits Trendyol rejects every request and the run returns an upgrade notice instead of products. You can also paste your own TR proxy URLs into the Custom proxies field and untick Use Apify Proxy.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large crawl of products without returning or charging for products already collected there. Use this after an interrupted run, or when continuing a product pull in another run. For recurring daily/weekly monitoring of the same search, use Incremental mode below instead.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. What is compared: price (current/original/discount), name, brand, seller, stock status (in stock or not), images, badges, promotions, categories, attributes and every other output field. What is excluded: scrapedAt, the raw stock count, rating and review counters, socialProof counters, the order of attributes/badges, and the CDN host of image URLs; these change on their own and never make a product UPDATED (they stay in the output). Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately for each mode/query/URL/filter combination; use State key when you want to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to let the actor derive a key automatically from the queries/URLs/specials tier/filters — different searches then never mix state with each other.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return products that have not changed since the last run, marked UNCHANGED. This returns — and bills — extra rows you already have, so leave it off unless you specifically want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return products that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned every tracked query/URL — not when Max products capped it, or when Resume was used. This returns — and bills — extra synthetic rows, so leave it off unless you need expiry tracking.

## `ignoreFieldsForChanges` (type: `array`):

Optional. Field names that must never make a product UPDATED, in addition to the built-in exclusions. Use a top-level name (for example badges) or a dotted path to a nested value (for example price.original). Ignored fields stay in the output, they are only left out of change detection and changedFields.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "iphone"
  ],
  "specialsCategory": "",
  "sortBy": "BEST_SCORE",
  "urls": [
    "https://www.trendyol.com/sr?q=iphone+15&pi=1",
    "https://www.trendyol.com/sr?q=iphone+15&pi=2&siralama=PRICE_BY_ASC",
    "https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu",
    "https://www.trendyol.com/flas-indirimler",
    "https://www.trendyol.com/cep-telefonu-x-c103498?pi=1",
    "https://www.trendyol.com/cep-telefonu-x-c103498?pi=2&sst=PRICE_BY_ASC",
    "https://www.trendyol.com/magaza/apple-m-968",
    "https://www.trendyol.com/sr?mid=968",
    "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
  ],
  "productInputs": [
    "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
  ],
  "maxReviewsPerProduct": 200,
  "reviewSort": "recommended",
  "minRating": "0",
  "freeCargoOnly": false,
  "fastDeliveryOnly": false,
  "officialSellerOnly": false,
  "couponsOnly": false,
  "lowestPriceDays": [],
  "influencerPreferredOnly": false,
  "specialOffersOnly": false,
  "inStockOnly": true,
  "maxPages": 0,
  "maxListings": 20,
  "fetchDetails": true,
  "fetchReviews": false,
  "fetchQna": false,
  "maxQnaPerProduct": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "TR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

## `overview` (type: `string`):

No description

## `detail` (type: `string`):

No description

## `reviews` (type: `string`):

No description

## `qna` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `summary` (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 = {
    "mode": "search",
    "queries": [
        "iphone"
    ],
    "urls": [
        "https://www.trendyol.com/sr?q=iphone+15&pi=1",
        "https://www.trendyol.com/sr?q=iphone+15&pi=2&siralama=PRICE_BY_ASC",
        "https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu",
        "https://www.trendyol.com/flas-indirimler",
        "https://www.trendyol.com/cep-telefonu-x-c103498?pi=1",
        "https://www.trendyol.com/cep-telefonu-x-c103498?pi=2&sst=PRICE_BY_ASC",
        "https://www.trendyol.com/magaza/apple-m-968",
        "https://www.trendyol.com/sr?mid=968",
        "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
    ],
    "productInputs": [
        "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "TR"
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/trendyol-scraper").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 = {
    "mode": "search",
    "queries": ["iphone"],
    "urls": [
        "https://www.trendyol.com/sr?q=iphone+15&pi=1",
        "https://www.trendyol.com/sr?q=iphone+15&pi=2&siralama=PRICE_BY_ASC",
        "https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu",
        "https://www.trendyol.com/flas-indirimler",
        "https://www.trendyol.com/cep-telefonu-x-c103498?pi=1",
        "https://www.trendyol.com/cep-telefonu-x-c103498?pi=2&sst=PRICE_BY_ASC",
        "https://www.trendyol.com/magaza/apple-m-968",
        "https://www.trendyol.com/sr?mid=968",
        "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114",
    ],
    "productInputs": ["https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "TR",
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/trendyol-scraper").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 '{
  "mode": "search",
  "queries": [
    "iphone"
  ],
  "urls": [
    "https://www.trendyol.com/sr?q=iphone+15&pi=1",
    "https://www.trendyol.com/sr?q=iphone+15&pi=2&siralama=PRICE_BY_ASC",
    "https://www.trendyol.com/sr?tag=kirmizi_kampanya_urunu",
    "https://www.trendyol.com/flas-indirimler",
    "https://www.trendyol.com/cep-telefonu-x-c103498?pi=1",
    "https://www.trendyol.com/cep-telefonu-x-c103498?pi=2&sst=PRICE_BY_ASC",
    "https://www.trendyol.com/magaza/apple-m-968",
    "https://www.trendyol.com/sr?mid=968",
    "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
  ],
  "productInputs": [
    "https://www.trendyol.com/apple/yenilenmis-iphone-11-64-gb-beyaz-cep-telefonu-12-ay-garantili-a-kalite-p-356251114"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "TR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/trendyol-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/trendyol-scraper"
        }
    }
}
```

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/bb6frdxuU9nnnDCat/builds/hfT1tLPaNtJGSwO2U/openapi.json
