{
  "openapi": "3.0.1",
  "info": {
    "title": "Haodf Scraper: 好大夫在线 Doctor & Hospital Reviews",
    "description": "Scrape Haodf (好大夫在线) doctor profiles, aggregate reputation stats, and real per-condition patient reviews (effect/attitude/skill ratings, anonymized patient location, dates). No login or API key needed. Includes a new-reviews monitor mode for tracking a shortlist of doctors over time.",
    "version": "0.1",
    "x-build-id": "nbPjjegfgAyqGg9z4"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/getascraper~haodf-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-getascraper-haodf-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/getascraper~haodf-scraper/runs": {
      "post": {
        "operationId": "runs-sync-getascraper-haodf-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/getascraper~haodf-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-getascraper-haodf-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": {
          "doctorUrls": {
            "title": "Doctor URLs or IDs",
            "type": "array",
            "description": "Direct Haodf doctor profile links or their bare numeric IDs, one per line (both https://www.haodf.com/doctor/11908.html and 11908 work). This is the cheapest, most reliable way to target specific doctors. Leave empty to auto-discover doctors from the Department field below instead.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "department": {
            "title": "Department",
            "type": "string",
            "description": "Only used when Doctor URLs above is empty. Picks which Haodf department directory page to auto-discover doctors from. You can also type in any other department slug from Haodf's own department picker, not just the ones suggested here.",
            "default": "huxineike"
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Haodf's doctor, review, and hospital pages were confirmed to return clean, unblocked responses across real-Chrome, Googlebot, and empty User-Agent tests, so Apify's cheaper datacenter proxy is used by default. Residential proxy is not needed for this target.",
            "default": {
              "useApifyProxy": true
            }
          },
          "includeHospitalDetails": {
            "title": "Include hospital details",
            "type": "boolean",
            "description": "Fetch each doctor's hospital profile page once (deduplicated across doctors sharing a hospital) to add hospital grade, total doctor/faculty counts, and hospital-wide service-patient counts to the Department Breakdown view. Adds one extra request per unique hospital, so it defaults off to keep runs fast and cheap.",
            "default": false
          },
          "maxDoctors": {
            "title": "Max doctors",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Maximum number of doctors to scrape in this run, whether they come from Doctor URLs or from department auto-discovery. Keep this low for a quick test run; raise it once you know the run time and cost you're comfortable with.",
            "default": 15
          },
          "maxDiseaseTagsPerDoctor": {
            "title": "Max disease tags per doctor",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Most active doctors on Haodf are reviewed under several different conditions (disease tags), each with its own review page. This caps how many of a doctor's most-reviewed disease tags get fetched, since each tag is one additional request yielding its own aggregate stats and up to 10 reviews.",
            "default": 5
          },
          "onlyNewReviews": {
            "title": "Only new reviews since last check",
            "type": "boolean",
            "description": "Turns this run into a monitor: only reviews whose ID has not been seen before for this doctor and disease tag under State Name below are pushed to the Reviews dataset. Run this Actor again later on a schedule with the same State Name to get alerted only to genuinely new patient reviews.",
            "default": false
          },
          "stateName": {
            "title": "State name",
            "type": "string",
            "description": "Identifies this tracked doctor set's saved monitor state, so you can run several independent trackers (e.g. one per client or department) without them overwriting each other's seen-review history. Only relevant when Only new reviews since last check is enabled.",
            "default": "default"
          },
          "resetState": {
            "title": "Reset monitor state",
            "type": "boolean",
            "description": "Clears the saved seen-review history for State Name before this run starts, so every review currently on the page is treated as new again. Use this once if you want to restart tracking from scratch.",
            "default": false
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}