{
  "openapi": "3.0.1",
  "info": {
    "title": "Website Technology Detector — Tech Stack Lookup",
    "description": "Find out what any website runs on. One row per site: CMS, e-commerce platform, JavaScript framework, analytics, ad pixels, live chat, payments, CDN, hosting, web server and security, each with the evidence that proved it. 232 signatures, no API key, no browser.",
    "version": "0.1",
    "x-build-id": "ZBDsZfIaVT4Vka68b"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/insight.solutions~website-tech-detector/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-insight.solutions-website-tech-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/insight.solutions~website-tech-detector/runs": {
      "post": {
        "operationId": "runs-sync-insight.solutions-website-tech-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/insight.solutions~website-tech-detector/run-sync": {
      "post": {
        "operationId": "run-sync-insight.solutions-website-tech-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",
        "required": [
          "websites"
        ],
        "properties": {
          "websites": {
            "title": "Websites",
            "type": "array",
            "description": "One entry per site. A bare domain is enough — `allbirds.com` — and so is a full URL. Each domain is tried on `https://`, then `https://www.`, then plain `http://`, so a host that only answers on one of them still gets read. A URL with a real path is fetched exactly as given, which is how you point the Actor at a product page instead of a home page. Email addresses and IP addresses are rejected for free. Duplicates are read, and billed, once.",
            "items": {
              "type": "string"
            }
          },
          "extraPages": {
            "title": "Extra pages per site",
            "minimum": 0,
            "maximum": 3,
            "type": "integer",
            "description": "How many internal pages to read *in addition to* the entry page, taking the shallowest internal links first. Zero — the default — reads the home page only, which is where the overwhelming majority of a site's stack declares itself. Raise it to 1 or 2 when you are looking for something that only loads deeper: a review widget on a product page, a checkout provider, a booking form. Each extra page costs a request and a little time; it never costs an extra `site` charge.",
            "default": 0
          },
          "rowPerTechnology": {
            "title": "One row per technology",
            "type": "boolean",
            "description": "Off by default: each site is one row, with the full detection list inside `technologies`. Turn it on and every detection also gets its own flat row — `name`, `category`, `version`, `confidence`, `evidence` — which is the shape you want for a pivot table, a warehouse load, or \"show me every site in this list running Klaviyo\". The `site` rows are still written, first. Per-technology rows are billed at $0.0001 each.",
            "default": false
          },
          "categories": {
            "title": "Only these categories",
            "type": "array",
            "description": "Leave empty for everything. Pick one or more categories and the rows carry only those — useful when you are qualifying leads on one axis (\"which of these 4,000 shops are on Shopify\") and do not want the other 200 signatures in your export. The flat columns follow the filter: filter to CMS only and `security`, `payments` and the rest come back empty.",
            "items": {
              "type": "string",
              "enum": [
                "CMS",
                "E-commerce",
                "JavaScript framework",
                "UI framework",
                "Analytics",
                "Tag manager",
                "Advertising",
                "Marketing automation",
                "Live chat",
                "Payments",
                "CDN",
                "Hosting",
                "Web server",
                "Programming language",
                "Security",
                "Cookie consent",
                "A/B testing",
                "Site search",
                "Forms",
                "Video",
                "Maps",
                "Fonts",
                "Media and images",
                "Monitoring",
                "Reviews",
                "Miscellaneous"
              ],
              "enumTitles": [
                "CMS",
                "E-commerce",
                "JavaScript framework",
                "UI framework",
                "Analytics",
                "Tag manager",
                "Advertising and pixels",
                "Marketing automation",
                "Live chat and support",
                "Payments",
                "CDN",
                "Hosting",
                "Web server",
                "Programming language",
                "Security and bot management",
                "Cookie consent",
                "A/B testing",
                "Site search",
                "Forms",
                "Video",
                "Maps",
                "Fonts",
                "Media and images",
                "Monitoring",
                "Reviews",
                "Miscellaneous"
              ]
            },
            "default": []
          },
          "minConfidence": {
            "title": "Minimum confidence",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Drop detections scored below this. Confidence is not a guess about how popular a product is — it is how good the evidence was. A response header or a cookie the server set scores 100; a script URL 95–100; a `<meta name=\"generator\">` 90; an attribute or class-name shape 75; a string in the page body 80; a global named in inline JavaScript 60. Something added only because another detection implies it scores 70. The default of 50 keeps everything; raise it to 90 for a list you are going to act on without reading.",
            "default": 50
          },
          "maxConcurrency": {
            "title": "Sites in parallel",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many sites are read at once. Each parallel worker keeps its own proxy session, so a site that refuses one exit IP does not burn the address the others are using. Five is a good citizen against a list of unrelated domains; raise it for a large list, lower it if you are sending many hostnames that share one origin.",
            "default": 5
          },
          "maxRunSecs": {
            "title": "Maximum run time (seconds)",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "Wall-clock budget for the whole run. When it is reached the Actor stops starting new sites, keeps and bills for every row it already wrote, and files a free diagnostic row for each site it never reached. Nothing is charged for work that did not happen.",
            "default": 240
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Ordinary websites do not refuse datacenter address ranges the way the big platforms do, so the default is Apify's datacenter proxy and its cost is already inside the per-site price. If you are fingerprinting sites behind an aggressive bot wall, switch the group to RESIDENTIAL here and nothing else changes — sessions still rotate automatically when an exit IP is refused. Clearing the field sends requests from the run's own address.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}