{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Email Finder - Fill Missing Company Emails",
    "description": "Fill missing Email cells in a company list that already has Website and Email columns. Read public company websites, keep source row IDs, and charge only sites where an email is found. No email verification or person lookup.",
    "version": "0.1",
    "x-build-id": "PYSqkGaFimlqj7KSA"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~website-email-finder-crm/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-website-email-finder-crm",
        "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-finder-crm/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-website-email-finder-crm",
        "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-finder-crm/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-website-email-finder-crm",
        "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": {
          "rows": {
            "title": "Company rows with Website and Email columns",
            "type": "array",
            "description": "Paste company rows as JSON objects with existing Website and Email columns, e.g. [{\"row_number\":1,\"Website\":\"hofbraeuhaus.de\",\"Email\":\"\"}]. Each source row gets an output row. Only rows/dataset items with a filled Email field are skipped when Only missing emails is on; use rowId and fill from full JSON to update empty cells."
          },
          "onlyMissingEmail": {
            "title": "Only fill missing Email cells",
            "type": "boolean",
            "description": "On (default): rows or dataset items that already have an email are skipped without reading the site or charging. A plain domain list has no Email column, so its sites are processed. Off: the engine processes all source rows.",
            "default": true
          },
          "requiredContact": {
            "title": "Which results are charged?",
            "enum": [
              "any",
              "email"
            ],
            "type": "string",
            "description": "Email only (default): charge a website only when an email is found; a site with only a phone or social profile is returned free. Any contact also counts a phone or social profile. The per-site price is unchanged.",
            "default": "email"
          },
          "domains": {
            "title": "Website/domain list (advanced)",
            "type": "array",
            "description": "Optional plain list of public company websites or domains, one per line. This input has no Email column: onlyMissingEmail cannot skip a site based on a pre-existing address. Up to 50,000 per run. Invalid lines are free.",
            "items": {
              "type": "string"
            }
          },
          "datasetId": {
            "title": "Existing company dataset (advanced)",
            "type": "string",
            "description": "Read an existing dataset of company rows with a website field and, optionally, an Email field. Only rows with a filled Email field are skipped when Only fill missing Email cells is on. The Actor reads their public websites, not Google Maps itself."
          },
          "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."
          },
          "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."
          },
          "outputMode": {
            "title": "Output format",
            "enum": [
              "sites",
              "emailRows"
            ],
            "type": "string",
            "description": "Sites (default): one output row per source row, with the best email and row status. Email rows: one row per found address. Both use the same per-website billing; advanced JSON may select either mode.",
            "default": "sites"
          },
          "findWebsitesForNames": {
            "title": "Find websites for company names",
            "type": "boolean",
            "description": "Off (default): a company name without a website is a free invalid_input row. Advanced JSON can turn on the engine’s verified website lookup for names; provide a city, address or phone to disambiguate.",
            "default": false
          },
          "respectRobotsTxt": {
            "title": "Skip pages robots.txt disallows",
            "type": "boolean",
            "description": "On (default): skip pages robots.txt disallows for TidyToolsContacts. A disallowed home page returns a free robots_disallowed row. The engine identifies as TidyTools, never logs in or solves CAPTCHAs. Advanced JSON can override this setting.",
            "default": true
          },
          "roleEmailsOnly": {
            "title": "Role mailboxes only (no personal emails)",
            "type": "boolean",
            "description": "Off (default): include business emails published on the listed website, including personal-looking addresses. On: keep only shared role mailboxes such as info@ or sales@. Do not use this Actor to make person-based lists.",
            "default": false
          },
          "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"
                }
              }
            }
          },
          "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"
            }
          },
          "mapsData": {
            "title": "Pasted Google Maps JSON or CSV (optional)",
            "type": "string",
            "description": "Alternative to rows or datasetId: paste a Maps JSON array, an object with items, or CSV with a website column. A datasetId takes precedence over sample pasted data."
          },
          "mapsPlaceRows": {
            "title": "Google Maps place view (optional)",
            "type": "boolean",
            "description": "Return CRM-ready place columns and preserve each original Maps item in source. Default off leaves this Actor's existing output unchanged.",
            "default": false
          },
          "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."
          },
          "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}