{
  "openapi": "3.0.1",
  "info": {
    "title": "Vinted Demand & Sell-Through Scraper",
    "description": "Vinted demand intelligence: sell-through rate, realised sale prices, days-to-sell, and cross-market sourcing. No proxy, no PII.",
    "version": "0.0",
    "x-build-id": "awTRYuLh8MgWhI7vG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/unfenced-group~vinted-arbitrage-scanner/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-unfenced-group-vinted-arbitrage-scanner",
        "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/unfenced-group~vinted-arbitrage-scanner/runs": {
      "post": {
        "operationId": "runs-sync-unfenced-group-vinted-arbitrage-scanner",
        "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/unfenced-group~vinted-arbitrage-scanner/run-sync": {
      "post": {
        "operationId": "run-sync-unfenced-group-vinted-arbitrage-scanner",
        "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": {
          "searchQuery": {
            "title": "🔍 Search query",
            "type": "string",
            "description": "Product, brand, or model to scan across markets (e.g. 'nike air force 1', 'ralph lauren jumper')."
          },
          "countries": {
            "title": "🌍 Markets to compare",
            "type": "array",
            "description": "Vinted markets to scan. Pick 2-5 for a focused arbitrage scan. All listings are normalised to one currency for comparison.",
            "items": {
              "type": "string",
              "enum": [
                "fr",
                "de",
                "uk",
                "it",
                "es",
                "nl",
                "pl",
                "pt",
                "be",
                "at",
                "lt",
                "cz",
                "sk",
                "hu",
                "ro",
                "hr",
                "fi",
                "dk",
                "se",
                "ee",
                "gr",
                "ie",
                "lu",
                "lv",
                "si",
                "us"
              ],
              "enumTitles": [
                "France",
                "Germany",
                "United Kingdom",
                "Italy",
                "Spain",
                "Netherlands",
                "Poland",
                "Portugal",
                "Belgium",
                "Austria",
                "Lithuania",
                "Czech Republic",
                "Slovakia",
                "Hungary",
                "Romania",
                "Croatia",
                "Finland",
                "Denmark",
                "Sweden",
                "Estonia",
                "Greece",
                "Ireland",
                "Luxembourg",
                "Latvia",
                "Slovenia",
                "United States"
              ]
            },
            "default": [
              "fr",
              "de",
              "nl",
              "it",
              "es"
            ]
          },
          "maxResults": {
            "title": "📊 Max results (total)",
            "minimum": 1,
            "type": "integer",
            "description": "Total listings to return across all markets (split evenly). Vinted caps each query at ~960 per market.",
            "default": 100
          },
          "baseCurrency": {
            "title": "💱 Comparison currency",
            "enum": [
              "EUR",
              "GBP",
              "USD",
              "PLN",
              "CZK",
              "SEK",
              "DKK",
              "HUF",
              "RON"
            ],
            "type": "string",
            "description": "Currency all markets are converted to for price-gap comparison. Live ECB rates.",
            "default": "EUR"
          },
          "sortBy": {
            "title": "📈 Sort by",
            "enum": [
              "relevance",
              "price_low_to_high",
              "price_high_to_low",
              "newest_first"
            ],
            "type": "string",
            "description": "How listings are ordered within each market.",
            "default": "relevance"
          },
          "priceMin": {
            "title": "💶 Min price (local currency)",
            "type": "integer",
            "description": "Minimum listing price in each market's local currency. Leave empty for no minimum."
          },
          "priceMax": {
            "title": "💶 Max price (local currency)",
            "type": "integer",
            "description": "Maximum listing price in each market's local currency. Leave empty for no maximum."
          },
          "condition": {
            "title": "✨ Condition filter",
            "type": "array",
            "description": "Filter by item condition. Leave empty to include all conditions.",
            "items": {
              "type": "string",
              "enum": [
                "new_with_tags",
                "new_without_tags",
                "very_good",
                "good",
                "satisfactory"
              ],
              "enumTitles": [
                "New with tags",
                "New without tags",
                "Very good",
                "Good",
                "Satisfactory"
              ]
            }
          },
          "brandNames": {
            "title": "🏷️ Brand names",
            "type": "array",
            "description": "Filter by brand — just type the names (e.g. 'Nike', 'Stone Island'). The actor looks up each brand's ID automatically. Leave empty for all brands.",
            "items": {
              "type": "string"
            }
          },
          "brandIds": {
            "title": "🏷️ Brand IDs (advanced)",
            "type": "array",
            "description": "Advanced: filter by raw Vinted brand ID if you already know it. Most users should use Brand names above instead.",
            "items": {
              "type": "string"
            }
          },
          "sizeIds": {
            "title": "📏 Size IDs (advanced)",
            "type": "array",
            "description": "Advanced: filter by raw Vinted size ID for categories not covered by the dropdowns below. Find it in the URL after selecting a size filter. Leave empty for all sizes.",
            "items": {
              "type": "string"
            }
          },
          "clothingSizes": {
            "title": "👕 Clothing size",
            "type": "array",
            "description": "Filter by clothing size (XS–XXXL). For shoes, use the shoe size filter below. Leave empty for all sizes.",
            "items": {
              "type": "string",
              "enum": [
                "xs",
                "s",
                "m",
                "l",
                "xl",
                "xxl",
                "xxxl"
              ],
              "enumTitles": [
                "XS",
                "S",
                "M",
                "L",
                "XL",
                "XXL",
                "XXXL"
              ]
            }
          },
          "shoeSizes": {
            "title": "👟 Shoe size (EU)",
            "type": "array",
            "description": "Filter by EU shoe size (38–47.5). For clothing, use the clothing size filter above. Leave empty for all sizes.",
            "items": {
              "type": "string",
              "enum": [
                "38",
                "38.5",
                "39",
                "39.5",
                "40",
                "40.5",
                "41",
                "41.5",
                "42",
                "42.5",
                "43",
                "43.5",
                "44",
                "44.5",
                "45",
                "45.5",
                "46",
                "46.5",
                "47",
                "47.5"
              ],
              "enumTitles": [
                "38",
                "38.5",
                "39",
                "39.5",
                "40",
                "40.5",
                "41",
                "41.5",
                "42",
                "42.5",
                "43",
                "43.5",
                "44",
                "44.5",
                "45",
                "45.5",
                "46",
                "46.5",
                "47",
                "47.5"
              ]
            }
          },
          "kidsSizes": {
            "title": "🧒 Kids size (age / cm)",
            "type": "array",
            "description": "Filter by kids clothing size (age / cm, e.g. '6 yr / 116 cm'). Covers newborn to 16 years. Leave empty for all sizes.",
            "items": {
              "type": "string",
              "enum": [
                "newborn_50",
                "1_3m_56",
                "3_6m_62",
                "6_9m_68",
                "9_12m_74",
                "12_18m_80",
                "18_24m_86",
                "2_3y_92",
                "3y_98",
                "4y_104",
                "5y_110",
                "6y_116",
                "7y_122",
                "8y_128",
                "9y_134",
                "10y_140",
                "11y_146",
                "12y_152",
                "13y_158",
                "14y_164",
                "15y_170",
                "16y_176"
              ],
              "enumTitles": [
                "Up to 1m / 50 cm",
                "1-3m / 56 cm",
                "3-6m / 62 cm",
                "6-9m / 68 cm",
                "9-12m / 74 cm",
                "12-18m / 80 cm",
                "18-24m / 86 cm",
                "2-3y / 92 cm",
                "3y / 98 cm",
                "4y / 104 cm",
                "5y / 110 cm",
                "6y / 116 cm",
                "7y / 122 cm",
                "8y / 128 cm",
                "9y / 134 cm",
                "10y / 140 cm",
                "11y / 146 cm",
                "12y / 152 cm",
                "13y / 158 cm",
                "14y / 164 cm",
                "15y / 170 cm",
                "16y / 176 cm"
              ]
            }
          },
          "colors": {
            "title": "🎨 Colour filter",
            "type": "array",
            "description": "Filter listings by colour. Leave empty for all colours. Note: Vinted does not return a colour value per listing, so this narrows the scan but does not add a colour output field.",
            "items": {
              "type": "string",
              "enum": [
                "black",
                "white",
                "grey",
                "beige",
                "brown",
                "red",
                "blue",
                "navy",
                "green",
                "yellow",
                "pink",
                "purple",
                "orange",
                "multi"
              ],
              "enumTitles": [
                "Black",
                "White",
                "Grey",
                "Beige",
                "Brown",
                "Red",
                "Blue",
                "Navy",
                "Green",
                "Yellow",
                "Pink",
                "Purple",
                "Orange",
                "Multicolour"
              ]
            }
          },
          "gender": {
            "title": "🚻 Department",
            "enum": [
              "all",
              "women",
              "men",
              "kids",
              "home",
              "electronics",
              "video_games",
              "books",
              "beauty",
              "jewellery",
              "sports",
              "phone_accessories",
              "bags"
            ],
            "type": "string",
            "description": "Filter by department. Vinted sells far more than clothing — pick Home, Electronics, Video Games, Books & Media, Beauty, Jewellery, Sports, or Bags for non-fashion categories. Leave as 'All' to search everything. Note: if you pick a specific Category below, that takes precedence over this.",
            "default": "all"
          },
          "category": {
            "title": "📂 Category",
            "enum": [
              "all",
              "shoes",
              "coats_jackets",
              "dresses",
              "bags",
              "mens_jeans"
            ],
            "type": "string",
            "description": "Filter by product category. These are the verified cross-department categories. For any other category, use the advanced Category ID field below. If set, this overrides the Department filter.",
            "default": "all"
          },
          "categoryId": {
            "title": "📁 Category ID (advanced)",
            "type": "integer",
            "description": "Advanced: filter by a specific Vinted catalog ID not covered by the Category dropdown. Find it in the catalog URL (catalog[]=NUMBER). Overrides Department and Category if set."
          },
          "includeListings": {
            "title": "📦 Output individual listings",
            "type": "boolean",
            "description": "Output every matching listing row. Disable to get only the cross-country arbitrage summary (cheaper).",
            "default": true
          },
          "dedupeAcrossMarkets": {
            "title": "🔁 Remove cross-market duplicates",
            "type": "boolean",
            "description": "Vinted shows the same listing in every market it ships to. With this on, each item appears once, with a 'markets' field listing every market it was found in. Turn off to get one row per market.",
            "default": true
          },
          "fetchDetails": {
            "title": "🔬 Fetch full item details (premium)",
            "type": "boolean",
            "description": "Fetch each listing's own page to add description, declaredColor and categoryPath, and to resolve status/isAvailable precisely (sold, reserved, hidden). Costs one extra request per listing.",
            "default": false
          },
          "fetchShipping": {
            "title": "Fetch shipping cost",
            "type": "boolean",
            "description": "Resolve the cheapest shipping option for each listing and fill shippingCostEur and totalCostEur. Costs one extra request per listing, but it is the SAME request fetchDetails already makes, so turning both on costs no more than turning on either. Leave off and both fields stay null - never zero, so a consumer can tell 'unknown' from 'free'.",
            "default": false
          },
          "maxPhotosPerItem": {
            "title": "Max photos per listing",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Cap on how many photo URLs to emit per listing in photoUrls. The source returns every photo (listings with 18 are common), so this only limits payload size. photoCount always reports the true number the listing holds, so you can tell when this cap bit.",
            "default": 10
          },
          "sellThroughTracking": {
            "title": "📈 Sell-through tracking mode",
            "type": "boolean",
            "description": "Measure real demand. Run this on a schedule (e.g. daily): the actor snapshots live listings and flags items that disappear as 'likely sold', giving you a sell-through rate and median days-to-sell for your niche. Overrides the normal scan output.",
            "default": false
          },
          "trackerName": {
            "title": "🏷️ Tracker name",
            "type": "string",
            "description": "Name for persistent run-to-run state, stored in a named key-value store. Set it and firstSeenAt becomes the listing's real first sighting instead of the current run's timestamp. Also used by sell-through tracking. Leave empty and firstSeenAt equals scrapedAt."
          },
          "missingRunsBeforeSold": {
            "title": "📉 Missing runs before 'likely sold'",
            "minimum": 1,
            "type": "integer",
            "description": "How many consecutive runs an item must be absent before it's marked likely sold. Use 2 to avoid false positives from search-ranking shuffle.",
            "default": 2
          },
          "emitActiveItems": {
            "title": "📤 Output still-active items too",
            "type": "boolean",
            "description": "In sell-through mode, also output items that are still listed (with days-listed and any price drop). Disable to output only newly-sold items and the summary (cheaper).",
            "default": true
          },
          "minSellThroughAlertPct": {
            "title": "🔔 Minimum sell-through % to alert",
            "type": "integer",
            "description": "In sell-through mode, only send a webhook alert when the sell-through rate is at least this percentage. Leave empty to always alert. Pairs with the Telegram/Discord/Slack fields below."
          },
          "includeArbitrageSummary": {
            "title": "📊 Output arbitrage summary",
            "type": "boolean",
            "description": "Add one summary row comparing median/min/max prices across markets and naming the buy-low / sell-high pair.",
            "default": true
          },
          "telegramBotToken": {
            "title": "📨 Telegram bot token",
            "type": "string",
            "description": "Optional. Send each run's arbitrage alert to Telegram. Create a bot with @BotFather and paste its token here. Also fill in the chat ID below."
          },
          "telegramChatId": {
            "title": "📨 Telegram chat ID",
            "type": "string",
            "description": "Optional. The chat or channel ID to send Telegram alerts to (e.g. your user ID, or -100... for a channel). Required if a bot token is set."
          },
          "discordWebhookUrl": {
            "title": "📨 Discord webhook URL",
            "type": "string",
            "description": "Optional. Send each run's arbitrage alert to a Discord channel. Paste an Incoming Webhook URL (Server Settings → Integrations → Webhooks)."
          },
          "slackWebhookUrl": {
            "title": "📨 Slack webhook URL",
            "type": "string",
            "description": "Optional. Send each run's arbitrage alert to a Slack channel. Paste an Incoming Webhook URL (api.slack.com/messaging/webhooks)."
          },
          "minSpreadPctAlert": {
            "title": "🔔 Minimum spread % to alert",
            "type": "integer",
            "description": "Only send alerts when the cross-country median spread is at least this percentage. Leave empty to always alert. Useful for scheduled runs that should only ping you on real opportunities."
          },
          "alertTopListings": {
            "title": "🔔 Listings per alert",
            "minimum": 1,
            "type": "integer",
            "description": "How many of the cheapest listings to include in each alert message.",
            "default": 5
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}