{
  "openapi": "3.0.1",
  "info": {
    "title": "Contact Details Scraper: Pay Per Site, Not Page",
    "description": "Extract website emails and contact details, and pay once per site with contacts, not per page read: phones, social profiles, company name, address, contact form and the page each value came from, one row per site. A site with no contacts comes back free and says why.",
    "version": "0.1",
    "x-build-id": "O8sgFOLnuCzA4jCck"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/pradio~website-email-phone/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-pradio-website-email-phone",
        "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/pradio~website-email-phone/runs": {
      "post": {
        "operationId": "runs-sync-pradio-website-email-phone",
        "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/pradio~website-email-phone/run-sync": {
      "post": {
        "operationId": "run-sync-pradio-website-email-phone",
        "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",
        "required": [
          "startUrls",
          "proxyConfig"
        ],
        "properties": {
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "the websites to read, one URL per site; each site returns one row of the contacts it publishes, or a status row saying why it could not. A social network's page (Facebook, LinkedIn, Instagram and the like) is not read: it comes back as a free bad_input row",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "defaultCountry": {
            "title": "Default country for phone numbers",
            "type": "string",
            "description": "Two-letter country code (US, GB, DE...) used to read phone numbers written without a country code. Leave empty to take the country from each site: its country domain (.de, .co.uk), its page language, or, when neither says, the country at least two thirds of its own international numbers share. Numbers that cannot be placed are kept as published when a tel: link or structured data carries them; in plain page text only a North American shape or a national 0 is kept."
          },
          "maxRequestsPerStartUrl": {
            "title": "Max Requests Per Start URL",
            "minimum": 1,
            "maximum": 25,
            "type": "integer",
            "description": "the most requests made to one site, counting the start page, the contact pages it leads to and, with useSitemap on, the sitemap (default 8, at most 25)",
            "default": 8
          },
          "mergeContacts": {
            "title": "Merge Contacts",
            "type": "boolean",
            "description": "on: every page a site answers folds into one row per site; off: one row per fetched page"
          },
          "maxDepth": {
            "title": "Max Depth",
            "minimum": 0,
            "maximum": 2,
            "type": "integer",
            "description": "how far to follow the site's own links looking for contact pages. 0 reads the start page alone, 1 the start page plus the pages it links to, 2 one step further (default 1, at most 2)",
            "default": 1
          },
          "maxRequests": {
            "title": "Max Requests",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "a fetch cap shared across the whole run, robots.txt reads included; leave unset for the most allowed, 100,000. A site the budget does not reach comes back as a free aborted row"
          },
          "sameDomain": {
            "title": "Same Domain",
            "type": "boolean",
            "description": "on (default): only follow links on the site's own host; off: also follow links to the same site's other subdomains (shop., careers.). Links to another site are never followed."
          },
          "considerChildFrames": {
            "title": "Consider Child Frames",
            "type": "boolean",
            "description": "also read same-host embedded frames: contacts living inside an iframe on the page"
          },
          "useBrowser": {
            "title": "Render JavaScript sites in a browser",
            "type": "boolean",
            "description": "Off by default. When a page answers with an empty app shell (the content is drawn by JavaScript), open it in a headless browser and read the rendered page. With mergeContacts on, a site that read fine but published no email, phone or contact form also gets one browser pass on its likeliest page before it is judged. Slower, and it needs more memory: run with 2048 MB or more. A site that refuses the request (401, 403, 429) or shows a challenge page is never rendered; it stays blocked.",
            "default": false
          },
          "waitUntil": {
            "title": "Browser wait",
            "enum": [
              "domcontentloaded",
              "load",
              "networkidle"
            ],
            "type": "string",
            "description": "Only used with useBrowser on. The load event the browser pass waits for before it reads a rendered page: domcontentloaded reads as soon as the HTML is parsed (the default), load waits for scripts and images, networkidle waits for the network to go quiet. A site whose contacts arrive late may read better on a longer wait.",
            "default": "domcontentloaded"
          },
          "includeUrlPatterns": {
            "title": "Only visit pages matching",
            "type": "array",
            "description": "Regular expressions matched against each internal page path, for example /locations/ or /imprint. When set, the crawl visits the site pages whose path matches one of them instead of the contact pages it would pick by itself, still within maxRequestsPerStartUrl, on the site's own host and never where robots.txt disallows. The start URL is always read.",
            "items": {
              "type": "string"
            }
          },
          "excludeUrlPatterns": {
            "title": "Never visit pages matching",
            "type": "array",
            "description": "Regular expressions matched against each internal page path, for example /careers or /blog/. A matching page is never requested.",
            "items": {
              "type": "string"
            }
          },
          "useSitemap": {
            "title": "Find contact pages in the sitemap",
            "type": "boolean",
            "description": "Off by default. Also read the site's sitemap.xml (the one robots.txt names on the site's own host, else /sitemap.xml) for contact, about and imprint pages the navigation does not link, and visit those first. The sitemap counts toward maxRequestsPerStartUrl, and a page robots.txt disallows is never requested.",
            "default": false
          },
          "verifyEmails": {
            "title": "Check e-mail domains (MX)",
            "type": "boolean",
            "description": "Off by default; the Console's example ticks it. Check each e-mail found: is it well formed, and does its domain publish mail servers (MX records)? The answer lands in emails_verified. A DNS lookup only: no mail server is contacted and nothing is sent.",
            "default": false
          },
          "scrapeSocialMediaProfiles": {
            "title": "Networks to Extract",
            "type": "object",
            "description": "per-network switches for the social links read off each site, for example {\"tiktoks\": false}; {\"enabled\": false} reads none. A network set to false is not extracted; unset reads them all. This picks which links are collected from the site's own pages; it does not look up or enrich the profiles"
          },
          "proxyConfig": {
            "title": "Proxy Config",
            "type": "object",
            "description": "Apify proxy settings for the fetches, used as you configure them. Whatever proxy you choose, a site that refuses a request (401, 403, 429 or a challenge page) comes back as a free blocked row and is not asked again in the run: never retried through another proxy, session, user agent or browser.",
            "default": {
              "useApifyProxy": true
            }
          },
          "maxItems": {
            "title": "Maximum items",
            "minimum": 1,
            "maximum": 10000,
            "type": "integer",
            "description": "the most rows one run returns (at most 10,000). The dataset simply ends at that many rows, with no extra row; RUN_SUMMARY in the key-value store shows rowsFetched beside rowsPushed, so you can see how many were left",
            "default": 100
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}