{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Tech Stack Detector: CMS, Analytics, Hosting & Email",
    "description": "What any website runs on: CMS, e-commerce, analytics, frameworks, CDN, hosting and email provider. Up to 10,000 domains per run from a list, CSV, Google Sheet or another Actor's dataset. Filter by technology and track stack changes between runs. Failed or blocked sites are free.",
    "version": "0.2",
    "x-build-id": "Mng1tJGvyWRjDVRYB"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/folt~tech-stack-detector/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-folt-tech-stack-detector",
        "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/folt~tech-stack-detector/runs": {
      "post": {
        "operationId": "runs-sync-folt-tech-stack-detector",
        "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/folt~tech-stack-detector/run-sync": {
      "post": {
        "operationId": "run-sync-folt-tech-stack-detector",
        "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": "Domains or URLs",
            "type": "array",
            "description": "Websites to analyze, one per line: a domain (example.com — its homepage is analyzed) or a full URL (https://example.com/shop — that page is analyzed). Up to 10,000 per run; duplicates are removed. IP addresses and internal hostnames are not accepted. You can also (or instead) import websites from a file or a dataset below.",
            "items": {
              "type": "string"
            }
          },
          "checkDns": {
            "title": "Check DNS (email provider, DNS provider, SaaS verifications)",
            "type": "boolean",
            "description": "Looks up the domain's MX, NS, TXT and SOA records (and the CNAME of the website host) to detect the email provider (Google Workspace, Microsoft 365…), email security gateway, DNS provider, hosting, and SaaS tools that verified the domain (e.g. Atlassian, Stripe, HubSpot).",
            "default": true
          },
          "includeEvidence": {
            "title": "Include evidence",
            "type": "boolean",
            "description": "Adds to every technology the signals that matched (header, script URL, meta tag, DNS record…). Useful to audit results; makes the output larger.",
            "default": false
          },
          "domainsFileUrl": {
            "title": "Domains file (CSV / TXT link or Google Sheets link)",
            "type": "string",
            "description": "Public link to a CSV or TXT file, or a Google Sheets link (share the sheet as \"Anyone with the link can view\"; the tab in the link is used). The column named domain, website, url or homepage is used (or a header containing one of these words, e.g. \"Company Website\"); otherwise the first column. Comma, semicolon and tab separated files work. Max 5 MB and 10,000 rows. Excel files (.xlsx) must be exported as CSV first. The file host's robots.txt is respected."
          },
          "datasetId": {
            "title": "Dataset with websites (e.g. Google Maps Scraper output)",
            "type": "string",
            "description": "An Apify dataset whose items contain websites, for example the output of a Google Maps, LinkedIn company or lead-list scraper run. The Actor only reads it. The first 10,000 items are used; items without a website are skipped, and social-media profile links (Facebook, Instagram, LinkedIn…) are reported as invalid instead of being analyzed."
          },
          "datasetField": {
            "title": "Dataset field with the website",
            "type": "string",
            "description": "Name of the item field that holds the website. Leave empty to detect it: the first of domain, website, url, homepage (case-insensitive) that has a value. A list value uses its first text entry."
          },
          "onlyWithTechnologies": {
            "title": "Only output domains using these technologies",
            "type": "array",
            "description": "Technology or category names exactly as they appear in the output (case does not matter), e.g. Shopify, WordPress, HubSpot, Microsoft 365, or a category such as Ecommerce, CMS, Live chat. A domain is output when it uses any of them. You pay per analyzed domain; the filter only trims the output, so filtered-out domains are still charged. Unknown names are reported in the log; if none of the names is known, the run stops before analyzing anything.",
            "items": {
              "type": "string"
            }
          },
          "monitorChanges": {
            "title": "Monitor technology changes",
            "type": "boolean",
            "description": "Remembers each domain's technologies between runs and adds changeStatus (new / changed / unchanged), technologiesAdded and technologiesRemoved to every record. The first run marks every domain as new. Technologies with confidence below 50 are ignored, and DNS-only technologies are compared only when both runs had Check DNS on.",
            "default": false
          },
          "stateKey": {
            "title": "Monitoring name",
            "pattern": "^[a-zA-Z0-9!_.'()-]{0,100}$",
            "type": "string",
            "description": "Runs with the same name compare against each other; use a different name for each list you monitor (letters, digits and ! - _ . ' ( ), up to 100 characters). Empty means \"default\". The memory is kept in your account's key-value store \"tech-stack-detector-state\"; a domain not seen for 180 days is forgotten."
          },
          "outputOnlyChanges": {
            "title": "Output only new and changed domains",
            "type": "boolean",
            "description": "With Monitor technology changes on, writes only domains whose stack is new or changed to the dataset. Unchanged, failed and blocked domains are counted in the run SUMMARY only. You pay per analyzed domain: unchanged domains are still charged even though they are not output.",
            "default": false
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "How many websites to analyze in parallel. Higher values finish large lists faster; the default memory (1 GB) is enough. Values below 10 are raised to 10.",
            "default": 20
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}