{
  "openapi": "3.0.1",
  "info": {
    "title": "Expat-Dakar Scraper - Senegal Property Listings & Prices",
    "description": "Senegalese property adverts from Expat-Dakar: asking price in CFA francs, bedrooms, floor area, neighbourhood and region, photos, and the advertiser's phone and WhatsApp number on every row. Search nine categories across seven regions, or open single adverts for the full seller text, bathroom count ",
    "version": "1.0",
    "x-build-id": "qpzSTk8URI5iYucJy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/sian.agency~expat-dakar-property-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-sian.agency-expat-dakar-property-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/sian.agency~expat-dakar-property-scraper/runs": {
      "post": {
        "operationId": "runs-sync-sian.agency-expat-dakar-property-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/sian.agency~expat-dakar-property-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-sian.agency-expat-dakar-property-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",
        "properties": {
          "operation": {
            "title": "🎯 What to do",
            "enum": [
              "search",
              "detail"
            ],
            "type": "string",
            "description": "Property Search walks the portal's result pages and returns ten adverts per request, each already carrying a phone and WhatsApp number. Property Detail takes advert addresses you already have and opens each one for the full seller text, the bathroom count and every photo. One operation per run.",
            "default": "search"
          },
          "category": {
            "title": "🏠 Category",
            "enum": [
              "immobilier",
              "appartements-a-louer",
              "appartements-meubles",
              "appartements-a-vendre",
              "maisons-a-louer",
              "maisons-a-vendre",
              "terrains-a-vendre",
              "chambres-a-louer",
              "proprietes-commerciales-a-louer",
              "proprietes-commerciales-a-vendre"
            ],
            "type": "string",
            "description": "One category per run. Expat-Dakar files property by what it is AND whether it is for sale or to rent, so the category is the deal type as well — there is no separate sale/rent switch and no combination that does not exist. Measured depth on 2026-09-13: apartments to rent 1,351, furnished apartments 685, land for sale 441, houses to rent 373, apartments for sale 323, houses for sale 289, commercial to rent 178, rooms to rent 93, commercial for sale 29. All property is all nine at once, 3,762…",
            "default": "immobilier"
          },
          "region": {
            "title": "📍 Region",
            "enum": [
              "all",
              "dakar",
              "thies",
              "saint-louis",
              "autres",
              "kaolack",
              "diourbel",
              "sine-saloum",
              "ziguinchor",
              "fatick",
              "kaffrine"
            ],
            "type": "string",
            "description": "Every value here is a place the portal's own index recognises, and that held property adverts when this actor was built. Six Senegalese regions hold none — Louga, Matam, Kolda, Tambacounda, Kédougou and Sédhiou — so they are left out rather than offered as a filter that returns nothing. The market is concentrated: Dakar held 3,401 of 3,762 adverts and Thiès 313, so anything outside those two is a handful. Pick All of Senegal to sweep the lot.",
            "default": "all"
          },
          "keyword": {
            "title": "🔎 Keyword",
            "type": "string",
            "description": "Optional. Narrows the chosen category to adverts whose text matches, which is how you reach a neighbourhood: Expat-Dakar has no URL for one, so \"almadies\", \"mermoz\", \"ngor\" or \"point e\" is the way to get a neighbourhood slice. Matching is on the advert's own wording, so a misspelling returns nothing rather than everything. Leave empty for the whole category.",
            "default": ""
          },
          "minPrice": {
            "title": "💰 Minimum price (CFA)",
            "minimum": 0,
            "maximum": 999999999999,
            "type": "integer",
            "description": "Optional floor, in CFA francs, on the figure printed on the advert — a monthly rent for rentals and an asking price for sales. Leave at 0 for no floor. Setting any price bound drops the adverts that carry no price at all: on the full vertical that is about 77 of 3,762.",
            "default": 0
          },
          "maxPrice": {
            "title": "💰 Maximum price (CFA)",
            "minimum": 0,
            "maximum": 999999999999,
            "type": "integer",
            "description": "Optional ceiling, in CFA francs, on the same figure. Leave at 0 for no ceiling. Rents in Dakar cluster between 200,000 and 1,500,000 F CFA a month; sale prices run from about 20,000,000 upwards.",
            "default": 0
          },
          "sortBy": {
            "title": "↕️ Order",
            "enum": [
              "priority",
              "latest",
              "lowest-price",
              "highest-price"
            ],
            "type": "string",
            "description": "Newest first is the one to use for monitoring — run it on a schedule and diff the advert IDs. The portal's own order is the default because it is the order the board itself paginates most stably. The board's fifth ordering, Special offers, is deliberately not offered: it quietly returns fewer adverts than the others, so it is a filter wearing a sort's clothes.",
            "default": "priority"
          },
          "maxItems": {
            "title": "🔢 How many adverts",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Stops the sweep once this many adverts have been returned. The portal serves ten per request, so 100 is ten requests. Set it above the slice's own size to drain it completely — All property across all of Senegal is about 3,760 adverts, apartments to rent about 1,350, and Dakar alone about 3,400.",
            "default": 100
          },
          "propertyUrl": {
            "title": "🔗 Advert address",
            "type": "string",
            "description": "Used by Property Detail. Paste the full address of an Expat-Dakar advert, exactly as it appears in your browser. An advert number on its own also works — the number is the trailing digits of the address — but the address is what the search rows give you. Ignored by Property Search.",
            "default": ""
          },
          "propertyUrls": {
            "title": "🔗 Several advert addresses",
            "type": "array",
            "description": "Used by Property Detail for more than one advert at a time. One full Expat-Dakar advert address per line. Duplicates are removed before anything is charged.",
            "default": [],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}