{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Contact Extractor — Bulk Company Domains",
    "description": "Extract public company website emails, phone numbers and social links from bulk domain lists or a source dataset. One site result by default; $0.002 per site with a contact, free when none is found.",
    "version": "0.1",
    "x-build-id": "HAPvSCSWNwJweP2Lt"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~website-contact-extractor-bulk/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-website-contact-extractor-bulk",
        "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/tidytools~website-contact-extractor-bulk/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-website-contact-extractor-bulk",
        "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/tidytools~website-contact-extractor-bulk/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-website-contact-extractor-bulk",
        "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": {
          "domains": {
            "title": "Company websites or domains",
            "type": "array",
            "description": "Paste public company websites or domains, one per line (for example hofbraeuhaus.de). Bare domains are accepted; paths are extra pages and www variants count once. With the default name lookup off, company-name lines return free invalid_input rows. Up to 50,000 sites per run. You can also select a source dataset below.",
            "items": {
              "type": "string"
            }
          },
          "datasetId": {
            "title": "Source dataset ID (optional)",
            "type": "string",
            "description": "Select a readable dataset containing public company website/domain fields. The website field is detected automatically; use Dataset field if needed. Source rows without a usable website are free. This Actor reads the listed websites; it does not scrape a directory or Google Maps itself."
          },
          "requiredContact": {
            "title": "Which results are charged?",
            "enum": [
              "any",
              "email"
            ],
            "type": "string",
            "description": "Choose which results are charged. \"any\" (default): a website with at least one email, phone number or social profile. \"email\": only websites where at least one email address is found are charged; websites with only a phone number or social profile are still returned, but free. The price per website is the same in both modes.",
            "default": "any"
          },
          "outputMode": {
            "title": "Output format",
            "enum": [
              "sites",
              "emailRows"
            ],
            "type": "string",
            "description": "\"One row per email\" splits each website into one row per email found, with the company name, primary phone, social profiles, the page where the email was found and whether it is on the website's own domain. The price is the same: each website is charged once (only its first row shows charged: true). A website with a phone or social profile but no email gives one row with email empty.",
            "default": "sites"
          },
          "respectRobotsTxt": {
            "title": "Skip pages robots.txt disallows",
            "type": "boolean",
            "description": "On by default: pages robots.txt disallows for TidyToolsContacts are skipped; a site whose home page is disallowed gets a free robots_disallowed row. If explicitly switched off, the engine may read user-supplied pages even where robots.txt disallows them. Requests still identify the crawler, do not log in or solve CAPTCHAs, and respect Retry-After.",
            "default": true
          },
          "startUrls": {
            "title": "Website URLs (optional)",
            "type": "array",
            "description": "The same as \"Websites or company names\", as a URL list; you can also upload or link a text/CSV file of websites. Bare domains belong in the list above (this editor rejects them).",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "findWebsitesForNames": {
            "title": "Find websites for company names",
            "type": "boolean",
            "description": "Off by default: company-name lines are free invalid_input rows; supply websites or domains. Advanced JSON can explicitly set true to use the engine's verified company-name website lookup. Add city, address or phone for better matching; names without a verified site get free company_not_found rows.",
            "default": false
          },
          "namesCountry": {
            "title": "Country of the company names (optional)",
            "type": "string",
            "description": "2-letter country code (e.g. DE, GB, JP) so that company names are first tried on that country's domains (.de, .co.uk, .co.jp) before .com. Empty = .com, .io, .co."
          },
          "datasetField": {
            "title": "Dataset field",
            "type": "string",
            "description": "Field (or \"rows\" column) with the website or domain, e.g. \"website\" (dot paths such as \"company.url\" work). Empty = found automatically: website, then url, domain, link... A field that only holds Google Maps links (the \"url\" of a Maps place) is skipped, so Google Maps results need no setting."
          },
          "datasetKeepFields": {
            "title": "Dataset fields to keep",
            "type": "array",
            "description": "Extra fields copied from each dataset item into the output's \"source\" object, e.g. totalScore, reviewsCount. Google Maps results already get flat place columns (placeName, placeAddress, placePhone, mapsUrl, placeId, placeCategory, placeCity, placeCountryCode) without this setting.",
            "items": {
              "type": "string"
            }
          },
          "rows": {
            "title": "Rows from a spreadsheet or CRM (API / n8n / Make)",
            "type": "array",
            "description": "Instead of a dataset: the rows of your sheet as JSON objects, e.g. [{\"row_number\": 2, \"Website\": \"acme.com\", \"Email\": \"\"}]. The website column is found automatically (Website, url, domain...) or set it in \"Dataset field\". Every row keeps its identifier (rowId) and gets its own output row, so you can write the result back to the same row."
          },
          "rowIdField": {
            "title": "Row identifier field",
            "type": "string",
            "description": "Field that identifies each row of the dataset or \"rows\" (returned as rowId). Empty = the first of rowId, row_number, placeId, id; otherwise the row position. Branches of a chain that share one website are read once but keep their own rowId."
          },
          "emailField": {
            "title": "Email column",
            "type": "string",
            "description": "Field with the email you already have (Email, emails, primaryEmail... are found automatically). Used by \"Only rows without an email\" and for \"fill\": the found email is only offered for rows where this field is empty, so your own values are never overwritten."
          },
          "phoneField": {
            "title": "Phone column",
            "type": "string",
            "description": "Field with the phone you already have (found automatically). The found phone is only put in \"fill\" when it is empty."
          },
          "onlyMissingEmail": {
            "title": "Only rows without an email",
            "type": "boolean",
            "description": "With a dataset or \"rows\": rows that already have an email are not read and not charged (they get one row with emailStatus already_had_email).",
            "default": false
          },
          "roleEmailsOnly": {
            "title": "Role mailboxes only (no personal emails)",
            "type": "boolean",
            "description": "Off (default): every business email published on the website is returned, including addresses that look like a named person (anna.meier@...). On: only shared role mailboxes (info@, contact@, sales@, support@, office@...) are returned and used for billing; personal-looking addresses are dropped before output.",
            "default": false
          },
          "dedupeStoreName": {
            "title": "Skip websites read in earlier runs (dedupe name)",
            "type": "string",
            "description": "Any name, e.g. \"my-lead-list\". Websites (by domain) read in an earlier run with the same name are not read or charged again: the earlier result is returned with fromPreviousRun. Kept in a key-value store \"contacts-<name>\" in your Apify account. Failed websites are not kept, so they are tried again. Empty = off."
          },
          "dedupeMaxAgeDays": {
            "title": "Reuse earlier results for (days)",
            "minimum": 0,
            "maximum": 3650,
            "type": "integer",
            "description": "With a dedupe name: results older than this are read again. 0 = no age limit.",
            "default": 90
          },
          "maxPagesPerSite": {
            "title": "Pages per website",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "The home page plus likely contact pages (contact, imprint/Impressum, about, team, support, legal). When those show no email, pages left over go to other pages likely to name a mailbox (policies, catering, jobs, locations...). The price per website is the same however many pages are read.",
            "default": 8
          },
          "excludePaths": {
            "title": "Pages not to read (paths)",
            "type": "array",
            "description": "Optional JSON array of site paths beginning with /, e.g. {\"excludePaths\":[\"/blog\",\"/privacy\"]}; enter one per line in the form. /blog excludes /blog/... but not /blogger; matching ignores case and query strings. Home pages and URLs you explicitly give are still read. Empty means no exclusion. A non-path entry causes a free invalid_input row and stops reading.",
            "items": {
              "type": "string"
            }
          },
          "maxConcurrency": {
            "title": "Parallel websites",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many websites are processed at the same time (each reads up to 2 pages at once).",
            "default": 10
          },
          "siteTimeoutSecs": {
            "title": "Time limit per website (seconds)",
            "minimum": 20,
            "maximum": 900,
            "type": "integer",
            "description": "After this time no further pages of a website are started and the pages read so far are returned (skipped pages are listed in timedOutPages). If even the home page is not read by then, the website fails (not charged).",
            "default": 120
          },
          "httpVia": {
            "title": "Plain HTTP requests from",
            "enum": [
              "auto",
              "backend",
              "direct",
              "vm"
            ],
            "type": "string",
            "description": "Some sites block requests from data centers. Auto retries from a second network before falling back to a real browser. If those routes are refused, Auto also tries our second server (Oracle, different IP) before a real browser.",
            "default": "auto"
          },
          "proxyConfiguration": {
            "title": "Proxy (optional)",
            "type": "object",
            "description": "Only used for requests sent from Apify's network. Apify proxy usage is billed to your Apify account."
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}