# Coupang Scraper - Products, Prices & 20+ Fields (`abotapi/coupang-scraper`) Actor

Scrape Coupang.com products by keyword, category or URL. Extract 20+ fields including title, brand, price, discount, ratings, reviews, availability, delivery, images, full descriptions, product URLs and image galleries.

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

## Pricing

from $1.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Coupang Scraper: Product Listings, Prices & Reviews

Coupang Scraper turns Coupang, South Korea's largest online marketplace, into structured product data. Search by keyword or category, walk pasted search, category or product URLs, or pull customer reviews for a list of product IDs. Every listing returns 30+ fields covering price, discount, rating, delivery badges and stock signals, with an optional detail-page fetch for brand, full description, image gallery and a spec table. Export to JSON, CSV or Excel, or pull results straight into your app through the API.

### Why This Scraper?

- **Three ways to get data.** Search by keyword or category, walk pasted search, category or product URLs, or pull customer reviews for a list of product IDs.
- **30+ fields per listing**, from price and discount to delivery badges, stock signals and a full spec table when detail fetch is on.
- **Filters apply everywhere.** Price range, Rocket Delivery and minimum rating narrow both a live search and a pasted category or search URL walk.
- **Two-speed detail fetch.** Leave it off for a fast, cheap core pull, or turn it on for brand, description, gallery and specs at roughly 5x the cost per item.
- **Localized to Korea.** Prices in KRW and delivery promises match exactly what Korean shoppers see.
- **Built for schedules.** Incremental mode returns only new, updated and reappeared listings on recurring runs, and stock-level signals never falsely trigger an "updated" flag.

### Use Cases

- **Price monitoring and repricing:** track price, discount and stock across a category or saved search over time.
- **Marketplace research:** compare Rocket Delivery coverage, ratings and seller counts across competing listings.
- **Voice-of-customer analysis:** pull reviews filtered by star rating to study complaints or praise for a product.
- **Catalog and content teams:** enrich a product feed with images, specs and descriptions via detail-page fetch.
- **Deal tracking:** monitor `isOnSpecial` and `savingsAmount` across a watched search or category.

### Data You Get

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

| Field | Example |
| --- | --- |
| `productId` / `vendorItemId` / `itemId` | the three identifiers Coupang assigns to a single listing |
| `title` | `"Sample Product Title"` |
| `brand` | `"Sample Brand"` (only when `fetchDetails = true`) |
| `url` | `"https://www.coupang.com/vp/products/0000000001?itemId=0&vendorItemId=0"` |
| `image` / `images` | one thumbnail URL, plus the full gallery array (gallery only when `fetchDetails = true`) |
| `price` / `originalPrice` / `currency` | `3490` / `5500` / `"KRW"` |
| `discountPercent` / `isOnSpecial` / `savingsAmount` | `36` / `true` / `2010` |
| `unitPrice` | `"(1개당 1,745원)"`, Coupang's own per-unit price string |
| `rating` / `reviewCount` | `4.7` / `120` |
| `rocketDelivery` / `rocketFresh` / `rocketGlobal` | `true` / `false` / `false` (`rocketGlobal` is the overseas direct-purchase badge) |
| `tomorrowDelivery` | `true` |
| `freeShipping` / `shippingCost` | `true` / `0` (only when `fetchDetails = true`) |
| `deliveryInfo` | `"내일(목) 도착 보장"`, Coupang's own delivery-promise text |
| `availability` | `"InStock"` (only when `fetchDetails = true`) |
| `rank` / `pageNumber` | `7` / `1`, the listing's 1-based position in the run's search or category walk, and the results page it came from |
| `isSponsored` | `false` |
| `isRocketMerchant` / `isOverseas` / `isSoldOut` | `false` / `false` / `false`: seller-fulfilled rocket badge, overseas direct-purchase listing, and Coupang's own sold-out flag for the card |
| `cashback` / `badges` | `17950` / `["ROCKET", "TOMORROW"]`: the card's "up to N won back" cash reward in KRW (`null` when the card shows none), and every delivery or benefit badge id on the card, in card order |
| `usedMinPrice` / `usedListingCount` | lowest price and count of used-condition listings for the same product, when Coupang shows one |
| `categoryId` / `categoryPath` | `"178155"` / `"가전디지털 > 컴퓨터 > 노트북"` |
| `description` | full seller description text (only when `fetchDetails = true`) |
| `specs` | key-value spec table, about 11 entries (only when `fetchDetails = true`) |
| `buyableQuantity` / `almostSoldOut` / `otherSellerCount` | stock-level signals read from the product page (only when `fetchDetails = true`) |
| `query` / `source` | `"노트북"` / `"search"`: the search term that produced this row (search mode, or a pasted search URL), and which kind of start produced it (`search`, `category` or `product`) |
| `scrapedAt` | `"2026-01-01T00:00:00.000Z"` |

Output tabs: **Listings**, **Product details**, **Reviews** and **Changes** (incremental runs). Incremental mode (below) adds `changeType`, `changedFields`, `firstSeenAt` and `lastSeenAt` to every row. Reviews mode returns a different record type: 29 fields per review, including title, content, rating, date, helpful counts, photos, videos, vendor name, the variant purchased, and Coupang's own structured survey answers.

### How to Use

1. Pick a **mode**: `search` (query and filters), `url` (walk pasted search, category or product URLs) or `reviews` (customer reviews by product ID).
2. Fill in the fields for that mode, and set price, rating or Rocket Delivery filters if you want them.
3. Set **Max listings** or **Max pages** to control run size and cost, then click **Start**.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Search by Korean keyword:**

```json
{
  "mode": "search",
  "queries": ["노트북"],
  "maxPages": 3,
  "maxListings": 60
}
```

**Search by English keyword with filters and detail fetch:**

```json
{
  "mode": "search",
  "queries": ["wireless mouse"],
  "minPrice": 10000,
  "maxPrice": 50000,
  "rocketOnly": true,
  "minRating": 4,
  "sortBy": "salePriceAsc",
  "maxPages": 5,
  "maxListings": 100,
  "fetchDetails": true
}
```

**Walk a category URL, with the same filters:**

```json
{
  "mode": "url",
  "urls": ["https://www.coupang.com/np/categories/178255", "https://www.coupang.com/np/categories/178255?page=2"],
  "minPrice": 10000,
  "rocketOnly": true,
  "minRating": 4,
  "maxPages": 2,
  "maxListings": 120
}
```

**Reviews for one or more products:**

```json
{
  "mode": "reviews",
  "productIds": ["8499380264"],
  "maxReviewsPerProduct": 50,
  "reviewSortBy": "DATE_DESC"
}
```

To scrape one specific product page directly, paste its `/vp/products/` URL in `urls` under url mode and turn on `fetchDetails`.

**Supported URL shapes (url mode):**

| Shape | Example | Returns |
|---|---|---|
| Search | `https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81` | Listings, paginated from the page in the URL |
| Category | `https://www.coupang.com/np/categories/178255` | Listings, paginated from the page in the URL |
| Product detail | `https://www.coupang.com/vp/products/8499380264` | That one product |
| Bare product ID | `8499380264` | Same as the product URL |
| Mobile link | `https://m.coupang.com/vp/products/8499380264` | Treated as the www link |

Any other URL is skipped with a warning in the run log. **Default behaviour:** if you run url mode without touching the `urls` field, the actor now scrapes one example of each of the search, category and product shapes instead of failing with an empty input.

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/coupang-scraper").call(run_input={"mode": "search", "queries": ["노트북"], "maxListings": 60})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"])
```

JavaScript:

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

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

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

#### Specials, was-price & discount

Every listing carries `price` (what you pay), `originalPrice` (the strike-through was-price, when Coupang shows one), `discountPercent`, `isOnSpecial` and `savingsAmount` (`originalPrice` minus `price`). These come straight off the search or category card and, when `fetchDetails = true`, are only ever upgraded by the product detail page, never overwritten: a detail page may lower `price` further (a genuinely cheaper price on the product page) but can never raise it above the card's sale price or null out a real card-derived discount. A non-discounted item always reports `originalPrice: null`, `isOnSpecial: false` and `savingsAmount: null`, never fabricated.

There is no dedicated "specials category" input. Coupang's own daily-deals hub renders as a client-side banner and ad widget system rather than a product grid, so it carries no product links or price data to parse, and the page is not reliably reachable on repeat navigation. Rather than point an input at markup that cannot be parsed, this actor surfaces the was-price and discount fields on every listing returned by search, category browse or URL mode, including a keyword search for a term like "특가" or "골드박스," which is the reliable way to reach discounted items today.

#### Resume and incremental updates

Two different tools for two different jobs: pick the one that matches what you are actually doing.

**Resume** (`resumeFromRunId`) continues one specific interrupted run. Paste a previous run ID or dataset ID and the run skips products, or reviews in Reviews mode, already collected there, appending only new ones. Use it after a timeout or crash, or to keep extending one large walk-all pull across several runs without re-scraping, and re-billing, what you already have.

**Incremental mode** (`incrementalMode`) is for scheduling this actor daily or weekly against the same search, category or URL list and getting only what changed. The actor remembers its own state, keyed by mode plus queries, category, URLs and filters, or your own `stateKey`, so there is no run ID to paste. The first run returns everything as `NEW`; later runs return only `NEW`, `UPDATED` and `REAPPEARED` by default. Search and URL mode only: Reviews mode has no persistent per-review baseline.

Every row gets a `changeType`: `NEW` (first time seen), `UPDATED` (content changed, check `changedFields` for exactly which keys), `UNCHANGED` (identical to last run, only returned when `emitUnchanged` is on), `REAPPEARED` (was gone, now back), or `EXPIRED` (tracked previously, not found this run, only returned when `emitExpired` is on, and only after a run that scanned the full tracked search with no cap hit and no resume). A product is `UPDATED` when any returned field other than the volatile ones changes (price, original price, discount, title, brand, images, category, delivery badges and so on). These are never compared, so they cannot trigger an update: `scrapedAt`, `rank`, `pageNumber`, `rating`, `reviewCount`, used-listing price and count, `deliveryInfo`, `buyableQuantity`, `almostSoldOut`, `otherSellerCount`, `cashback`, `isSoldOut` and `badges` (each badge also has its own compared flag, such as `rocketDelivery` or `isRocketMerchant`). Add your own with `ignoreFieldsForChanges`. `EXPIRED` is never produced for a partial scope: a capped run, a pasted URL starting at `?page=2` or later, or a filtered run on a shared `stateKey`. `emitUnchanged` and `emitExpired` are both off by default because they return, and bill, extra rows; turn them on only when you specifically need that signal. `firstSeenAt` and `lastSeenAt` track when a product was first and most recently observed.

`buyableQuantity`, `almostSoldOut` and `otherSellerCount` are treated as volatile stock-level signals and are excluded from the change-detection fingerprint, so a row never classifies as `UPDATED` purely because one of these three fields changed. If you are monitoring for a restock or low-stock alert, read the field itself on every run rather than relying on `changeType`. The same applies to `isSoldOut` and `cashback` on listing rows.

Products already tracked before `source`, `isOverseas` and `isRocketMerchant` existed, and before `image` stopped returning Coupang's blank placeholder picture and `rocketGlobal` started reading the current overseas badge, are not reported as `UPDATED` for those changes alone. Their stored copy is corrected on the next run, so with `emitUnchanged` off you see the new values on such a product once it changes for another reason. Any other change on the same run is still reported.

Both features can combine: `incrementalMode` plus `resumeFromRunId` bootstraps a fresh incremental baseline from a prior resume-style pull's dataset, so nothing looks `NEW` again tomorrow, but only on a genuinely first run for that state key. If incremental state already exists, the run stops rather than silently mixing two different baselines.

When `fetchDetails` is on, a suppressed `UNCHANGED` product may still have had its detail page fetched, needed to compute the fingerprint, but it is never pushed and never billed the detail-enrichment surcharge; only products that actually reach the dataset are charged for enrichment.

### 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` for query and filters, `url` for direct URL walking, `reviews` for customer reviews by product ID. If you leave the mode at `search`, keep the sample query, and send only your own `urls` (or only your own `productIds`), the run switches to `url` (or `reviews`) mode so your list is used and the sample is never scraped. Set `mode` explicitly to override. |
| `queries` | array | `["노트북"]` | (Search mode) One or more Korean or English search terms. |
| `categoryId` | integer | (none) | (Search mode) Optional category id to narrow the search. In URL mode the category comes from the pasted URL itself. |
| `sortBy` | string | `scoreDesc` | (Search mode) One of `scoreDesc`, `salePriceAsc`, `salePriceDesc`, `latest`, `saleCountDesc`. A pasted URL keeps its own sort order. |
| `urls` | array | one example search, category and product URL | (URL mode) One or more search, category or product URLs. The four filters below still apply to listings walked from a search or category URL; only a pasted product URL is returned unfiltered. |
| `productIds` | array | sample product ID | (Reviews mode) One or more product IDs or product URLs. |
| `maxReviewsPerProduct` | integer | `50` | (Reviews mode) Reviews per product to fetch via the paginated review API (1 to 1000). |
| `reviewSortBy` | string | `ORDER_SCORE_ASC` | (Reviews mode) `ORDER_SCORE_ASC` (Best) or `DATE_DESC` (Newest). |
| `reviewRatingFilter` | integer | (none) | (Reviews mode) Only return reviews with this exact star rating, 1 to 5. |
| `minPrice` | integer | (none) | (Search and URL modes) Minimum item price in KRW. |
| `maxPrice` | integer | (none) | (Search and URL modes) Maximum item price in KRW. |
| `rocketOnly` | boolean | `false` | (Search and URL modes) Keep only items eligible for Rocket Delivery. |
| `minRating` | integer | (none) | (Search and URL modes) Minimum average rating, 1 to 5. |
| `maxPages` | integer | `0` | Pages to walk per query or URL; each page returns up to 60 items. `0` means no page limit: the walk stops at `maxListings`, when the results end, or after 30 pages per query or URL. |
| `maxListings` | integer | `20` | Stop after this many items in total, split evenly across the queries or URLs (1 to 100,000). `0`, as sent by older saved tasks, and values above 100,000 are read as 100,000. |
| `fetchDetails` | boolean | `false` | Visit each product page for brand, full description, image gallery, shipping, availability, specs and stock signals, at roughly 5x the cost of a lean run. |
| `proxy` | object | Apify Residential, KR | Proxy configuration. Korean or Japanese residential is strongly recommended. |
| `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. |
| `resumeFromRunId` | string | (none) | Continue one specific interrupted run. See "Resume and incremental updates" above. |
| `incrementalMode` | boolean | `false` | Return only new, updated and reappeared records on recurring search or URL-mode runs. |
| `stateKey` | string | (auto) | Name a monitoring campaign, or leave empty to derive one automatically from mode plus search, category, URL and filter settings. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) records unchanged since the last run. |
| `emitExpired` | boolean | `false` | Also return (and bill) records no longer found, after a complete, uncapped, non-resumed scan that started at page 1. |
| `ignoreFieldsForChanges` | string list | (empty) | Incremental mode only. Field names that never count as a change (plain name matches at any depth, `a.b` for one nested key). They stay in the output. |

### Output Example

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

```json
{
  "productId": "0000000001",
  "vendorItemId": "0000000000",
  "itemId": "0000000000",
  "title": "Sample Product Title",
  "brand": "Sample Brand",
  "url": "https://www.coupang.com/vp/products/0000000001?itemId=0&vendorItemId=0",
  "image": "https://thumbnail.coupangcdn.com/thumbnails/remote/230x230ex/sample.jpg",
  "images": [
    "https://thumbnail.coupangcdn.com/thumbnails/remote/492x492ex/sample-1.jpg",
    "https://thumbnail.coupangcdn.com/thumbnails/remote/492x492ex/sample-2.jpg"
  ],
  "price": 3490,
  "originalPrice": 5500,
  "discountPercent": 36,
  "isOnSpecial": true,
  "savingsAmount": 2010,
  "unitPrice": "(1개당 1,745원)",
  "currency": "KRW",
  "rating": 4.7,
  "reviewCount": 120,
  "rocketDelivery": true,
  "rocketFresh": false,
  "rocketGlobal": false,
  "tomorrowDelivery": true,
  "freeShipping": true,
  "shippingCost": 0,
  "availability": "InStock",
  "deliveryInfo": "내일(목) 도착 보장",
  "isSponsored": false,
  "isRocketMerchant": false,
  "isOverseas": false,
  "isSoldOut": false,
  "cashback": 170,
  "badges": ["ROCKET", "TOMORROW"],
  "usedMinPrice": null,
  "usedListingCount": null,
  "categoryId": "178155",
  "categoryPath": "가전디지털 > 컴퓨터 > 노트북",
  "description": "Full seller description text appears here when fetchDetails is true.",
  "query": "노트북",
  "source": "search",
  "rank": 7,
  "pageNumber": 1,
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### Plan Requirement

Coupang serves Korean shoppers and its edge refuses most traffic from outside Korea. In our tests, plain datacenter proxies and a direct connection were refused with an "Access Denied" page, and plain HTTP clients through a Korean residential proxy were refused too, so this actor loads pages in a real browser session. Keep the default **Proxy configuration** (Apify Residential, country KR). Datacenter proxies are not enough on their own.

What the run does when the connection is not available:

- If your Apify plan has no residential proxy access (free plans do not include it), the run logs "The selected connection is unavailable to this run. Apify free plans do not include residential proxies." and continues on a backup connection. Some pages may still be unavailable.
- If no results page could be loaded, the run ends as failed rather than returning an empty dataset, with one of these messages: "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 Coupang pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again." or "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later." If the account is refused any proxy access, the message says a paid plan is required.
- Choosing a non-residential proxy group logs a warning that the upstream edge filter rejects most other exits.

You can also supply your own proxy URLs in the proxy field.

### FAQ

#### How much does it cost?

You pay per listing or review returned. Turning on **Fetch product detail pages** adds the detail-page enrichment charge per item. The **Pricing** tab shows the current rates. Use **Max listings** or **Max pages** to cap the cost of any run. A default run now returns at most 20 items in total, split evenly across your queries or URLs (earlier versions walked one page per query, about 55 items each). Raise **Max listings** (up to 100,000) to get more; pages are walked until that cap, the end of the results, or the 30-page limit per query or URL.

#### Is it legal to scrape Coupang?

This actor collects only publicly available product and review data. You are responsible for how you use it: follow Coupang's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Prices and availability change constantly and are not guaranteed accurate after you read them.

#### Can I get only new or changed listings 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 listings, and unchanged ones are not billed unless you turn on **Emit unchanged**.

#### Why does turning on detail fetch cost so much more?

Each enriched item adds one extra page visit, to fetch brand, description, gallery, specs and stock signals, so a detail-fetch run costs roughly 5x a lean run. Leave it off unless you need those specific fields.

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

In Reviews mode, if Coupang refuses every review request, the run is marked failed with a clear message, so "no reviews" is never confused with "nothing could be read." In search and URL mode, a query, category or URL that cannot be read is skipped with a warning in the run log, and the rest of the run continues. If you get an empty dataset, check the log and run it again in a few minutes.

#### 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/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/ozon-ru-scraper"><b>Ozon.ru Scraper</b></a><br>Extract structured product data from Ozon.ru, Russia’s largest marketplace. Search by...</td></tr>
<tr><td>🛒 <a href="https://apify.com/abotapi/gmarket-global-scraper"><b>Gmarket.co.kr Scraper</b></a><br>Scrape Gmarket.co.kr product listings and customer reviews into clean JSON. Search by...</td><td>🛒 <a href="https://apify.com/abotapi/officeworks-scraper"><b>Officeworks Scraper</b></a><br>Scrape Officeworks products by keyword, category, or URL. Extract names, brands, prices...</td></tr>
<tr><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><td>🛒 <a href="https://apify.com/abotapi/mediamarkt-de-scraper"><b>MediaMarkt Germany Scraper</b></a><br>Scrape MediaMarkt.de products by keyword or URL. Extract current and original prices...</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/coupang-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`):

Pick how to start. 'search' uses query + filters below. 'url' walks one or more category / search URLs. 'reviews' returns customer reviews for a list of product IDs (one record per review, ~10 reviews per product). If mode is left at 'search' with the sample query and only your own URLs or product IDs are sent, the matching mode is used automatically.

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

One or more Korean or English search terms (e.g. '노트북', 'laptop'). Only used when mode = search.

## `categoryId` (type: `integer`):

Optional: narrow the search to a Coupang category id (the number after /np/categories/ in a category URL). Leave empty for all categories. Only used when mode = search; in URL mode the category comes from the pasted URL itself, and in Reviews mode this field is ignored.

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

Sort the search results. Only used when mode = search, where it is sent to coupang.com as the sort parameter; a pasted URL keeps whatever sort order it already carries, and Reviews mode has its own separate sort field below.

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

One or more https://www.coupang.com/np/search?q=, /np/categories/<id>, or /vp/products/<id> URLs (m.coupang.com links and bare numeric product IDs are also accepted). Left untouched, one example of each shape is scraped. Multi-URL supported. Pagination starts at the page in the URL and walks forward. The Filters section below (min price, max price, Rocket Delivery only, minimum rating) DOES apply to the listings walked from a pasted search or category URL; only a pasted /vp/products/ product URL is returned unfiltered, because that URL names one specific product. Search-only fields (search queries, category ID, sort order) are ignored here.

## `productIds` (type: `array`):

One or more Coupang product IDs (the number after /vp/products/ in a product URL) OR full product URLs. Output is one record per review.

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

How many reviews to fetch per product. The actor pages through Coupang's review API to reach this number. Most popular products have 1000+ reviews available. Default 50, at most 1000.

## `reviewSortBy` (type: `string`):

How to order the reviews returned. 'Best' is Coupang's recommended ranking (mixes rating and helpfulness); 'Newest' returns most recent first.

## `reviewRatingFilter` (type: `integer`):

Optional. When set, only return reviews with this exact star rating (1, 2, 3, 4, or 5). Useful for analysing low-rated reviews or pulling only top reviews.

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

Optional: only return items with price >= this value. Leave empty for no lower bound. Applies in BOTH search mode and URL mode. In search mode the value is also sent to coupang.com as a search parameter, so results are narrowed on the site first and then re-checked here; in URL mode the pasted URL is walked exactly as given and the check runs here, on every listing found. Has no effect in Reviews mode, and a pasted /vp/products/ product URL is returned unfiltered.

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

Optional: only return items with price <= this value. Leave empty for no upper bound. Applies in BOTH search mode and URL mode. In search mode the value is also sent to coupang.com as a search parameter, so results are narrowed on the site first and then re-checked here; in URL mode the pasted URL is walked exactly as given and the check runs here, on every listing found. Has no effect in Reviews mode, and a pasted /vp/products/ product URL is returned unfiltered.

## `rocketOnly` (type: `boolean`):

Keep only items eligible for the next-day Rocket Delivery service. Applies in BOTH search mode and URL mode. In search mode the value is also sent to coupang.com as a search parameter, so results are narrowed on the site first and then re-checked here; in URL mode the pasted URL is walked exactly as given and the check runs here, on every listing found. Has no effect in Reviews mode, and a pasted /vp/products/ product URL is returned unfiltered.

## `minRating` (type: `integer`):

Optional: only keep items whose average rating is >= this value (1 to 5). Applies in BOTH search mode and URL mode. Unlike the price and Rocket Delivery filters, this one is never sent to coupang.com (its rating parameter triggers stricter blocking), so in both modes the check always runs here, on every listing found. Has no effect in Reviews mode, and a pasted /vp/products/ product URL is returned unfiltered; to filter reviews by star rating use the Reviews mode rating field above.

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

How many pages of results to walk per query or URL. Each page returns up to 60 items. Leave 0 for no page limit: the run then stops at Max listings, when the results end, or after 30 pages per query / URL.

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

Stop after this many items in total across all queries / URLs (split evenly between them). Default 20. Maximum 100000. A value of 0, as sent by older saved tasks, and values above 100000 are read as 100000.

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

Off (default, recommended): each item gets 15 fields (productId, vendorItemId, itemId, title, price, originalPrice, discountPercent, currency, rating, reviewCount, image, url, isSponsored, rocketDelivery, tomorrowDelivery). Fast and cheap. On: also visits each product page to add brand, full image gallery, description, shipping details, availability, category path, and a spec key-value map (~11 entries). Each detail page adds one navigation, so total cost is roughly 5x the lean run.

## `proxy` (type: `object`):

Pick the proxy. Korean or Japanese residential is strongly recommended; the upstream edge filter rejects most other exits.

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

Paste a previous run ID or dataset ID to continue a large pull without returning or charging for products already collected there. Use this after an interrupted run, or to keep extending one walk-all pull across separate runs. For recurring daily monitoring of the same search, use Incremental mode below instead.

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

Turn this on for daily or recurring monitoring of Search or URL mode. The first run returns all matching products as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED products. Turn on "Emit unchanged" or "Emit expired" only when you also want those products returned (and billed). State is kept separately per mode + queries/category/URLs/filters configuration; use State key when you want to name or deliberately share a monitoring campaign. A product is UPDATED when any returned field other than the volatile ones changes (price, original price, discount, title, brand, images, category, seller, stock status and so on; changedFields lists them). Never compared: scrapedAt, rating, reviewCount, used-listing price and count, deliveryInfo, buyableQuantity, almostSoldOut, otherSellerCount, plus anything in Ignore fields. Has no effect in Reviews mode. 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 mode + search/category/URL/filter settings — 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 the tracked search — not when Max listings 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 should NOT count as a change. A product is only marked UPDATED when a field outside this list changes. Use a plain name (for example images) to ignore that key wherever it appears, or a dotted path (for example a.b) for one nested key. The fields are still returned in the output. Always ignored already: scrapedAt, rating, reviewCount, usedMinPrice, usedListingCount, deliveryInfo, buyableQuantity, almostSoldOut, otherSellerCount.

## `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": [
    "노트북"
  ],
  "sortBy": "scoreDesc",
  "urls": [
    "https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81",
    "https://www.coupang.com/np/categories/178255",
    "https://www.coupang.com/vp/products/8499380264"
  ],
  "productIds": [
    "8499380264"
  ],
  "maxReviewsPerProduct": 50,
  "reviewSortBy": "ORDER_SCORE_ASC",
  "rocketOnly": false,
  "maxPages": 0,
  "maxListings": 20,
  "fetchDetails": false,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "KR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

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

No description

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

No description

## `changes` (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": [
        "노트북"
    ],
    "urls": [
        "https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81",
        "https://www.coupang.com/np/categories/178255",
        "https://www.coupang.com/vp/products/8499380264"
    ],
    "productIds": [
        "8499380264"
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "KR"
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/coupang-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": ["노트북"],
    "urls": [
        "https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81",
        "https://www.coupang.com/np/categories/178255",
        "https://www.coupang.com/vp/products/8499380264",
    ],
    "productIds": ["8499380264"],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "KR",
    },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/coupang-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": [
    "노트북"
  ],
  "urls": [
    "https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81",
    "https://www.coupang.com/np/categories/178255",
    "https://www.coupang.com/vp/products/8499380264"
  ],
  "productIds": [
    "8499380264"
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "KR"
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/coupang-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/coupang-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/foGTFE4fecZH35VGe/builds/du3Az4WYe2uWAYhx1/openapi.json
