{
  "openapi": "3.0.1",
  "info": {
    "title": "Florida Medical License Scraper — DOH MQA Verification",
    "description": "Primary-source verification and bulk extraction of Florida's 3.48M health care licenses from the DOH/MQA portal: physicians, nurses, dentists, pharmacists and 32 more boards. Paste license numbers to verify, or filter by board, profession, county or ZIP. Status, address, expiry, discipline.",
    "version": "0.2",
    "x-build-id": "FlrzPzOTMEFdergFp"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapersdelight~florida-medical-license-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapersdelight-florida-medical-license-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/scrapersdelight~florida-medical-license-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapersdelight-florida-medical-license-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/scrapersdelight~florida-medical-license-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapersdelight-florida-medical-license-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": {
          "licenseNumbers": {
            "title": "License numbers to verify (batch)",
            "type": "array",
            "description": "One Florida DOH/MQA license number per line, e.g. ME58861, RN9268431, PS17155. Each number costs one search request plus its detail pages, and is billed as one licensee row only if it resolves. Verifying 500 numbers in ONE run costs exactly the same as 500 single-number runs and takes a fraction of the wall time — but raise \"Max licensees\" below to at least the length of your list, because it caps this batch too and ships at 100. These are DOH health-care numbers — Florida DBPR contractor and real-estate numbers (CGC…, CFC…, SL…) are a different agency and will not resolve here. Detail level \"roster\" has no meaning on this path: a license number resolves directly to its verification page, so these rows always come back at license depth (or profile, if you ask for it) at the same price per row.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "licenseNumber": {
            "title": "Single license number",
            "type": "string",
            "description": "A one-off lookup, identical to putting a single value in the batch field above. Handy for run-sync API calls: POST /run-sync-get-dataset-items with {\"licenseNumber\":\"ME58861\",\"detailLevel\":\"profile\"} returns the finished record in the HTTP response.",
            "default": ""
          },
          "board": {
            "title": "Licensing board",
            "enum": [
              "",
              "60",
              "38",
              "10",
              "5",
              "66",
              "52",
              "7",
              "36",
              "14",
              "15",
              "16",
              "17",
              "56",
              "20",
              "18",
              "31",
              "19",
              "22",
              "55",
              "21",
              "27",
              "57",
              "41",
              "25",
              "54",
              "32",
              "61",
              "65",
              "26",
              "53",
              "62",
              "8",
              "24",
              "76",
              "30",
              "96"
            ],
            "type": "string",
            "description": "Which of Florida's 36 MQA boards and councils to search. The list is exactly the portal's own dropdown, read live on 2026-08-12. Board sizes measured the same day: Nursing 1,573,814 · Pharmacy 272,596 · Medicine 269,685 · Emergency Medical Services 258,162 · Radiation Control 179,419 · Massage Therapy 152,118 · CSW/MFT/MHC 122,492 · Dentistry 105,285. Leave on \"Any board\" if you are filtering by profession instead — a profession is unique across boards, so the board adds nothing.",
            "default": ""
          },
          "profession": {
            "title": "Profession",
            "enum": [
              "",
              "2403",
              "2401",
              "2402",
              "3801",
              "9676",
              "1711",
              "1712",
              "9603",
              "1515",
              "9607",
              "2002",
              "9641",
              "1001",
              "9639",
              "3002",
              "9672",
              "3004",
              "9679",
              "9677",
              "9678",
              "1403",
              "503",
              "9622",
              "5401",
              "9653",
              "4401",
              "9604",
              "2105",
              "5702",
              "9663",
              "506",
              "501",
              "9621",
              "6604",
              "6601",
              "9633",
              "6602",
              "9634",
              "6603",
              "5211",
              "2203",
              "9611",
              "701",
              "717",
              "702",
              "704",
              "9637",
              "703",
              "707",
              "706",
              "9638",
              "709",
              "708",
              "6001",
              "9627",
              "6101",
              "9666",
              "6501",
              "9668",
              "6503",
              "6502",
              "2503",
              "9626",
              "2501",
              "9624",
              "2603",
              "2601",
              "2602",
              "1533",
              "5301",
              "9681",
              "1519",
              "3601",
              "9642",
              "3603",
              "9643",
              "5201",
              "9644",
              "5202",
              "9645",
              "5203",
              "9646",
              "1702",
              "9602",
              "1506",
              "2703",
              "9656",
              "5212",
              "1402",
              "1401",
              "9669",
              "1406",
              "1501",
              "1517",
              "1505",
              "1504",
              "9605",
              "1503",
              "1502",
              "1513",
              "1509",
              "1507",
              "1508",
              "6004",
              "9630",
              "6003",
              "9629",
              "6007",
              "9631",
              "5213",
              "3201",
              "9675",
              "1601",
              "710",
              "2210",
              "2204",
              "9612",
              "1705",
              "1704",
              "801",
              "802",
              "6102",
              "9667",
              "5601",
              "9660",
              "5602",
              "9661",
              "5604",
              "1514",
              "2003",
              "2001",
              "9640",
              "1805",
              "1801",
              "9623",
              "1802",
              "3104",
              "3105",
              "9617",
              "9616",
              "3109",
              "9619",
              "3111",
              "3103",
              "9615",
              "1904",
              "1906",
              "1903",
              "1901",
              "1917",
              "9670",
              "1902",
              "1905",
              "1516",
              "2502",
              "9625",
              "3106",
              "9618",
              "2201",
              "2202",
              "9610",
              "2205",
              "2209",
              "5501",
              "5502",
              "9659",
              "9658",
              "1512",
              "9606",
              "1520",
              "1709",
              "2101",
              "9608",
              "2102",
              "2106",
              "9609",
              "3110",
              "9620",
              "3102",
              "9614",
              "3101",
              "9613",
              "3006",
              "9674",
              "5204",
              "9647",
              "5205",
              "9648",
              "5206",
              "9649",
              "2702",
              "9655",
              "3005",
              "9673",
              "2701",
              "9654",
              "7601",
              "9635",
              "7602",
              "9636",
              "502",
              "5207",
              "9650",
              "5208",
              "9651",
              "5209",
              "9652",
              "1701",
              "9601",
              "2208",
              "5701",
              "9662",
              "5706",
              "1510",
              "5703",
              "5704",
              "9664",
              "5705",
              "9665",
              "1708",
              "4101",
              "9657",
              "3001",
              "9671",
              "3003",
              "9680",
              "6008",
              "9632",
              "3202",
              "1518",
              "1918",
              "2218",
              "6002",
              "9628",
              "2606",
              "2604",
              "2605"
            ],
            "type": "string",
            "description": "One of the 237 professions MQA licenses, each labelled with the board that owns it. Slice sizes measured 2026-08-12 (all statuses / practicing only): Registered Nurse 790,880 / 395,219 · Certified Nursing Assistant 484,858 / 152,572 · Licensed Practical Nurse 213,475 / 62,469 · Medical Doctor 174,575 / 91,039 · Emergency Medical Technician 161,484 / 50,538 · Registered Pharmacy Technician 137,615 / 59,709 · Massage Therapist 107,519 / 36,723 · Advanced Practice Registered Nurse 82,864 / 69,531 · Paramedic 65,416 / 39,928 · Pharmacist 60,144 / 37,204 · Physical Therapist 41,387 / 21,678 · Dental Hygienist 32,905 / 19,225 · Dentist 30,279 / 18,638. If the profession you pick belongs to a different board than the one above, the board filter is dropped and the run continues — the result set is identical either way (verified: board=\"\" + Medical Doctor returns the same 174,575 as Medicine + Medical Doctor).",
            "default": ""
          },
          "professionCustom": {
            "title": "Profession not in the list",
            "type": "string",
            "description": "Escape hatch. Overrides the dropdown when filled. Accepts a profession NAME (partial and case-insensitive, e.g. \"genetic counsel\") or its numeric code. Use it if DOH adds a profession after this build — the Actor re-reads the live profession list on every run, so a new code works here immediately even though the dropdown above has not caught up.",
            "default": ""
          },
          "county": {
            "title": "County",
            "enum": [
              "",
              "11",
              "12",
              "13",
              "14",
              "15",
              "16",
              "17",
              "18",
              "19",
              "20",
              "21",
              "22",
              "24",
              "25",
              "26",
              "27",
              "28",
              "29",
              "30",
              "31",
              "32",
              "33",
              "34",
              "35",
              "36",
              "37",
              "38",
              "39",
              "40",
              "41",
              "42",
              "43",
              "44",
              "45",
              "46",
              "47",
              "48",
              "49",
              "50",
              "51",
              "52",
              "53",
              "23",
              "54",
              "55",
              "56",
              "57",
              "58",
              "59",
              "60",
              "61",
              "62",
              "63",
              "64",
              "67",
              "68",
              "69",
              "65",
              "66",
              "70",
              "71",
              "72",
              "73",
              "74",
              "75",
              "76",
              "77"
            ],
            "type": "string",
            "description": "One of Florida's 67 counties, read live from the portal. IMPORTANT: only about 55% of licensees carry a Florida county — the rest hold a Florida license at an out-of-state address — so a county filter deliberately drops them. Measured: the 67 counties sum to 96,534 of 174,569 physicians = 55.3%. Use it when you genuinely mean \"practises in this county\", not as a way to slice the state into 67 equal parts. The county you pick is echoed onto every row; DOH prints no county anywhere in its output, so the field is null on unfiltered runs.",
            "default": ""
          },
          "city": {
            "title": "City",
            "type": "string",
            "description": "City of the address of record, spelled as DOH stores it — MIAMI, ORLANDO, TAMPA, JACKSONVILLE, GAINESVILLE. Exact match, not a prefix. Empty = everywhere.",
            "default": ""
          },
          "zipCode": {
            "title": "ZIP code",
            "type": "string",
            "description": "5-digit ZIP of the address of record, e.g. 32610. The tightest geographic filter available and the cheapest way to keep a license-depth run small. Empty = everywhere.",
            "default": ""
          },
          "lastName": {
            "title": "Last name starts with",
            "type": "string",
            "description": "Prefix match on the licensee's last name. This is also the axis the Actor uses internally to split any slice too big for the portal's CSV export: A–Z summed to 174,561 of 174,569 physicians (100.00%) and 790,805 of 790,875 registered nurses (99.99%), where county sums to 55.3% and the state's own status buckets to 99.78%.",
            "default": ""
          },
          "firstName": {
            "title": "First name starts with",
            "type": "string",
            "description": "Prefix match on the licensee's first name. Combine with lastName to find a specific person whose license number you do not have.",
            "default": ""
          },
          "businessName": {
            "title": "Business name starts with",
            "type": "string",
            "description": "Prefix match for licenses held by a FACILITY rather than a person — pharmacies, clinical labs, EMS providers, health care services pools. Measured 2026-08-12: 27,040 pharmacy-facility licenses and 279 health care services pools exist. Those rows have a business name and no first/last name.",
            "default": ""
          },
          "detailLevel": {
            "title": "How much detail per licensee",
            "enum": [
              "roster",
              "license",
              "profile"
            ],
            "type": "string",
            "description": "roster = the bulk read: license number, name, profession, city and status for the WHOLE slice in ONE request (13,853 Miami physicians arrived in a single request, verified against the portal's own count). license = also opens each licensee's verification page for address of record, original issue date, expiry date, days-until-expiry, controlled-substance and cannabis-order flags and the full disciplinary / public-complaint history — roughly one request per licensee. profile = additionally pulls the DOH Practitioner Profile for e-mail, specialty board certifications, hospital staff privileges, Medicaid participation and other-state licenses. Florida publishes that profile for physicians, PAs and ARNPs only, so on nurses, dentists and pharmacists it costs nothing extra and simply leaves those fields null. Measured on 200 practicing Gainesville physicians: e-mail 88%, hospital privileges 57%, specialty certifications 50%, other-state licenses 50%.",
            "default": "roster"
          },
          "licenseStatus": {
            "title": "License status",
            "enum": [
              "ALL",
              "ACT",
              "PREV"
            ],
            "type": "string",
            "description": "Practicing only is the default because Florida publishes an address of record ONLY for practicing licenses. Measured on a full 300-licensee run: 100% address fill on the 183 practicing rows versus 9% on the 117 non-practicing ones. ACT = Clear/Active, Obligations/Active, Conditional/Active, Probation/Active, Military Active. PREV = Null and Void, Retired, Deceased, Revoked, Vol Relinquish, Delinquent. Choose All statuses when you are credentialing and need to see the bad ones. Note the state's own two buckets do not quite sum to All — four statuses, Clear/Inactive among them, sit in neither (ACT 91,034 + PREV 83,150 = 174,184 of 174,569). A license-number lookup always searches all statuses regardless of this setting.",
            "default": "ACT"
          },
          "maxItems": {
            "title": "Max licensees (your cost cap)",
            "minimum": 1,
            "type": "integer",
            "description": "Hard cap on rows returned AND on what you are billed, at $0.003 per licensee: 100 rows = $0.30, 1,000 = $3.00, 10,000 = $30.00. Duplicates are dropped before billing and never count against it. Roster depth reaches 100,000+ rows comfortably; license and profile depth cost about one page fetch per licensee, so a run in the low thousands is the sensible ceiling there. Ships at 100 so the first click is cheap — which also means a pasted list of more than 100 license numbers stops at 100 until you raise this.",
            "default": 100
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Leave OFF. The MQA portal is public and unwalled, and proxying it only adds a failure mode. Measured ladder, 18 identical calls per rung: direct 18/18 = 100% in 28 s · Apify automatic proxy 16/18 = 88.9% in 298 s (the two failures were \"proxy responded with 590 UPSTREAM502\") · Apify residential US with a pinned session 18/18 = 100% in 98 s. Switch it on only if you need a fixed egress IP for your own network policy.",
            "default": {
              "useApifyProxy": 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}