{
  "openapi": "3.0.1",
  "info": {
    "title": "Kijiji & RentFaster Scraper — Canada Rental Listings + Geo Data",
    "description": "Scrape Canadian rental listings from Kijiji and RentFaster.ca in one normalized schema — price, beds, baths, address, coordinates — with cross-source dedup and nearest-amenity (subway/grocery/school) distances. Apartments, condos, houses across Canada.",
    "version": "0.1",
    "x-build-id": "vh73nBUNkbgXHqBNi"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/soroush98~kijiji-canada-rentals-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-soroush98-kijiji-canada-rentals-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/soroush98~kijiji-canada-rentals-scraper/runs": {
      "post": {
        "operationId": "runs-sync-soroush98-kijiji-canada-rentals-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/soroush98~kijiji-canada-rentals-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-soroush98-kijiji-canada-rentals-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": [
          "sources"
        ],
        "properties": {
          "sources": {
            "title": "Sources",
            "type": "array",
            "description": "Which rental sites to scrape.",
            "items": {
              "type": "string",
              "enum": [
                "kijiji",
                "rentfaster"
              ],
              "enumTitles": [
                "Kijiji",
                "RentFaster.ca"
              ]
            },
            "default": [
              "kijiji",
              "rentfaster"
            ]
          },
          "cities": {
            "title": "Cities",
            "type": "array",
            "description": "City names to cover (e.g. Toronto, Calgary). Leave empty for all supported cities.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxPerCity": {
            "title": "Max listings per city (per source)",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Upper bound on listings collected from each city, for each source.",
            "default": 100
          },
          "maxResults": {
            "title": "Max results (total)",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "Hard cap on how many listings the run returns (after filtering + dedup). Raise it for bulk dataset pulls.",
            "default": 50
          },
          "minRent": {
            "title": "Min rent ($/month)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only listings at or above this monthly rent."
          },
          "maxRent": {
            "title": "Max rent ($/month)",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only listings at or below this monthly rent. e.g. 2500."
          },
          "minBedrooms": {
            "title": "Min bedrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum bedroom count. Use 0 to include bachelor/studio (stored as 0.5)."
          },
          "maxBedrooms": {
            "title": "Max bedrooms",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum bedroom count. For exactly 2-bed, set min and max both to 2."
          },
          "keywords": {
            "title": "Description must contain ALL of these",
            "type": "array",
            "description": "Case-insensitive substring match over title + description. ALL must be present. e.g. [\"female\"] for women-only, or [\"parking\",\"balcony\"].",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Description must contain NONE of these",
            "type": "array",
            "description": "Drop a listing if its title/description contains ANY of these. e.g. [\"no pets\",\"students only\"].",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "nearAmenities": {
            "title": "Near these amenity types",
            "type": "array",
            "description": "Keep only listings within the distance below of EACH selected amenity type (uses OpenStreetMap). Turns on amenity enrichment automatically.",
            "items": {
              "type": "string",
              "enum": [
                "subway",
                "train",
                "bus_stop",
                "grocery",
                "cafe",
                "pharmacy",
                "park",
                "school",
                "university",
                "library",
                "gym",
                "hospital"
              ]
            },
            "default": []
          },
          "maxAmenityDistanceM": {
            "title": "Max distance to amenity (m)",
            "minimum": 100,
            "maximum": 5000,
            "type": "integer",
            "description": "Used with 'Near these amenity types'. 800 m ≈ a 10-minute walk.",
            "default": 800
          },
          "nearAddress": {
            "title": "Near a specific address / place",
            "type": "string",
            "description": "Free-text address or place to anchor on, e.g. 'University of Toronto' or '200 Bay St, Toronto'. Geocoded, then listings are kept within the radius below. Use this for 'near my workplace' (amenity categories can't find a specific employer)."
          },
          "nearAddressRadiusM": {
            "title": "Radius around that address (m)",
            "minimum": 100,
            "maximum": 20000,
            "type": "integer",
            "description": "Used with 'Near a specific address'.",
            "default": 2000
          },
          "dedupe": {
            "title": "Collapse cross-source duplicates",
            "type": "boolean",
            "description": "Merge the same unit posted to multiple sites into one row (records the extra site in `also_on`).",
            "default": true
          },
          "enrichAmenities": {
            "title": "Attach nearest-amenity distances",
            "type": "boolean",
            "description": "Add `amenity_distances_m` (nearest subway/grocery/school/etc. in metres) from a bundled offline POI index — fast, free, no external API. Off by default. See README.",
            "default": false
          },
          "enrichRadiusM": {
            "title": "Amenity search radius (m)",
            "minimum": 250,
            "maximum": 5000,
            "type": "integer",
            "description": "Only used when amenity enrichment is on.",
            "default": 1500
          },
          "maxEnrich": {
            "title": "Max listings to enrich",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Cap on how many listings are enriched per run. Only used when enrichment is on.",
            "default": 200
          },
          "maxConcurrency": {
            "title": "Max concurrent requests",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Per-source request concurrency. Keep low to stay polite and avoid blocks.",
            "default": 3
          },
          "minDelayMs": {
            "title": "Min per-request delay (ms)",
            "type": "integer",
            "description": "Lower bound of the random delay inserted before each request (politeness).",
            "default": 500
          },
          "maxDelayMs": {
            "title": "Max per-request delay (ms)",
            "type": "integer",
            "description": "Upper bound of the random delay inserted before each request (politeness).",
            "default": 1500
          },
          "userAgent": {
            "title": "User-Agent override",
            "type": "string",
            "description": "Optional. Set a real contact string in production."
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Both Kijiji and RentFaster block datacenter IPs (Cloudflare), so this defaults to RESIDENTIAL Canadian IPs, rotated per request. Residential proxy is metered (~$8/GB) and draws from your plan credit. Switch the group to datacenter to run free, but expect intermittent blocks.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ],
              "apifyProxyCountry": "CA"
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}