{
  "openapi": "3.0.1",
  "info": {
    "title": "Gmarket.co.kr Scraper - Products, Prices & Customer Reviews",
    "description": "Scrape Gmarket.co.kr product listings and customer reviews into clean JSON. Search by keyword, paste product URLs, or use review-only mode with a product ID. Fast, simple, and built for structured ecommerce data collection.",
    "version": "1.0",
    "x-build-id": "uNszFVryc9Pqk7oev"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~gmarket-global-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-gmarket-global-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/abotapi~gmarket-global-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-gmarket-global-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/abotapi~gmarket-global-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-gmarket-global-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "title": "🎯 Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Pick how you want to drive the scrape. 'Keyword search' uses your keywords + filters; 'Paste URLs' uses Gmarket Global search-result URLs you already have.",
            "default": "search"
          },
          "keywords": {
            "title": "🔎 Keywords",
            "type": "array",
            "description": "One or more product keywords to search for (English or Korean both work). One run = one search per keyword × applied filters. Only used when mode is 'Keyword search'.",
            "default": [
              "laptop"
            ],
            "items": {
              "type": "string"
            }
          },
          "minPrice": {
            "title": "Minimum price (KRW)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum sale price in Korean Won. Leave 0 for no minimum. Example: 10000 (≈ $7 USD).",
            "default": 0
          },
          "maxPrice": {
            "title": "Maximum price (KRW)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum sale price in Korean Won. Leave 0 for no maximum. Example: 100000 (≈ $70 USD).",
            "default": 0
          },
          "overseaDeliveryOnly": {
            "title": "Oversea delivery only",
            "type": "boolean",
            "description": "When on, returns only items that ship outside Korea. Verified to narrow results by ~75% on broad queries.",
            "default": false
          },
          "bigSmileOnly": {
            "title": "BigSmile promotion only",
            "type": "boolean",
            "description": "When on, returns only items participating in the BigSmile sitewide promotion.",
            "default": false
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "GLOBAL_RANKPOINT",
              "GLOBAL_SELL_QTY",
              "GLOBAL_LOW_PRICE",
              "GLOBAL_HIGH_PRICE",
              "GLOBAL_RECENT"
            ],
            "type": "string",
            "description": "Result order for keyword and pasted-URL searches. The storefront has no best-selling order: Relevance and Gmarket ranking both use its ranking order. A sortType in a pasted URL wins over this field.",
            "default": "GLOBAL_RANKPOINT"
          },
          "urls": {
            "title": "🔗 URLs",
            "type": "array",
            "description": "Gmarket Global URLs, one per line. Supported: search results (/Search/Search?keyword=, with pageNo, minPrice, maxPrice, overseaTransYn, isBigSmile), category listings (/Category/List?lcId=), the category hub (/AllCategory, expanded to its top-level categories), product pages (/Item?goodscode=) and review pages (/Review/Review?GoodsCode=, routed to that product). item./www./m./global. hosts are read through the Global storefront; pages with no products (the homepage) are skipped with a warning. sellCustNo is not applied by the site. Leaving this empty in URL mode runs the example URLs below.",
            "default": [
              "https://mg.gmarket.co.kr/Search/Search?keyword=laptop",
              "https://mg.gmarket.co.kr/Search/Search?keyword=laptop&pageNo=2",
              "https://mg.gmarket.co.kr/Search/Search?keyword=laptop&minPrice=100000&maxPrice=500000&overseaTransYn=Y&isBigSmile=true",
              "https://mg.gmarket.co.kr/Category/List?lcId=100000028",
              "https://mg.gmarket.co.kr/AllCategory",
              "https://mg.gmarket.co.kr/Item?goodscode=4196091684",
              "https://mg.gmarket.co.kr/Item?goodsCode=1284344651"
            ],
            "items": {
              "type": "string"
            }
          },
          "reviewsOnly": {
            "title": "💬 Reviews only",
            "type": "boolean",
            "description": "When on, the actor still uses your keyword search or pasted URLs to discover products, but pushes one record per REVIEW instead of one record per product. Pair with maxReviewsPerProduct to cap how deep to walk each product.",
            "default": false
          },
          "maxReviewsPerProduct": {
            "title": "Max reviews per product",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "Only applies when 'Reviews only' is on. Stop after this many reviews per product. The API serves 20 per page; the default of 20 is one page each. Set 0 to walk every review the product has. Reviews come back in Gmarket's default order (typically featured first; the storefront does not expose a sort control).",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "How many pages to walk per keyword (or per URL). The API serves 60 items per page, so 1 page returns up to 60 products. 0 = unlimited (walk all pages until the site runs out of results).",
            "default": 0
          },
          "maxListings": {
            "title": "Max total records",
            "minimum": 0,
            "type": "integer",
            "description": "Stop the whole run once this many unique records have been collected. When 'Reviews only' is off this counts products; when on it counts reviews across all products. Default 20 keeps a run small; set 0 to walk the entire catalogue (unlimited).",
            "default": 20
          },
          "fetchDetails": {
            "title": "Fetch detail pages (richer; default)",
            "type": "boolean",
            "description": "When on, makes one extra fetch per item to capture description text, brand, and full seller info (company name, manager, customer-service phone, business number, e-commerce sales registration). Turn off for a faster, leaner scrape with only the search-listing fields.",
            "default": true
          },
          "proxy": {
            "title": "Proxy",
            "type": "object",
            "description": "Uses your Apify Proxy (the default automatic pool is enough; residential is rarely needed). An Apify plan with proxy access is required; the actor never connects without a proxy while this is on."
          },
          "resumeFromRunId": {
            "title": "Resume from a prior run",
            "type": "string",
            "description": "Optional. Paste a previous run ID or dataset ID to continue a large walk-all pull: products/reviews already saved by that run are loaded before scraping starts and skipped, so this run only appends new records. Leave empty for a normal fresh run. Combine with 'Incremental mode' only to bootstrap a brand-new recurring monitor from a completed walk-all pull — if this search already has saved incremental state, the run fails fast instead of silently starting a second, overlapping baseline."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "When on, the actor remembers the products (or reviews, if 'Reviews only' is on) from the last run of this SAME search and only pushes what's NEW, UPDATED, or REAPPEARED since then — a different workflow from 'Resume from a prior run' above, which continues one specific interrupted run instead of remembering a search across scheduled runs. Every pushed record gets a `changeType` field. Compared: every product field (title, prices, discount, delivery, category, seller and detail fields, images, raw card data) or, for reviews, every review field (rating, text, translation, seller reply, photos). Excluded from comparison but still in the output: `scrapedAt`, the per-request `sellerInfo.EncodedCustNo` token, the review view counter (`readCount` / `raw.ReadCount`), and anything you list in 'Ignore fields when detecting changes'. A new review never makes its product UPDATED. Off by default so a plain run behaves exactly as before.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Only used when 'Incremental mode' is on. Leave empty to auto-derive the tracked search from your mode/keywords/URLs/price range/'Reviews only'/'Fetch detail pages' settings (raising maxListings or maxPages does not start a new baseline). Set your own text here to track multiple schedules explicitly, or to keep the baseline stable even if you plan to change a filter later."
          },
          "emitUnchanged": {
            "title": "Emit unchanged records too",
            "type": "boolean",
            "description": "Only used when 'Incremental mode' is on. Off by default: a record that hasn't changed since the last run is neither pushed nor billed. Turn this on to also push (and pay for) every UNCHANGED record every run — useful if you want a complete snapshot each time instead of only the delta.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit records that disappeared",
            "type": "boolean",
            "description": "Only used when 'Incremental mode' is on. Off by default. Turn this on to push (and pay for) an EXPIRED row for any previously-tracked product/review that no longer appears — only fires after a run that completed a full scan of the tracked search (a capped, resumed, or partial run never marks anything expired, since it can't tell 'gone' apart from 'not reached yet').",
            "default": false
          },
          "expireAfterMissedScans": {
            "title": "Grace scans before EXPIRED (incremental mode only)",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Only used when 'Incremental mode' and 'Emit records that disappeared' are on. A record is marked EXPIRED only after it was missing from this many CONSECUTIVE complete scans (counter resets when it is seen again). Default 1 = the next complete scan. EXPIRED means the listing stopped appearing in the search; without a detail probe that cannot tell a search-ranking drop from a delisting.",
            "default": 1
          },
          "changeScope": {
            "title": "What counts as a change (incremental mode only)",
            "enum": [
              "all",
              "priceAndStock"
            ],
            "type": "string",
            "description": "Only used when 'Incremental mode' is on. 'all' (default) compares every field. 'priceAndStock' compares ONLY price fields (sell/original/sale price, was/current price, savings, discount, on-special flag): description, image, delivery and badge changes never create a billable UPDATED row. The search card has no separate stock field; a product that leaves the search appears as EXPIRED when enabled.",
            "default": "all"
          },
          "compactUpdates": {
            "title": "Compact UPDATED rows (incremental mode only)",
            "type": "boolean",
            "description": "Only used when 'Incremental mode' is on. UPDATED product rows contain only ids, link, current price and a `priceChanges` object with old/new values; NEW rows stay full. A compact row no longer carries seller or description data, so the detail-enrichment charge is not made for it.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Only used when 'Incremental mode' is on. Field names (dotted paths such as `sellerInfo.CompanyName` or `raw.DiscountRate`) that never count as a change and never appear in `changedFields`. The fields stay in the output. Applies to the next comparison against already-saved state without a one-time wave of UPDATED rows. Built-in exclusions always apply.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "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": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          },
          "query": {
            "title": "Query (alias of keywords)",
            "type": "string",
            "description": "Alias: a single search term, used only when keywords is empty."
          },
          "maxItems": {
            "title": "Max items (alias of maxListings)",
            "minimum": 1,
            "type": "integer",
            "description": "Alias of maxListings."
          },
          "proxyConfiguration": {
            "title": "Proxy configuration (alias of proxy)",
            "type": "object",
            "description": "Alias of proxy, used only when proxy is not set."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}