{
  "openapi": "3.0.1",
  "info": {
    "title": "Gap US Scraper - Clothing, Prices, Discounts & Stock",
    "description": "Scrape Gap US (gap.com) clothing and fashion products by category. Extract product names, prices, discounts, ratings, stock availability, colors, color-specific details and full descriptions. Ideal for price monitoring, competitor analysis and retail research.",
    "version": "0.1",
    "x-build-id": "5mY4LUIEs9TfUulEv"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~gap-us-shopping-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-gap-us-shopping-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~gap-us-shopping-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-gap-us-shopping-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~gap-us-shopping-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-gap-us-shopping-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "category",
              "url"
            ],
            "type": "string",
            "description": "Choose 'search' to search by keyword, 'category' to pick category pages by name, or 'url' to scrape pasted links. Each mode reads only its own fields below.",
            "default": "search"
          },
          "brands": {
            "title": "Storefronts",
            "type": "array",
            "description": "Which storefronts to search or browse. Gap is used when none is ticked. Each keyword and category is run in every ticked storefront. Pasted links ignore this setting, except a bare product number, which is read in the first ticked storefront.",
            "items": {
              "type": "string",
              "enum": [
                "gap",
                "oldnavy",
                "bananarepublic",
                "athleta",
                "gapfactory",
                "bananarepublicfactory"
              ],
              "enumTitles": [
                "Gap",
                "Old Navy",
                "Banana Republic",
                "Athleta",
                "Gap Factory",
                "Banana Republic Factory"
              ]
            },
            "default": [
              "gap"
            ]
          },
          "queries": {
            "title": "Search keywords",
            "type": "array",
            "description": "Words to search for, for example 'denim jacket'. One search per keyword and storefront; duplicates are searched once. Up to 50 keywords. Read only in search mode.",
            "items": {
              "type": "string"
            }
          },
          "categoryKeywords": {
            "title": "Category name words",
            "type": "array",
            "description": "Words from the category's address, for example 'women dresses' or 'sweaters'. Several phrases select several categories. Read only in category mode.",
            "items": {
              "type": "string"
            }
          },
          "maxCategories": {
            "title": "Max categories per storefront",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "At most this many matching categories are walked in each ticked storefront (the broadest names are taken first).",
            "default": 5
          },
          "urls": {
            "title": "Links",
            "type": "array",
            "description": "Storefront links to scrape directly. A category link may carry the filters the site writes after the # sign; they win over the price, sale and rating settings below. A product link always reads the product page. Read only in url mode.",
            "default": [
              "https://www.gap.com/browse/product.do?pid=1184537",
              "https://oldnavy.gap.com/browse/women/shop-all-womens?cid=1185233",
              "https://oldnavy.gap.com/browse/women/shop-all-womens?cid=1185233#department=136&priceType=P&sortByField=price&sortByDir=asc",
              "https://athleta.gap.com/browse/search.do?searchText=leggings",
              "https://bananarepublic.gap.com/native-category-sitemap.xml"
            ],
            "items": {
              "type": "string"
            }
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "priceAsc",
              "priceDesc",
              "ratingDesc"
            ],
            "type": "string",
            "description": "Order of the results in category and keyword scopes. A sort order written into a pasted category link wins. 'Relevance' keeps the store's own order.",
            "default": "relevance"
          },
          "minPrice": {
            "title": "Min price (USD)",
            "minimum": 0,
            "type": "number",
            "description": "Only products with a colour priced at or above this amount. Leave empty for no lower limit."
          },
          "maxPrice": {
            "title": "Max price (USD)",
            "minimum": 0,
            "type": "number",
            "description": "Only products with a colour priced at or below this amount. Leave empty for no upper limit."
          },
          "onSaleOnly": {
            "title": "On sale or clearance only",
            "type": "boolean",
            "description": "Only products with at least one colour marked down (sale or clearance price).",
            "default": false
          },
          "minRating": {
            "title": "Min rating",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Only products rated at or above this average (0 to 5). Products without reviews are excluded."
          },
          "fetchDetails": {
            "title": "Read each product's page",
            "type": "boolean",
            "description": "Search and category scopes only: read every product's own page for the full description, fit and fabric text, size and barcode table, breadcrumbs and rating breakdown. Off by default because it costs one extra page per product. Pasted product links always read the product page (there is no result card behind them), so those rows are always billed one 'Product page detail' event whatever this toggle says.",
            "default": false
          },
          "fetchReviews": {
            "title": "Collect customer reviews",
            "type": "boolean",
            "description": "Add customer reviews to every product row (this also reads the product page, so the detail surcharge applies). Billed per review returned.",
            "default": false
          },
          "maxReviewsPerProduct": {
            "title": "Max reviews per product",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Reviews to collect per product when 'Collect customer reviews' is on. Up to 1000.",
            "default": 20
          },
          "reviewSort": {
            "title": "Review order",
            "enum": [
              "newest",
              "oldest",
              "helpful",
              "highest",
              "lowest"
            ],
            "type": "string",
            "description": "Which reviews come first when a product has more than the maximum.",
            "default": "newest"
          },
          "includeReviewPhotos": {
            "title": "Include review photo links",
            "type": "boolean",
            "description": "Add the links of photos customers attached to their reviews.",
            "default": false
          },
          "maxItems": {
            "title": "Max products",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum number of products to return across the whole run, EXPIRED rows from Incremental mode included. This is the run's cap. Use 0 for the maximum of 100000 products per run.",
            "default": 20
          },
          "maxPages": {
            "title": "Max result pages per keyword or category",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum number of result pages to take per keyword or category. Each page carries up to 200 colour listings (roughly 100 to 180 products). 0 = no page limit set; the run then stops at Max products, when there are no more results, or at a safety limit of 2000 pages per keyword or category (far above what Max products can reach). Product links have no result pages.",
            "default": 0
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Connection used for every request. Leave the default (US residential); the run escalates on its own when the store refuses a page. Apify free plans do not include residential proxies.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ],
              "apifyProxyCountry": "US"
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "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. For recurring monitoring of the same scope, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns every matching product as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED products, which makes it a cheap way to watch price drops. What is compared: price range, was-price, discount, on-sale flag, price type, name, brand, description, fit and fabric text, every colour with its own price and the size table. What is excluded by default (still returned in the row, never a change): scrape timestamps, the product's rank and page, where it was found (link, keyword, category), ratings and reviews (average rating, review count, rating breakdown, fit summary and the review sample), the rotating promo and 'new' flags, and image links. Stock and availability (in-stock flag, units, per-colour and per-size stock) are also excluded unless you turn on 'Count stock changes', because they move with every order. Colour and size lists are compared regardless of the order the store returns them. 'Changes to watch' narrows this to price (and stock when counted) only. Turn on 'Emit unchanged' or 'Emit expired' only when you also want those rows returned (and billed). State is kept separately for each scope and filter setup; use State key to name or deliberately share a monitoring campaign. To continue one specific interrupted run instead, use Resume from a previous run above.",
            "default": false
          },
          "stateKey": {
            "title": "State key (incremental mode only)",
            "type": "string",
            "description": "Optional. Name this monitoring campaign to keep its state stable, or to deliberately share state across differently configured runs. Leave empty to derive a key automatically from the scope and filter settings, so two different scopes never mix state."
          },
          "emitUnchanged": {
            "title": "Emit unchanged products (incremental mode only)",
            "type": "boolean",
            "description": "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 want a full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired products (incremental mode only)",
            "type": "boolean",
            "description": "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 scope without a page that could not be read, never when Max products capped it or Resume was used. A product page the store reports as not available also counts as missing; consider 'Expire after missed scans' above 1 so a brief gap does not expire a product. EXPIRED rows count against Max products: a run returns at most the room left under it, and the rest are returned on a later complete run. This returns, and bills, extra rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "changeScope": {
            "title": "Changes to watch (incremental mode only)",
            "enum": [
              "all",
              "priceAndStock"
            ],
            "type": "string",
            "description": "All fields (default): any change to the compared product data marks a product UPDATED. Price only (and stock when counted): just price, was-price, discount, on-sale flag and per-colour price, so name, description or fit-text edits never produce a billable UPDATED row. Changing this never starts a new baseline: the existing saved state is kept (under an automatic or a named State key) and each stored product is simply compared under the new setting.",
            "default": "all"
          },
          "watchStock": {
            "title": "Count stock changes (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Stock figures move with every order, so counting them marks products UPDATED, and bills them, without a price or content change. Turn on to count the in-stock flag, unit totals and per-colour and per-size stock as changes.",
            "default": false
          },
          "compactUpdates": {
            "title": "Compact UPDATED rows (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. When on, UPDATED and EXPIRED rows are slim: ids, link, name, current price and stock, plus priceChanges (old and new value of each field that moved) and variantChanges (per-colour ADDED, REMOVED or CHANGED). NEW rows stay full. A compact row does not carry product-page detail fields or reviews, so no detail or review charge applies to it.",
            "default": false
          },
          "expireAfterMissedScans": {
            "title": "Expire after missed scans (incremental mode only)",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Used with 'Emit expired'. A product is marked EXPIRED only after it was missing from this many CONSECUTIVE complete scans (default 1). Products rotate in and out of a category as the store restocks, so a value of 2 or more avoids false expiries.",
            "default": 1
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Field names that must not count as a change, for example name or highlights. Use a dotted path to ignore a key inside every element of a list, for example colors.price. Ignored fields are still returned in the row. Rank, where the product was found, ratings and reviews, promo flags and image links are already ignored by default. Changing this list never starts a new baseline: the saved state is kept and each stored product is re-compared under the new list, so no product comes back as NEW.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per product; other connectors get a best-effort write or digest. Each connector receives a condensed summary per product, not the full record; the complete record always stays in the dataset. Leave empty to skip; this never changes the dataset output. 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 product 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 products written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}