{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Contact & Email Scraper: Emails, Phones, Forms, $3/1k",
    "description": "Website contact and email scraper: paste a list of domains, get emails, phone numbers, socials, contact page URLs and contact form URLs per site. Click Start to test it: the first 2 sites in every run are free. CSV/JSON, no login. $3 per 1,000 sites with contacts. Built with AI assistance.",
    "version": "0.2",
    "x-build-id": "S7yN6vYZaRtzx0R1I"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/pennydata~website-contact-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-pennydata-website-contact-extractor",
        "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/pennydata~website-contact-extractor/runs": {
      "post": {
        "operationId": "runs-sync-pennydata-website-contact-extractor",
        "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/pennydata~website-contact-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-pennydata-website-contact-extractor",
        "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": {
          "urls": {
            "title": "URLs",
            "type": "array",
            "description": "WHAT TO PASS: a JSON array of websites, one per company, as bare domains or full URLs (strings or {\"url\": ...} objects). Example: [\"apify.com\", \"https://www.eff.org\"]. Default: 3 sample sites. Required unless you pass domains, startUrls, websites, datasetId or domainsCsvUrl. Output: one row per site (emails, phones, socials, contact page, contact form). Reads the homepage plus up to 2 contact/about pages (more with deepScan). Cost: $0.003 per site where something is found; nothing found, errors and robots.txt skips are free; first 2 sites per run free.",
            "default": [
              {
                "url": "https://www.eff.org"
              },
              {
                "url": "https://www.torproject.org"
              },
              {
                "url": "https://www.gnu.org"
              }
            ]
          },
          "respectRobotsTxt": {
            "title": "Respect robots.txt",
            "type": "boolean",
            "description": "true (default) skips pages that robots.txt disallows for all bots; skipped domains are free. Leave on unless you own the sites.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of sites analyzed in parallel (1-20). Default 5, or 10 automatically for lists of 100+ sites.",
            "default": 5
          },
          "timeoutSecs": {
            "title": "Request timeout (s)",
            "minimum": 5,
            "maximum": 60,
            "type": "integer",
            "description": "Optional. Per-request timeout in whole seconds, 5 to 60 (default 20). Raise to 40 for slow sites; leave it for normal runs.",
            "default": 20
          },
          "maxCostUsd": {
            "title": "Max cost (USD)",
            "minimum": 0,
            "type": "number",
            "description": "WHAT TO PASS: a number, the hard USD spending cap for the run. Example: 0.05 stops after about 50 billed sites. Default 5. Set it when running unattended. Cost basis: $0.001 per site where contacts are found; nothing found, errors and robots.txt skips are free; first 2 per run free. 0 charges nothing: only the 2 free sites return contacts, the rest return a free not_processed row. In contactPageOnly mode a billed site can cost up to $0.004, so the cap allows fewer sites.",
            "default": 5
          },
          "validateEmails": {
            "title": "Validate emails (syntax + MX)",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. Marks every found email with syntax_ok (valid format), mx_ok (domain has MX records) and is_deliverable_guess (both true; a guess, not a mailbox check). DNS only: no SMTP, no mail sent, 3 s timeout, one lookup per domain. Added to emailDetails (and to each row in outputMode perEmail). No extra charge.",
            "default": false
          },
          "verifyEmails": {
            "title": "Verify emails (alias of Validate emails)",
            "type": "boolean",
            "description": "Alias of validateEmails. Set true for syntax + MX check and is_deliverable_guess on every found email.",
            "default": false
          },
          "renderJs": {
            "title": "Render JavaScript when no email is found",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false, plain HTTP only). Example: true. Re-reads sites where the plain pass found no email in a headless browser (homepage + contact page) to catch emails injected by JavaScript. Only those sites are rendered. Slower (about 3-8 s per rendered site); price per site unchanged.",
            "default": false
          },
          "retryBlocked": {
            "title": "Retry blocked sites in a browser",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. When a site answers 401/403/429/503 to the plain request, re-read its homepage and contact page once in a headless browser that keeps the honest ContactExtractorBot user agent and respects robots.txt. Bot-check/captcha pages are not detected or bypassed: sites that still refuse stay blocked_403 and are not charged. Price per site unchanged (only status=found is charged).",
            "default": false
          },
          "crawl": {
            "title": "Follow contact/about pages",
            "type": "boolean",
            "description": "Compatibility with gordian/email-extractor input. true (default) also reads up to 2 same-site contact/about pages; false reads only the given pages.",
            "default": true
          },
          "findContactPages": {
            "title": "Find contact pages & forms",
            "type": "boolean",
            "description": "true (default) adds contactPages and contactForm (form URL, method, field names, captcha flag) to every row. false returns only emails, phones and socials.",
            "default": true
          },
          "email": {
            "title": "email (ignored)",
            "type": "string",
            "description": "Compatibility field from other email extractors' inputs; accepted and ignored."
          },
          "startUrls": {
            "title": "Start URLs (alias of URLs)",
            "type": "array",
            "description": "Alias of urls (for pasting other scrapers' inputs). Pass an array of strings or {\"url\": ...} objects. Example: [{\"url\": \"https://example.com\"}]. Merged with urls. Same cost per site as urls."
          },
          "datasetId": {
            "title": "Dataset ID (e.g. Google Maps scraper results)",
            "type": "string",
            "description": "WHAT TO PASS: the ID of another Apify run's dataset that lists websites, e.g. from compass/crawler-google-places. Example: \"aBcDeFgHiJkLmNoPq\". Use instead of urls; leave empty otherwise. Reads the field named in urlField (default website), dedupes by domain and skips rows that already have emails. Same cost per site as urls."
          },
          "urlField": {
            "title": "Field holding the website URL",
            "type": "string",
            "description": "Name of the dataset field that holds the website, used with Dataset ID. Defaults to `website`; `url`, `websiteUrl` and `domain` are tried as fallbacks.",
            "default": "website"
          },
          "scrapeEmails": {
            "title": "Scrape emails",
            "type": "boolean",
            "description": "false removes the emails field from the output (and email-only matches no longer count as a result for billing). Compatible with jurassic_jove/website-email-extractor.",
            "default": true
          },
          "scrapePhones": {
            "title": "Scrape phones",
            "type": "boolean",
            "description": "false removes the phones field from the output and phones no longer count as a result for billing.",
            "default": true
          },
          "scrapeSocials": {
            "title": "Scrape social links",
            "type": "boolean",
            "description": "false removes the socials field from the output and social links no longer count as a result for billing.",
            "default": true
          },
          "scrapeMessaging": {
            "title": "Messaging & community links (WhatsApp, Telegram, Discord, Snapchat, Threads, Reddit)",
            "type": "boolean",
            "description": "Also finds WhatsApp, Telegram, Discord, Snapchat, Threads and Reddit links (same field names as vdrmota/contact-info-scraper: whatsapps, telegrams, discords, snapchats, threads, reddits). Needs scrape social links on. A site with only such a link counts as a result for billing.",
            "default": true
          },
          "scrapeAddress": {
            "title": "Postal address & company name",
            "type": "boolean",
            "description": "Also returns companyName (schema.org name, og:site_name or page title), addresses and postalAddress (from JSON-LD or <address>). A site with only an address counts as a result for billing. Cloudflare-protected emails (data-cfemail) are always decoded.",
            "default": true
          },
          "timeoutPerUrl": {
            "title": "Timeout per URL (alias)",
            "minimum": 5,
            "maximum": 60,
            "type": "integer",
            "description": "Alias of \"timeoutSecs\" (jurassic_jove naming), 5-60 seconds. timeoutSecs wins if both are set."
          },
          "maxPagesPerSite": {
            "title": "Max pages per site",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Hard limit on pages fetched per website, homepage included (1-10). Default 3 (5 if deepScan is on). The price is per website, not per page, so this only bounds run time."
          },
          "maxPagesPerStartUrl": {
            "title": "Max pages per start URL (alias of maxPagesPerSite)",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Alias of maxPagesPerSite for paste-compatibility with betterdevsscrape/contact-details-extractor. maxPagesPerSite wins if both are set. Values above 10 in a pasted input should be lowered to 10."
          },
          "maxDepth": {
            "title": "maxDepth (ignored)",
            "type": "integer",
            "description": "Compatibility field from betterdevsscrape/contact-details-extractor; accepted and ignored (this Actor reads the homepage plus contact/about pages, not a deep crawl)."
          },
          "sameDomain": {
            "title": "sameDomain (ignored)",
            "type": "boolean",
            "description": "Compatibility field; accepted and ignored. This Actor only reads pages on the start URL's own domain."
          },
          "proxyConfig": {
            "title": "proxyConfig (ignored)",
            "type": "object",
            "description": "Compatibility field from betterdevsscrape/contact-details-extractor; accepted and ignored, same as proxyConfiguration (no proxy is used)."
          },
          "followLinkPages": {
            "title": "followLinkPages (ignored)",
            "type": "boolean",
            "description": "Compatibility with jurassic_jove/website-email-extractor input. false = same as crawl false (read only the given pages). Leave empty for the default. This Actor does not follow Linktree or bio-link pages; pass the real website URL instead."
          },
          "maxContactPages": {
            "title": "Max contact pages (alias)",
            "minimum": 0,
            "maximum": 9,
            "type": "integer",
            "description": "Alias for contact-page-finder input: contact/about pages read besides the homepage, i.e. maxPagesPerSite minus 1. maxPagesPerSite wins if both are set."
          },
          "datasetUrlField": {
            "title": "Dataset URL field (alias of urlField)",
            "type": "string",
            "description": "Alias of urlField for paste-compatibility; wins over urlField if set."
          },
          "phoneRegion": {
            "title": "Phone region",
            "type": "string",
            "description": "2-letter ISO-3166 country (US, GB, AU, DE...) used to read local phone numbers written without a +country prefix. Valid numbers are added as E.164 in phonesE164 (e.g. (415) 555-0100 with US becomes +14155550100); numbers that fail to parse are left out of phonesE164 only, never from phones. Empty (default) keeps current behaviour. Same as phoneCountryCode (lowest priority)."
          },
          "proxyConfiguration": {
            "title": "proxyConfiguration (ignored)",
            "type": "object",
            "description": "Compatibility field from other contact scrapers' inputs; accepted and ignored (no proxy is used)."
          },
          "proxyFallback": {
            "title": "proxyFallback (ignored)",
            "type": "boolean",
            "description": "Compatibility field; accepted and ignored."
          },
          "deepScan": {
            "title": "Deep scan",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. Reads up to 5 pages per site instead of 3, for when default runs miss contacts. No extra charge: still one event per site with results.",
            "default": false
          },
          "websites": {
            "title": "Websites (alias of URLs)",
            "type": "array",
            "description": "Alias of urls. Pass an array of strings or {\"url\": ...} objects. Example: [\"example.com\"]. Merged with urls. Same cost per site as urls."
          },
          "domains": {
            "title": "Domains (alias of URLs)",
            "type": "array",
            "description": "WHAT TO PASS: a JSON array of bare domains, same as urls. Example: [\"apify.com\", \"eff.org\", \"mozilla.org\"]. A call with only domains works. Cost: $0.001 per site where something is found; nothing found, errors and robots.txt skips are free; first 2 sites per run free."
          },
          "domainsCsvUrl": {
            "title": "Domains CSV / Google Sheet URL",
            "type": "string",
            "description": "WHAT TO PASS: one public link to a CSV or Google Sheet (published to the web or shared with anyone with the link) with one domain or URL per row. Example: \"https://docs.google.com/spreadsheets/d/<id>/export?format=csv\". Use instead of urls. Reads the first column or a column named domain, website or url; up to 5000 rows, deduplicated. Fails with a clear error if the link is not public. Same cost per site as urls."
          },
          "csvUrl": {
            "title": "CSV URL (alias of Domains CSV URL)",
            "type": "string",
            "description": "Alias of \"domainsCsvUrl\": public link to a CSV or Google Sheet with one domain or URL per row (first column, or a column named website / domain / url). domainsCsvUrl wins if both are set."
          },
          "outputXlsx": {
            "title": "Excel report (XLSX)",
            "type": "boolean",
            "description": "true also writes contacts-report.xlsx to the run's key-value store: a Summary sheet (one row per domain) and a Contacts sheet (every email, phone and social), ready to hand to a client. Default false.",
            "default": false
          },
          "crmCsv": {
            "title": "CRM import CSV",
            "enum": [
              "hubspot",
              "none"
            ],
            "type": "string",
            "description": "hubspot (default) also writes contacts.csv to the run's key-value store in HubSpot import format, one row per site with an email. none skips it.",
            "default": "hubspot"
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (alias)",
            "minimum": 5,
            "maximum": 60,
            "type": "integer",
            "description": "Alias of \"timeoutSecs\" (datagleaner naming), 5-60 seconds. timeoutSecs and timeoutPerUrl win if set."
          },
          "defaultCountry": {
            "title": "Default phone country (alias)",
            "type": "string",
            "description": "Alias of phoneCountryCode (emastra/datagleaner naming): 2-letter ISO country code, e.g. US, GB, AU."
          },
          "phoneCountryCode": {
            "title": "Phone country code",
            "type": "string",
            "description": "2-letter ISO country (US, GB, AU, DE...) used to read local phone numbers that have no +country prefix. Valid numbers are added as E.164 in phonesE164. Leave empty if sites write numbers with +CC."
          },
          "outputMode": {
            "title": "Output mode",
            "enum": [
              "perDomain",
              "perEmail"
            ],
            "type": "string",
            "description": "WHAT TO PASS: \"perDomain\" (default) or \"perEmail\". Example: \"perEmail\". perDomain gives one row per website with an emails array. perEmail gives one row per unique email with sourceUrl, isRoleAddress and phones (sites with no email still get one row). Price is the same: one event per site with results.",
            "default": "perDomain"
          },
          "contactPageOnly": {
            "title": "Contact page finder mode",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. Returns only each site's contact page URL, whether it has a contact form (contact_form, contact_form_kind, contact_form_page, contact_form_fields) and any mailto addresses on it. No phone, social or address extraction. Same column names as sandy_yclept/contact-page-finder. Cost: $0.001 per site with a contact page or form, plus $0.003 when a contact form is found ($0.004 total); other sites are free.",
            "default": false
          },
          "socialsOnly": {
            "title": "Social profiles only",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. Returns only social profile URLs (LinkedIn, Facebook, Instagram, X, YouTube, TikTok, GitHub, Pinterest) per site, no emails or phones. Cost: $0.001 per site with a social link; other sites are free.",
            "default": false
          },
          "socialOnly": {
            "title": "Social profile links only (alias of socialsOnly)",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Same as socialsOnly. Example: true. Skips email and phone extraction and returns per site only social profile links: LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub (plus Pinterest). Cost: $0.001 per site with a social link; other sites are free.",
            "default": false
          },
          "excludeDomains": {
            "title": "Exclude email domains",
            "type": "array",
            "description": "Emails on these domains (and subdomains) are dropped and input sites on them are skipped, e.g. [\"sentry.io\",\"wixpress.com\"]. Use to remove junk addresses. Leave empty for none.",
            "items": {
              "type": "string"
            }
          },
          "excludeEmailPatterns": {
            "title": "Exclude email patterns (regex)",
            "type": "array",
            "description": "Optional. Emails matching any of these regular expressions (case-insensitive, tested on the full address) are dropped, e.g. [\"^(no-?reply|donotreply)@\",\"@example\\\\.\"]. Invalid regexes are logged and ignored.",
            "items": {
              "type": "string"
            }
          },
          "extractPeople": {
            "title": "Extract people (names and job titles)",
            "type": "boolean",
            "description": "Also read team / about / leadership pages and add people[] ({name, title, email if printed}) plus primaryPersonName and primaryPersonTitle. Only what the site itself publishes; nothing is guessed. No extra charge. Business contacts only: you are responsible for lawful use (GDPR).",
            "default": false
          },
          "onlyWithEmail": {
            "title": "Only sites with an email",
            "type": "boolean",
            "description": "WHAT TO PASS: true or false (default false). Example: true. Drops sites where no email was found: no row is written and the site is not charged. Use it to get a clean lead list.",
            "default": false
          },
          "onlyMxValidEmails": {
            "title": "Only emails whose domain has MX",
            "type": "boolean",
            "description": "Drop emails whose domain has no MX record (cannot receive mail). Emails whose DNS lookup failed or timed out are kept. DNS only, no mail sent. Every email row in outputMode perEmail carries emailDomainHasMx (true / false / null when unknown) either way.",
            "default": false
          },
          "onlySiteDomainEmails": {
            "title": "Only emails on the site's own domain",
            "type": "boolean",
            "description": "Drop emails that are not on the site's own domain (free-mail like gmail, third-party agency or webmaster addresses, disposable). A site left with no email is not charged. Every email row in outputMode perEmail carries emailOnSiteDomain, isFreeProvider and isDisposable either way.",
            "default": false
          },
          "maxEmailsPerSite": {
            "title": "Max emails per site",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "WHAT TO PASS: an integer 1-1000. Example: 3. Keeps at most this many emails per site, best-ranked first (role addresses like info@/contact@ on the site's own domain, then personal, then other). Empty = no limit. Use 1-3 for outreach lists. No extra charge."
          },
          "maxSecondsPerSite": {
            "title": "Max seconds per site",
            "minimum": 5,
            "maximum": 600,
            "type": "integer",
            "description": "Wall-clock limit per website. When it is reached no further pages of that site are fetched and the row is returned with what was found so far. Default 60.",
            "default": 60
          },
          "includePaths": {
            "title": "Include paths",
            "type": "array",
            "description": "Only follow contact-page links whose path starts with one of these prefixes, e.g. [\"/contact\",\"/about\"]. Empty = all contact-like links. Built-in fallback paths (/contact, /contact-us ...) are still tried unless excluded.",
            "items": {
              "type": "string"
            }
          },
          "excludePaths": {
            "title": "Exclude paths",
            "type": "array",
            "description": "Never fetch links whose path starts with one of these prefixes, e.g. [\"/blog\",\"/careers\"]. Also applies to the built-in fallback paths. Wins over includePaths.",
            "items": {
              "type": "string"
            }
          },
          "maxRequests": {
            "title": "Max requests per run",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on total page fetches (homepages and contact pages) for the whole run. When it is reached the run stops cleanly: sites not yet processed get a status=skipped_cap row and are not charged. 0 = no cap.",
            "default": 0
          },
          "guessEmails": {
            "title": "Guess emails from names (optional mode)",
            "type": "boolean",
            "description": "true switches to the name+domain mode: give `people` ({firstName,lastName,domain}) and get ranked pattern guesses (first.last@, flast@, first@ ...) per person, cross-checked against emails the company's own site publishes. MX check only: no SMTP probing, results are guesses, not verified mailboxes. Billed $0.001 per row that has a guess (first 2 per run free). Ignores `urls`.",
            "default": false
          },
          "people": {
            "title": "People (guessEmails mode)",
            "type": "array",
            "description": "Only used with guessEmails=true. List of objects: {\"firstName\":\"Jane\",\"lastName\":\"Doe\",\"domain\":\"acme.com\"}. Rows with no valid domain or name are free."
          },
          "maxGuessesPerPerson": {
            "title": "Max guesses per person",
            "minimum": 1,
            "maximum": 12,
            "type": "integer",
            "description": "guessEmails mode: how many ranked address guesses to return per person (1-12).",
            "default": 5
          },
          "scanSiteForGuess": {
            "title": "Check the company site (guessEmails)",
            "type": "boolean",
            "description": "guessEmails mode: read the homepage and up to 2 contact pages of each domain (robots.txt respected) to confirm a guess or learn the staff address pattern. Off = pattern guesses + MX only.",
            "default": true
          },
          "considerChildFrames": {
            "title": "Read embedded iframes",
            "type": "boolean",
            "description": "Also read up to 3 embedded iframes (booking or contact widgets) on the pages visited and add their emails and phones to the row. Ads, video, maps and social widgets are skipped. Same option name as vdrmota/contact-info-scraper.",
            "default": false
          },
          "maxUrlsToCrawl": {
            "title": "Max URLs to crawl (alias of maxPagesPerSite)",
            "minimum": 1,
            "type": "integer",
            "description": "Alias of maxPagesPerSite for paste-compatibility with thenetaji/website-email-scraper. maxPagesPerSite and maxPagesPerStartUrl win if set. Capped at 10 pages per site."
          },
          "mediaType": {
            "title": "Contact type (alias)",
            "enum": [
              "all",
              "contact",
              "email",
              "phone",
              "social",
              "address"
            ],
            "type": "string",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged: limits the run to emails, phones, social links or addresses ('all' and 'contact' change nothing). Our scrape* switches still apply on top."
          },
          "maxCrawlDepth": {
            "title": "maxCrawlDepth (accepted, ignored)",
            "type": "integer",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "maxRequestRetries": {
            "title": "maxRequestRetries (accepted, ignored)",
            "type": "integer",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "maxBlockedRetries": {
            "title": "maxBlockedRetries (accepted, ignored)",
            "type": "integer",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "stayOnDomain": {
            "title": "stayOnDomain (accepted, ignored)",
            "type": "boolean",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "useStealth": {
            "title": "useStealth (accepted, ignored)",
            "type": "boolean",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "solveCloudflare": {
            "title": "solveCloudflare (accepted, ignored)",
            "type": "boolean",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "includeContactText": {
            "title": "includeContactText (accepted, ignored)",
            "type": "boolean",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "groupByPage": {
            "title": "groupByPage (accepted, ignored)",
            "type": "boolean",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used: this Actor reads the homepage plus contact and about pages, not a deep crawl."
          },
          "useProxy": {
            "title": "Proxy (accepted, ignored)",
            "type": "object",
            "description": "Accepted so inputs saved for thenetaji/website-email-scraper run unchanged. Not used."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}