{
  "openapi": "3.0.1",
  "info": {
    "title": "Mudah.my Cars, Property, Jobs & Marketplace Scraper",
    "description": "Scrape Mudah.my listings across every category: cars, motorcycles, property, mobiles, electronics, home, hobbies, jobs and services. Search by keyword, filter by category, state and price, or paste URLs. Rich records with seller, store verification, images and category-specific specs.",
    "version": "1.0",
    "x-build-id": "Gu4QFAYgQg2Xe5zad"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~mudah-my-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-mudah-my-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~mudah-my-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-mudah-my-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~mudah-my-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-mudah-my-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: run a keyword/category search, or scrape specific pasted URLs.",
            "default": "search"
          },
          "queries": {
            "title": "Search keywords",
            "type": "array",
            "description": "One or more keywords to search across Mudah.my (e.g. iphone, honda civic, condo). Leave empty to browse a whole category or state.",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "Category",
            "enum": [
              "all",
              "cars",
              "motorcycles",
              "property",
              "apartments-condos",
              "computers",
              "mobiles-gadgets",
              "home-furniture",
              "hobbies-collectibles",
              "business-equipment",
              "jobs",
              "services-others"
            ],
            "type": "string",
            "description": "Restrict results to a category. Choose All to search across every category.",
            "default": "all"
          },
          "state": {
            "title": "State",
            "enum": [
              "all",
              "johor",
              "kedah",
              "kelantan",
              "kuala-lumpur",
              "labuan",
              "melaka",
              "negeri-sembilan",
              "pahang",
              "penang",
              "perak",
              "perlis",
              "putrajaya",
              "sabah",
              "sarawak",
              "selangor",
              "terengganu"
            ],
            "type": "string",
            "description": "Restrict results to a Malaysian state. Choose All for the whole country.",
            "default": "all"
          },
          "listingType": {
            "title": "Listing type",
            "enum": [
              "all",
              "for-sale",
              "for-rent"
            ],
            "type": "string",
            "description": "All listings, only items offered for sale, or only items offered for rent (rentals, rooms, property for rent). Search mode; in URL mode a ...-for-rent page already implies rent.",
            "default": "all"
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "Mudah.my URLs to scrape. Supports individual listing pages (…-<id>.htm), category pages (including state pages such as /selangor/cars-for-sale and rentals such as /malaysia/properties-for-rent), keyword-search pages (?q=) and page links (?o=2, mapped to an approximate start position). Multiple URLs supported. Left untouched, URL mode scrapes the ten example links (one per URL shape).",
            "default": [
              "https://www.mudah.my/malaysia/cars-for-sale?q=honda+civic",
              "https://www.mudah.my/malaysia/cars-for-sale",
              "https://www.mudah.my/selangor/cars-for-sale",
              "https://www.mudah.my/malaysia/all?q=iphone",
              "https://www.mudah.my/malaysia/cars-for-sale?o=2",
              "https://www.mudah.my/malaysia/cars-for-sale?q=honda+civic&o=2",
              "https://www.mudah.my/malaysia/cars-for-sale?q=honda&price=10000-50000",
              "https://www.mudah.my/malaysia/properties-for-rent",
              "https://www.mudah.my/malaysia/mobile-phones-and-gadgets-for-sale",
              "https://www.mudah.my/selangor/honda-civic-for-sale-115524640.htm"
            ],
            "items": {
              "type": "string"
            }
          },
          "minPrice": {
            "title": "Minimum price (RM)",
            "minimum": 0,
            "type": "integer",
            "description": "Only listings priced at or above this amount in Malaysian Ringgit."
          },
          "maxPrice": {
            "title": "Maximum price (RM)",
            "minimum": 0,
            "type": "integer",
            "description": "Only listings priced at or below this amount in Malaysian Ringgit."
          },
          "onlyUrgent": {
            "title": "Only urgent listings",
            "type": "boolean",
            "description": "Only listings the seller has flagged URGENT (a paid boost on Mudah.my). Applies to search mode and to category/keyword links in URL mode.",
            "default": false
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Maximum number of listings to return across all searches / URLs (up to 100000). Set 0 for the highest allowed limit (100000); the run stops earlier when results are exhausted.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "Optional bound on result pages walked per search/URL. Leave empty to walk result pages up to a hard limit of 500 pages per search/URL; the run stops earlier at Max items or when a search's results are exhausted."
          },
          "includeDetails": {
            "title": "Include listing details",
            "type": "boolean",
            "description": "Also open each listing's own page to add the full description, the whole photo gallery and the seller and contact flags (chat and WhatsApp available, advertiser online, agent and firm numbers where shown). Costs one extra page request per listing, so runs are slower; the number of rows and the price per row stay the same. Phone numbers are never collected. If a page cannot be read, that row is still returned without these fields.",
            "default": false
          },
          "proxy": {
            "title": "Connection",
            "type": "object",
            "description": "Connection configuration. The default Apify connection is recommended.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run (optional)",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue a full-catalogue walk across separate runs. Listings already collected there (matched by listing id) are skipped, so this run only saves the new ones. For recurring daily/weekly monitoring of the same search, use Incremental mode below instead. Leave empty for a normal fresh run."
          },
          "incrementalMode": {
            "title": "Incremental changes for scheduled runs",
            "type": "boolean",
            "description": "Turn this on for daily or recurring monitoring. The first run returns all matching listings as NEW. Later runs normally return only NEW, UPDATED, and REAPPEARED listings, unchanged ones are suppressed (and not billed). A listing is UPDATED when any of its scraped fields changed (price, title, description, images, seller, highlights, timestamps such as modifiedAt, and the raw attributes); the changed names are listed in changedFields. scrapedAt and the per-search rank are always excluded (at any depth) because they change on every fetch, and any field you list in Ignore fields never triggers UPDATED, though it stays in the output. Turn on \"Emit unchanged\" or \"Emit expired\" only when you also want those listings returned (and billed). State is kept separately for each mode/keyword/category/state/listing type/price/urgent-only filter/URL setup; use State key when you want 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 (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 mode/keyword/category/state/price/URL setup, different searches then never mix state with each other."
          },
          "emitUnchanged": {
            "title": "Emit unchanged listings (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return listings 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 the full snapshot every run.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit expired listings (incremental mode only)",
            "type": "boolean",
            "description": "Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search, so not when Max items/Max pages capped it, not when Resume was used, and not on a URL-mode run that only looked up individual listing URLs (such a run never walks the tracked search, so it cannot prove anything is gone). 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": "Field names that must NOT make a listing UPDATED, one per entry. Use dots for nested fields, for example \"timestamps.modifiedAt\" or \"seller.storeId\"; array items are covered automatically. Ignored fields stay in the output, they just never count as a change. Only applies when Incremental changes is on.",
            "default": [],
            "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-item export; other connectors get a best-effort write. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}