{
  "openapi": "3.0.1",
  "info": {
    "title": "Arizona ROC Contractor License Scraper",
    "description": "Scrape Arizona Registrar of Contractors (AZ ROC) public license records. Search by license number, business name, qualifying party, or city. Returns license status, classifications, bonds, complaints, personnel, address, phone — fast, no login.",
    "version": "1.0",
    "x-build-id": "uwuS6io5To1wTTToq"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/muhammadafzal~az-roc-contractor-license-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-muhammadafzal-az-roc-contractor-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/muhammadafzal~az-roc-contractor-license-scraper/runs": {
      "post": {
        "operationId": "runs-sync-muhammadafzal-az-roc-contractor-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/muhammadafzal~az-roc-contractor-license-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-muhammadafzal-az-roc-contractor-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",
            "type": "array",
            "description": "One or more AZ ROC license numbers to look up directly (e.g. '123456'). Fastest and most precise search method — direct single-record lookup, no pagination. Leading zeros are handled automatically. Use this field when the user provides exact license numbers or a list of licenses to verify. Do NOT use this when the user describes a trade, region, or company name — use companyNames, qualifyingPartyNames, or cities instead.",
            "items": {
              "type": "string"
            },
            "default": [
              "333282"
            ]
          },
          "companyNames": {
            "title": "Company / Business Names",
            "type": "array",
            "description": "Business names to search (e.g. 'Desert HVAC', 'Acme Plumbing'). Partial matches are supported by the AZ ROC portal. Each name triggers a separate search and may return multiple results across multiple pages — all are traversed automatically. Use this field when the user provides company names. Do NOT use this for license-number lookups — use licenseNumbers instead.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "qualifyingPartyNames": {
            "title": "Qualifying Party Names",
            "type": "array",
            "description": "Full name of the qualifying party (the individual responsible for the license). Format: 'First Last' (e.g. 'John Smith'). Partial names are accepted by the AZ ROC portal. Use this field when the user provides a person's name rather than a company name. Do NOT use this for business-name searches — use companyNames instead.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "cities": {
            "title": "Cities",
            "type": "array",
            "description": "Arizona city names to search by location (e.g. 'Phoenix', 'Tucson', 'Scottsdale', 'Mesa'). Each city triggers a separate search and may return thousands of records across many pages — all are traversed. Combine with licenseType, licenseStatus, or licenseClassification filters to narrow. Use this field when the user wants contractors by region or for building territory-based lead lists. Do NOT use this for a single license lookup — use licenseNumbers instead.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "licenseType": {
            "title": "License Type",
            "enum": [
              "ALL",
              "RESIDENTIAL",
              "COMMERCIAL",
              "DUAL"
            ],
            "type": "string",
            "description": "Filter results by license type. 'ALL' returns all types. 'RESIDENTIAL' covers home construction/repair. 'COMMERCIAL' covers non-residential projects. 'DUAL' covers both. Applied as a client-side filter on the AZ ROC portal's results. Use this to narrow city or company searches to a license category.",
            "default": "ALL"
          },
          "licenseStatus": {
            "title": "License Status Filter",
            "enum": [
              "ALL",
              "ACTIVE",
              "SUSPENDED",
              "EXPIRED",
              "REVOKED",
              "CANCELLED"
            ],
            "type": "string",
            "description": "Filter by license status. 'ALL' returns every record regardless of standing. 'ACTIVE' returns only contractors currently authorized to work — the common choice for lead-generation and insurance use cases. Applied post-scrape since the AZ ROC portal uses a single text-search field.",
            "default": "ALL"
          },
          "licenseClassification": {
            "title": "License Classification",
            "type": "string",
            "description": "Optional classification code to filter results (e.g. 'B-1', 'R-11', 'C-37', 'CR-39'). Leave blank to include all classifications. Find all codes at https://roc.az.gov/license-classifications. Applied post-scrape — the portal's search is text-based and may return broader results, which are then narrowed in the output.",
            "default": ""
          },
          "scrapeDetailPage": {
            "title": "Scrape Full Detail Page",
            "type": "boolean",
            "description": "When enabled, the scraper opens each contractor's detail page to collect complete information including bond details, all license classifications, complaint history, and qualifying party details. This is much slower (one extra page load per contractor), so it is OFF by default — the fast list view already returns license number, business name, qualifying party, classification, status, city, phone, and profile URL. Turn this ON only when you need bond and complaint data.",
            "default": false
          },
          "scrapeComplaints": {
            "title": "Include Complaint History",
            "type": "boolean",
            "description": "When enabled (requires Scrape Full Detail Page), fetches the per-complaint records (date, type, status, summary) in addition to the aggregate complaint count. Only complaints from the prior two years are shown on the AZ ROC portal. OFF by default to keep runs fast and cheap.",
            "default": false
          },
          "maxResults": {
            "title": "Max Results (total)",
            "minimum": 0,
            "maximum": 1000000,
            "type": "integer",
            "description": "Hard cap on the total number of records pushed to the dataset across all search jobs. Protects against accidental large runs — billing is per record pushed. Start low (10-50) to validate output quality before scaling up. Set to 0 for unlimited (use with caution on city searches, which can return thousands of records and unexpected billing).",
            "default": 100
          },
          "resultsPerPage": {
            "title": "Results Per Page",
            "enum": [
              "10",
              "20",
              "50"
            ],
            "type": "string",
            "description": "Number of rows per DOM page on the AZ ROC portal. Valid values are 10, 20, or 50 (as offered by the native page-size selector). 50 minimises the number of Next clicks required and is fastest.",
            "default": "50"
          },
          "maxConcurrency": {
            "title": "Max Concurrent Browsers",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of browser tabs running in parallel. Higher values speed up bulk runs but increase memory and proxy usage. Recommended: 2-5 for residential proxies. Keep ≤ 5 to avoid triggering Salesforce bot protection.",
            "default": 3
          },
          "customProxyUrl": {
            "title": "Custom Proxy URL",
            "type": "string",
            "description": "Optional premium residential proxy URL (e.g. 'http://user:pass@proxy.decodo.com:10000'). The AZ ROC portal uses Salesforce bot protection which can challenge Apify's shared datacenter and residential IPs. For production bulk runs, provide your own premium residential proxy (Decodo/Bright Data/IPRoyal) for maximum reliability. If left blank, the actor uses Apify residential proxy automatically.",
            "default": ""
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Apify proxy settings. Residential proxy is strongly recommended — the AZ ROC portal uses Salesforce bot protection which can challenge datacenter IP pools."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}