{
  "openapi": "3.0.1",
  "info": {
    "title": "Tech Stack Enrichment - Website Technology Scanner, DNS + HTML",
    "description": "293 technology detections on 10 sites against 69 from a rival Actor, ahead on all 10. Bulk tech stack lookup from the page and DNS: 428 technologies in 46 categories with confidence and evidence. Technographic data, Wappalyzer alternative, no API key. Detects frameworks and hosting.",
    "version": "0.1",
    "x-build-id": "0ivrHovLW7EpXScf0"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/snow_leo_data~tech-stack-detector/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-snow_leo_data-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/snow_leo_data~tech-stack-detector/runs": {
      "post": {
        "operationId": "runs-sync-snow_leo_data-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/snow_leo_data~tech-stack-detector/run-sync": {
      "post": {
        "operationId": "run-sync-snow_leo_data-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": {
          "urls": {
            "title": "Websites",
            "type": "array",
            "description": "Websites to analyse. A bare domain is enough ('stripe.com'); full URLs, {\"url\": ...} objects, and comma or newline separated lists all work, and an email address is reduced to its domain. The same list is also accepted under startUrls, domains, websites, targetUrls, url, domain and website, so output from another Actor can be pasted in unchanged.",
            "default": [
              "stripe.com",
              "shopify.com",
              "nytimes.com"
            ],
            "items": {
              "type": "string"
            }
          },
          "inputDatasetId": {
            "title": "Input dataset ID (optional)",
            "type": "string",
            "description": "Take the list of websites from an existing Apify dataset instead of typing it. Use this to chain after a Google Maps, company list or lead scraper."
          },
          "urlField": {
            "title": "Website field name",
            "type": "string",
            "description": "Which field of the input dataset holds the website address. Only used together with Input dataset ID.",
            "default": "url"
          },
          "includeDns": {
            "title": "Detect DNS-layer technologies",
            "type": "boolean",
            "description": "Read MX, NS, SPF, TXT, CAA and DMARC records as well as the page. This is where mail hosting, SSO, e-signature, DMARC monitoring and dozens of internal SaaS tools become visible - none of them ever appear in the HTML. Turning it off makes a run faster and blinder.",
            "default": true
          },
          "includeTls": {
            "title": "Read the TLS certificate",
            "type": "boolean",
            "description": "One extra handshake per host: names the certificate authority, the TLS version and the expiry date.",
            "default": true
          },
          "checkDkim": {
            "title": "Probe known DKIM selectors",
            "type": "boolean",
            "description": "Ask for 16 well-known DKIM selectors (google, selector1, k1, s1, pm ...). It proves which mail sender actually signs the domain's email, at the cost of 16 extra DNS lookups per site. Off by default because on a list of a thousand domains that is sixteen thousand extra lookups.",
            "default": false
          },
          "categoriesFilter": {
            "title": "Only these categories",
            "type": "array",
            "description": "Keep only technologies in these categories, for example CMS, Ecommerce, Analytics, CDN, Payment Processors, Email Hosting, SaaS Vendors. Leave empty for all of them. A category that does not exist is reported back instead of silently emptying the run.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "onlyWithTechnologies": {
            "title": "Only sites using",
            "type": "array",
            "description": "Keep a site only if it uses at least one of these technologies. Matching is by substring, so 'shopify' also keeps Shopify Plus and Shopify Hydrogen. Empty means keep every site.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "excludeTechnologies": {
            "title": "Exclude sites using",
            "type": "array",
            "description": "Drop a site if it uses any of these technologies. Useful for 'WordPress sites that are not on WooCommerce yet'.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minConfidence": {
            "title": "Minimum confidence",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Drop detections below this confidence. A response header scores 100, a cookie or meta generator 95, a script URL 90, a match in the page body 85, and a technology only implied by another one 60. Set 90 to keep only hard evidence.",
            "default": 0
          },
          "onlyChanged": {
            "title": "Monitor mode: only report changes",
            "type": "boolean",
            "description": "Remember every site between runs and deliver a row only when its technology set is new or has changed. Each row then also carries technologies_added and technologies_removed. Put the Actor on a schedule with this on and you pay for changes, not for the same answer every day.",
            "default": false
          },
          "emitUnchanged": {
            "title": "Monitor mode: also emit unchanged sites",
            "type": "boolean",
            "description": "Keep the run memory and the NEW / UPDATED / UNCHANGED label, but deliver every site anyway.",
            "default": false
          },
          "includeConfidence": {
            "title": "Include confidence scores",
            "type": "boolean",
            "description": "Add a 0-100 confidence to every detected technology.",
            "default": true
          },
          "includeVersions": {
            "title": "Extract version numbers",
            "type": "boolean",
            "description": "Parse a version out of the matched header, script URL or meta generator when the source really states one. Left null otherwise - an invented version is worse than none.",
            "default": true
          },
          "includeEvidence": {
            "title": "Include the evidence",
            "type": "boolean",
            "description": "Add the exact header, cookie, script URL, DNS record or HTML fragment each detection came from, so every row can be checked by hand.",
            "default": true
          },
          "includeSecurityHeaders": {
            "title": "Include security headers",
            "type": "boolean",
            "description": "Add HSTS, CSP, X-Frame-Options and the other security headers the site sends.",
            "default": true
          },
          "includeHeaders": {
            "title": "Include all response headers",
            "type": "boolean",
            "description": "Add the first 40 raw response headers to each row.",
            "default": false
          },
          "compactOutput": {
            "title": "Compact output (for AI agents)",
            "type": "boolean",
            "description": "Return only url, domain, status, technology names, categories and the counts. Measured on nytimes.com: 11 120 bytes per row full, 1 910 bytes compact.",
            "default": false
          },
          "dropEmptyFields": {
            "title": "Drop empty fields",
            "type": "boolean",
            "description": "Leave out fields that are null or empty, for loading straight into a database.",
            "default": false
          },
          "concurrency": {
            "title": "Parallel sites",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "How many sites to scan at once. Each worker is one site, and every host is rate-limited separately, so raising this does not hammer any single server.",
            "default": 8
          },
          "timeoutSeconds": {
            "title": "HTTP timeout (seconds)",
            "minimum": 3,
            "maximum": 60,
            "type": "integer",
            "description": "Per-request timeout. Raise it for slow sites.",
            "default": 20
          },
          "maxItems": {
            "title": "Maximum rows",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many rows have been DELIVERED, not after this many sites have been looked at - so a filter cannot turn a limit of 30 into an empty dataset. 0 means no limit.",
            "default": 0
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}