{
  "openapi": "3.0.1",
  "info": {
    "title": "AI Web Scraper - Extract Structured Data & URL to JSON",
    "description": "AI scraper and AI extractor: list the fields or describe what you want, and an LLM reads each page and returns JSON. No selectors or code. One row per list item, follows detail links. $0.01/page.",
    "version": "0.1",
    "x-build-id": "VSqnnITzLag0W3V5w"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/tidytools~ai-web-data-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-tidytools-ai-web-data-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/tidytools~ai-web-data-extractor/runs": {
      "post": {
        "operationId": "runs-sync-tidytools-ai-web-data-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/tidytools~ai-web-data-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-tidytools-ai-web-data-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 or domains",
            "type": "array",
            "description": "Main input (fill this, or `startUrls` / `datasetId`). Pages to extract data from (product pages, job posts, articles, company pages, listing pages...). One per line; full URLs or bare domains such as stripe.com. A line that is not a URL becomes one free error row; the rest of the run continues.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "URLs (request list, optional)",
            "type": "array",
            "description": "Same as \"URLs or domains\", in Apify's request list format (also accepts a link to a text file with URLs). Kept for existing integrations; new integrations should use \"urls\".",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "preset": {
            "title": "Ready-made fields",
            "enum": [
              "property",
              "hotel",
              "menu"
            ],
            "type": "string",
            "description": "Optional: property listing, hotel page, or your own restaurant menu. Selecting one supplies the fields and row mode automatically. Extra Fields are merged; your types win. Leave unselected for the existing behavior. Use only websites you own or may access."
          },
          "fields": {
            "title": "Fields to extract",
            "type": "object",
            "description": "Field name → type (string, number, integer, boolean, array). Example: {\"product_name\": \"string\", \"price\": \"number\", \"in_stock\": \"boolean\"}. Missing values come back as null. With a preset, clear the sample Fields unless you want to add or override columns; otherwise leave empty to let the AI pick fields from your instructions."
          },
          "instructions": {
            "title": "Instructions (or just a prompt)",
            "type": "string",
            "description": "Plain-language hints for the AI, e.g. \"Prices in USD, without currency symbol\". With no Fields and no JSON Schema, write what you want (\"Get every product with its name, price and rating\"): the AI designs the fields from the first page, keeps them for the whole run and saves them as SCHEMA in the key-value store."
          },
          "prompt": {
            "title": "Prompt (same as Instructions)",
            "type": "string",
            "description": "Same as \"Instructions\"; used only when Instructions is empty. Lets you paste the input JSON of Apify's AI Web Scraper (`startUrls` + `prompt`) and run it unchanged. Its crawl options (extractionMode scout/agentic, maxPagesToVisit, maxCrawlDepth) are ignored: only the start URLs are read, or turn on \"Follow links to detail pages\"."
          },
          "outputMode": {
            "title": "Output",
            "enum": [
              "page",
              "items"
            ],
            "type": "string",
            "description": "\"One row per page\": one data object per URL. \"One row per item\": for listing pages (products, jobs, search results, team members), every item on the page becomes its own row with url and itemIndex. Still charged per page. Values: page = One row per page; items = One row per item on the page (lists).",
            "default": "page"
          },
          "flatOutput": {
            "title": "Flat columns (for Google Sheets, n8n, CSV)",
            "type": "boolean",
            "description": "Put every extracted field in its own column instead of inside \"data\". Nested objects become columns joined with _ (price.amount → price_amount), lists of values become one text cell (\"red, blue\"), lists of objects become a JSON text cell. Every row has the same columns in the same order, failed pages included (empty values, recordCount 0). recordIndex is the item's position on the page and the page title is in pageTitle. Same number of rows and same price as without it.",
            "default": false
          },
          "followLinks": {
            "title": "Follow links to detail pages",
            "type": "boolean",
            "description": "Treat the start URLs as list pages (category, search results, index): read each one for free, then extract data from the pages it links to (e.g. every product page). The start page itself is not extracted. Each extracted page is charged as usual.",
            "default": false
          },
          "linkPattern": {
            "title": "Link pattern",
            "type": "string",
            "description": "Which links to follow. A glob such as https://books.toscrape.com/catalogue/*/index.html (* = any text within one path segment, ** = across segments), or plain text the link must contain, such as /product/. Separate several with commas. Empty = every link to the same site (menus included, so a pattern is recommended)."
          },
          "maxPagesPerStartUrl": {
            "title": "Max pages per start URL",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "At most this many linked pages are extracted from each start page (in page order). Caps the cost.",
            "default": 20
          },
          "jsonSchema": {
            "title": "JSON Schema (advanced)",
            "type": "object",
            "description": "Optional full JSON Schema (type: object) for nested output. When set, it replaces \"Fields\". In item mode it describes one item."
          },
          "datasetId": {
            "title": "Dataset ID (optional)",
            "type": "string",
            "description": "Read the URLs from another Actor run's dataset, e.g. a crawler or a search results scraper. Values that are not URLs are extracted from as text."
          },
          "datasetField": {
            "title": "Dataset field",
            "type": "string",
            "description": "Field with the URLs, e.g. \"url\" or \"website\" (dot paths such as \"company.url\" work). Empty = the first URL field found."
          },
          "mode": {
            "title": "Page fetching (HTTP or browser)",
            "enum": [
              "auto",
              "fast",
              "browser"
            ],
            "type": "string",
            "description": "\"Auto\" reads pages over plain HTTP and switches to a real browser when a site blocks it or needs JavaScript. Values: auto = Auto (recommended); fast = Fast (HTTP only); browser = Browser (JavaScript rendering).",
            "default": "auto"
          },
          "cssSelector": {
            "title": "Content selector (CSS)",
            "type": "string",
            "description": "Optional. Only read this part of each page, e.g. \"main\". Helps with very long pages."
          },
          "maxConcurrency": {
            "title": "Parallel pages",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many pages are processed at the same time.",
            "default": 5
          },
          "itemTimeoutSecs": {
            "title": "Time limit per page (seconds)",
            "minimum": 0,
            "maximum": 900,
            "type": "integer",
            "description": "A page that takes longer (reading + AI) is stopped and returned as a free error row with errorType \"timeout\". In list mode, the items from the parts that finished in time are kept. 0 = no limit.",
            "default": 180
          },
          "aiModel": {
            "title": "AI model",
            "enum": [
              "auto",
              "llama-3.3-70b",
              "qwen3-30b",
              "llama-4-scout"
            ],
            "type": "string",
            "description": "Same price for every model. Auto uses Llama 3.3 70B for one row per page and Qwen3 30B for list pages (one row per item), where it writes long lists about 3 times faster with the same accuracy in our tests.",
            "default": "auto"
          },
          "httpVia": {
            "title": "Plain HTTP requests from",
            "enum": [
              "auto",
              "backend",
              "direct",
              "vm"
            ],
            "type": "string",
            "description": "Some sites block requests from data centers. Auto retries from a second network before falling back to a real browser. If both are refused, Auto also tries our second server (Oracle, different IP) before a real browser.",
            "default": "auto"
          },
          "proxyConfiguration": {
            "title": "Proxy (optional)",
            "type": "object",
            "description": "Only used for requests sent from Apify's network. Apify proxy usage is billed to your Apify account."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}