{
  "openapi": "3.0.1",
  "info": {
    "title": "Switch Scraper - Luxury Handbags, Jewelry & Rental Listings",
    "description": "Scrape Switch designer handbag and jewelry rental listings by keyword, filter or URL. Extract product names, brands, retail values, member purchase prices, Core or Select membership tiers, availability and product images.",
    "version": "0.1",
    "x-build-id": "bf1iUXexf3OHlwi8y"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~joinswitch-rental-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-joinswitch-rental-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~joinswitch-rental-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-joinswitch-rental-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~joinswitch-rental-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-joinswitch-rental-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",
              "url"
            ],
            "type": "string",
            "description": "How to start the scrape. 'search' runs catalog searches with the filters below. 'url' processes the Switch URLs you paste: a piece URL returns that single piece in full, and a catalog or designer URL is paged like a browse, its own path deciding the scope.",
            "default": "search"
          },
          "searchTerms": {
            "title": "Search terms",
            "type": "array",
            "description": "One or more things to search for, for example 'chanel flap bag', 'diamond studs', 'hermes'. Each term is scraped independently. Leave empty to browse the whole catalog. Search mode only.",
            "items": {
              "type": "string"
            }
          },
          "brands": {
            "title": "Brands",
            "type": "array",
            "description": "Restrict the walk to these designers, given as plain names ('Chanel', 'Hermes'), slugs ('chanel') or the store's brand ids. Several brands are allowed and combine with every other filter. Names are matched against the store's own designer list at run start; a name that matches nothing fails the run with the unmatched names listed. Search mode only.",
            "items": {
              "type": "string"
            }
          },
          "categories": {
            "title": "Categories",
            "type": "array",
            "description": "Restrict the walk to these piece categories, by slug or name: handbags, necklaces, earrings, bracelets, rings, belts, brooches, other. Several are allowed. The store cannot combine keyword search with category filters, so when both are set the keyword decides and this filter is ignored for search walks (a clear note is logged). Search mode only.",
            "items": {
              "type": "string"
            }
          },
          "occasions": {
            "title": "Occasions",
            "type": "array",
            "description": "Restrict the walk to pieces tagged for these occasions: everyday, festival, night-out, vacation, wedding. Several are allowed. Search mode only.",
            "items": {
              "type": "string"
            }
          },
          "shop": {
            "title": "Collection (shop)",
            "enum": [
              "",
              "fine",
              "fashion",
              "statement",
              "everyday",
              "vintage"
            ],
            "type": "string",
            "description": "Restrict the walk to one of the store's own collections: fine, fashion, statement, everyday or vintage. Search mode only."
          },
          "tier": {
            "title": "Rental tier",
            "enum": [
              "any",
              "core",
              "select"
            ],
            "type": "string",
            "description": "Restrict the walk to one membership tier. Core pieces carry an average retail value around $1,000; Select pieces around $4,000. 'any' sends no tier filter. Search mode only.",
            "default": "any"
          },
          "availability": {
            "title": "Availability",
            "enum": [
              "any",
              "available"
            ],
            "type": "string",
            "description": "'available' restricts the walk to pieces that are on the shelf right now (not checked out by another member). 'any' returns every catalog piece, checked out or not, with its availability field telling you which is which. Search mode only.",
            "default": "any"
          },
          "sort": {
            "title": "Sort results by",
            "enum": [
              "recommended",
              "newest",
              "price-desc",
              "price-asc"
            ],
            "type": "string",
            "description": "The store's own server-side ordering, sent with every page of every search walk: 'recommended' (most loved, the store default), 'newest', 'price-desc' (highest retail value first) or 'price-asc' (lowest first). A pasted URL decides its own ordering when it carries a sort parameter. Search mode only.",
            "default": "recommended"
          },
          "urls": {
            "title": "Switch URLs",
            "type": "array",
            "description": "Paste Switch URLs; every link shape the site uses is accepted. Piece links look like /product/chanel-matelasse-chain-flap-bag-1731355475. Catalog links look like /collections?search=chanel&page=2 (the page number starts that walk further in), /collections?brand=10&category=10&sort=PRICE_DESC, or designer pages like /collections/designer/chanel and /collections/designer/chanel/handbags. A pasted URL decides its own scope: a piece URL returns that one piece in full, a catalog or designer URL is paged forward from the page in the link. Site pages that are not catalog pages (home, membership, FAQ) are skipped with a note.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minRetailValue": {
            "title": "Minimum retail value (USD)",
            "minimum": 0,
            "type": "number",
            "description": "Only keep pieces whose retail value is at least this amount, in US dollars. Applied to the rows this run reads. Applies in BOTH search mode and URL mode."
          },
          "maxRetailValue": {
            "title": "Maximum retail value (USD)",
            "minimum": 0,
            "type": "number",
            "description": "Only keep pieces whose retail value is at most this amount, in US dollars. Applied to the rows this run reads. Applies in BOTH search mode and URL mode."
          },
          "fetchDetails": {
            "title": "Fetch piece details",
            "type": "boolean",
            "description": "Fetch each piece's own page for the full image gallery and to refresh availability, prices and favorite counts against the live listing. Slower, and charged once per record. Leave off for a fast crawl: every row still carries the card fields (title, brand, category, retail value, member buy price, tier, availability and the lead image).",
            "default": true
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "type": "integer",
            "description": "The single cap on this run: stop after collecting this many records across all search terms and URLs. Set 0 for unlimited.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per source",
            "minimum": 0,
            "type": "integer",
            "description": "Safety bound on how many result pages to walk per search term or URL. Leave empty (0) for no page limit: the run then stops at Max items, not here. Does not impose a separate cap below Max items.",
            "default": 0
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Leave the default for the cheapest run. The catalog is served over ordinary shared connections; Residential is recommended for the most reliable results on large or frequent runs. If a run reports it could not read any pages, try residential before anything else.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for records already collected there. Use this after an interrupted or capped run. For recurring monitoring of the same search, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or weekly recurring monitoring of the same catalog walk, for example a watch on one designer. The first run returns everything matching as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED records. Availability flips, price moves and new pieces ARE reported as UPDATED or NEW: on a rental catalog that is the signal, not noise. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately per search, URL and filter setup; use State key to name or deliberately share a monitoring campaign.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, 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 let the actor derive a key automatically from the search terms, URLs and filters, so two different walks never mix state."
          },
          "emitUnchanged": {
            "title": "Emit unchanged records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return pieces 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 a full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired records (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return pieces that were present in a previous run but are no longer in the catalog, marked EXPIRED. Only produced once a run has fully scanned the tracked walk: not when Max items capped it, not when Resume was used, and not when the run was refused. This returns, and bills, extra synthetic rows, so leave it off unless you need expiry tracking.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Optional. Extra top-level field names to exclude from incremental change detection, on top of the built-in list (favoritesCount, notifyCount, updatedAt, inventoryUpdatedOn, imageUrls). Use when a field moves every run without the piece changing.",
            "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 and Integrations, then select it here. Notion gets a page per record; other connectors get a best-effort write or digest. Each connector receives a condensed summary per record, 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 record 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 records 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}