{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Email Scraper - Role Mailboxes from Domains",
    "description": "Scrape shared role mailboxes (info@, sales@, support@) from company websites and domain lists. One row per email with the page it was found on. Personal-looking addresses dropped; $2/1,000 sites with an email, others free.",
    "version": "0.1",
    "x-build-id": "kgFsvibhOix53m2QH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~website-email-scraper-roles/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-website-email-scraper-roles",
        "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-email-scraper-roles/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-website-email-scraper-roles",
        "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-email-scraper-roles/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-website-email-scraper-roles",
        "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 one company website or domain per line, e.g. acme.com or https://www.acme.com/contact. https:// is added to bare domains; paths are extra pages and www variants count once. Only shared role mailboxes (info@, sales@, support@...) published on the website are returned. Company names without a website are free invalid_input rows unless \"Find websites for company names\" is on. Up to 50,000 per run. Or use startUrls, datasetId or rows. The two sites are an example; replace them.",
            "items": {
              "type": "string"
            }
          },
          "roleEmailsOnly": {
            "title": "Role mailboxes only (no personal emails)",
            "type": "boolean",
            "description": "On (default here): only shared role mailboxes (info@, contact@, sales@, support@, office@...) are returned and used for billing; addresses that look like a named person (anna.meier@...) are dropped before output. Off: every business email published on the website is returned, including personal-looking ones.",
            "default": true
          },
          "requiredContact": {
            "title": "Which results are charged?",
            "enum": [
              "any",
              "email"
            ],
            "type": "string",
            "description": "Choose which results are charged. \"email\" (default here): only websites where at least one email address is kept are charged; websites with only a phone number, a social profile or a personal email dropped by \"Role mailboxes only\" are still returned, but free. \"any\": a website with at least one email, phone number or social profile is charged. The price per website is the same in both modes.",
            "default": "email"
          },
          "outputMode": {
            "title": "Output format",
            "enum": [
              "sites",
              "emailRows"
            ],
            "type": "string",
            "description": "\"One row per email\" (default here) gives each mailbox its own row with the domain, whether it is a role or personal address and the page where it was found. Each website is charged once: only its first row shows charged: true. A website with a phone or social profile but no kept email gives one row with email empty. \"One row per website\" puts all emails of a site in one row; the price is the same.",
            "default": "emailRows"
          },
          "respectRobotsTxt": {
            "title": "Skip pages robots.txt disallows",
            "type": "boolean",
            "description": "On (default here): pages robots.txt disallows for our crawler (TidyToolsContacts) are skipped, and a website whose home page is disallowed is a free robots_disallowed row. Off: the websites you list are read even where their robots.txt disallows automated crawlers, as when you open them yourself. Either way every request identifies itself as TidyTools; we never log in (sign-in pages are reported as login_required, free), never solve CAPTCHAs and respect Retry-After.",
            "default": true
          },
          "startUrls": {
            "title": "Website URLs (optional)",
            "type": "array",
            "description": "The same as \"Company websites or domains\", 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": "Boolean, false by default here: a line that is a company name rather than a website or domain is a free invalid_input row. Turn it on to look company names up as websites, e.g. {\"findWebsitesForNames\":true,\"domains\":[\"Joe's Pizza, 7 Carmine St, New York, NY\"]}; put a city, address or phone on the same line, or paste tab/comma-separated columns with a Name,City,Phone header. Only verified websites are used; no verified website gives a free company_not_found row.",
            "default": false
          },
          "namesCountry": {
            "title": "Country of the company names (optional)",
            "type": "string",
            "description": "With \"Find websites for company names\" on: 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."
          },
          "datasetId": {
            "title": "Google Maps / other source dataset ID (optional)",
            "type": "string",
            "description": "Select a dataset from an earlier run (e.g. a Google Maps or directory scraper). This Actor reads websites listed in the dataset; it does not scrape Google Maps. For Maps results, it finds the website field automatically and keeps each place's name, address, phone, Maps link and placeId (placeName, placeAddress, placePhone, mapsUrl, placeId)."
          },
          "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 rows, 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
          },
          "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}