{
  "openapi": "3.0.1",
  "info": {
    "title": "Milanuncios Scraper API 🇪🇸 Condition & Price Drops",
    "description": "Searches Milanuncios by keyword across 17 categories — motor, property, fashion, pets and more — filtering by price, condition, seller type and province. For phones, also parses storage and battery health from the description. Reads the page's own embedded JSON, no browser.",
    "version": "0.1",
    "x-build-id": "ib7RgYY3wSFd9aMiJ"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/reventadata~milanuncios-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-reventadata-milanuncios-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/reventadata~milanuncios-scraper/runs": {
      "post": {
        "operationId": "runs-sync-reventadata-milanuncios-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/reventadata~milanuncios-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-reventadata-milanuncios-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": [
          "searchQueries"
        ],
        "properties": {
          "searchQueries": {
            "title": "Search keywords",
            "type": "array",
            "description": "One search per keyword. There is no default: an empty list fails the run rather than searching for something you did not ask for.",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Category slug",
            "type": "string",
            "description": "Optional. Milanuncios' category is a URL path segment, not a query parameter. Verified top-level slugs: motor, inmobiliaria, ofertas-de-empleo, formacion, servicios, negocios, informatica-segunda-mano, imagen-y-sonido, telefonia, telefonos-moviles, juegos, casa-y-jardin, moda-y-complementos, bebes, aficiones, deportes-nautica, mascotas. Combines freely with province - setting both narrows to their intersection (e.g. category=telefonia + province=madrid -> path /telefonia-en-madrid/, narrower than either alone). Validated against the known slug list before the run starts; an unknown slug fails the run rather than silently searching every category."
          },
          "province": {
            "title": "Province",
            "enum": [
              "alava",
              "albacete",
              "alicante",
              "almeria",
              "asturias",
              "avila",
              "badajoz",
              "baleares",
              "barcelona",
              "vizcaya",
              "burgos",
              "caceres",
              "cadiz",
              "cantabria",
              "castellon",
              "ceuta",
              "ciudad_real",
              "cordoba",
              "la_coruna",
              "cuenca",
              "guipuzcoa",
              "girona",
              "granada",
              "guadalajara",
              "huelva",
              "huesca",
              "jaen",
              "la_rioja",
              "las_palmas",
              "leon",
              "lleida",
              "lugo",
              "madrid",
              "malaga",
              "melilla",
              "murcia",
              "navarra",
              "ourense",
              "palencia",
              "pontevedra",
              "salamanca",
              "segovia",
              "sevilla",
              "soria",
              "tarragona",
              "tenerife",
              "teruel",
              "toledo",
              "valencia",
              "valladolid",
              "zamora",
              "zaragoza"
            ],
            "type": "string",
            "description": "Optional. Restricts results to one Spanish province via its own URL path segment. Combines freely with category, not exclusively - setting both narrows the path to their intersection (e.g. /telefonia-en-madrid/ is narrower than either /telefonia/ or /anuncios-en-madrid/ alone). A closed set of 52 (50 provinces plus Ceuta and Melilla), so this is a dropdown rather than free text - a typo is caught here instead of failing the run later."
          },
          "minPrice": {
            "title": "Minimum price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Maps to the site's own \"desde\" parameter. Left out of the request entirely when unset - there is no default floor, and 0 is not silently substituted."
          },
          "maxPrice": {
            "title": "Maximum price (EUR)",
            "minimum": 1,
            "type": "integer",
            "description": "Optional. Maps to the site's own \"hasta\" parameter. Left out of the request entirely when unset - there is no default ceiling."
          },
          "sellerType": {
            "title": "Seller type",
            "enum": [
              "any",
              "private",
              "professional"
            ],
            "type": "string",
            "description": "Filters by who is selling, using the site's own \"vendedor\" parameter. Only the truncated values \"part\"/\"prof\" work server-side - the full words \"particular\"/\"profesional\" are silently ignored, which is why this is an enum rather than free text.",
            "default": "any"
          },
          "adType": {
            "title": "Ad type",
            "enum": [
              "any",
              "offer",
              "wanted"
            ],
            "type": "string",
            "description": "Filters by whether the ad is an offer to sell or a request to buy, using the site's own \"demanda\" parameter (n = offer, s = wanted).",
            "default": "any"
          },
          "onlyShippable": {
            "title": "Only shippable listings",
            "type": "boolean",
            "description": "Maps to the site's own \"isShippable=true\" parameter. Left out of the request entirely when false - there is no explicit isShippable=false.",
            "default": false
          },
          "onlyPriceDropped": {
            "title": "Only price-dropped listings",
            "type": "boolean",
            "description": "Maps to the site's own \"isPriceDropped=true\" parameter. Left out of the request entirely when false.",
            "default": false
          },
          "conditions": {
            "title": "Condition",
            "type": "array",
            "description": "Milanuncios carries a structured \"estado del producto\" tag on each ad, so this is closer to a fact than a seller's claim. Filtered client-side against that tag. Leave empty for any condition. The vocabulary below is a sample measured over 100 live ads, not a closed set - an ad with an unseen condition value is never offered here but still passes through unfiltered results untouched.",
            "items": {
              "type": "string",
              "enum": [
                "sin estrenar",
                "prácticamente nuevo",
                "en buen estado",
                "aceptable"
              ],
              "enumTitles": [
                "Sin estrenar (unopened)",
                "Prácticamente nuevo (as new)",
                "En buen estado (good condition)",
                "Aceptable (acceptable)"
              ]
            },
            "default": []
          },
          "minStorageGb": {
            "title": "Minimum storage (GB)",
            "minimum": 0,
            "type": "integer",
            "description": "Parsed from the title and description, since Milanuncios does not carry storage as a structured field. Items that never state it are dropped when this is set. Leave empty to ignore storage. TB values are converted, so 1TB counts as 1024."
          },
          "minBatteryHealth": {
            "title": "Minimum battery health (%)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Parsed from the description text. Only meaningful for phones - non-phone listings simply never match and are dropped if this is set. Leave empty to ignore battery health."
          },
          "excludeDamaged": {
            "title": "Exclude damaged items",
            "type": "boolean",
            "description": "Drops listings whose description matches known damage wording (cracked screen, broken, for parts, etc.), using the same vocabulary as the sibling Wallapop Actor. On by default.",
            "default": true
          },
          "requireKeywordMatch": {
            "title": "Require the keyword to appear in the title",
            "type": "boolean",
            "description": "Milanuncios' search is fuzzy - searching \"iphone 15\" can also return unrelated accessories or other models. This drops any item whose title does not contain the query. Turn it off for broad exploration.",
            "default": true
          },
          "sortBy": {
            "title": "Sort order",
            "enum": [
              "relevance",
              "date",
              "baratos",
              "caros"
            ],
            "type": "string",
            "description": "The site's own sort rules, via the \"orden\" parameter. Order only - it changes nothing about which ads exist, only the order they are paged in.",
            "default": "relevance"
          },
          "maxItems": {
            "title": "Maximum results",
            "minimum": 1,
            "type": "integer",
            "description": "Hard cap on rows pushed for the whole run. When this cap or the site's own page cap is hit, it is logged rather than silently truncating the result set.",
            "default": 1000
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Sustained scraping earns the requesting IP a silent block - a 200 with a plausible page and no data blob at all, with no 429 and no Retry-After to signal it. A small run works fine without a proxy; a rotating one is what keeps a large run alive. Left unset, no proxy is used at all."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}