{
  "openapi": "3.0.3",
  "info": {
    "title": "QuanticData API",
    "version": "1.0",
    "description": "REST API for scrape, SERP, map, crawl, batch, SEO audit, collectors and\nproxy generation (list plans, generate endpoint strings, whitelist IPs, geo).\nOne host, one Bearer key, one JSON envelope. Failed Data API calls are never billed.\n$2 free every month, no card. PAYG is 60 requests per minute.\n\nCanonical HTML reference: https://quanticdata.io/docs/\nMarkdown twin: https://quanticdata.io/docs/index.md\n",
    "contact": {
      "name": "QuanticData",
      "email": "hello@quanticdata.io",
      "url": "https://quanticdata.io/"
    },
    "termsOfService": "https://quanticdata.io/terms/"
  },
  "externalDocs": {
    "description": "API reference",
    "url": "https://quanticdata.io/docs/"
  },
  "servers": [
    {
      "url": "https://api.quanticdata.io",
      "description": "Primary"
    },
    {
      "url": "https://app.quanticdata.io/api",
      "description": "App-host fallback (same API)"
    }
  ],
  "tags": [
    {
      "name": "Scrape"
    },
    {
      "name": "SERP"
    },
    {
      "name": "Map"
    },
    {
      "name": "Crawl"
    },
    {
      "name": "Batch"
    },
    {
      "name": "SEO audit"
    },
    {
      "name": "Collectors"
    },
    {
      "name": "Proxies"
    },
    {
      "name": "AI",
      "description": "Prompt-guided extraction and AI-enriched search"
    },
    {
      "name": "Unlocker",
      "description": "Hard targets through the unblocking pipeline"
    },
    {
      "name": "Datasets",
      "description": "AI dataset builder"
    },
    {
      "name": "Parser",
      "description": "Reusable, self-healing extraction schemas"
    },
    {
      "name": "Account",
      "description": "Usage and billing, read-only"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/scrape": {
      "post": {
        "tags": [
          "Scrape"
        ],
        "operationId": "scrape",
        "summary": "Scrape one page",
        "description": "One URL through the residential pool, returned as Markdown, HTML or text.\nStarts on a TLS-fingerprint tier and escalates to a stealth browser only on a block,\nor when you set render true. Alias path: POST /v1/scraper/extract.\nList price $0.0002 per page, $0.001 when rendered.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrapeRequest"
              },
              "example": {
                "url": "https://example.com",
                "format": "markdown"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extraction successful (or type error in the envelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScrapeEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/extract": {
      "post": {
        "tags": [
          "Scrape"
        ],
        "operationId": "scrapeAlias",
        "summary": "Scrape one page (alias)",
        "description": "Same as POST /v1/scrape.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrapeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extraction successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScrapeEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/serp": {
      "post": {
        "tags": [
          "SERP"
        ],
        "operationId": "serp",
        "summary": "Search engine results",
        "description": "Google, Bing or DuckDuckGo as JSON. 17 verticals on Google.\nAlias POST /v1/scraper/serp. List price from $0.0005 ($0.002 rendered).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SerpRequest"
              },
              "example": {
                "query": "best coffee grinder",
                "engine": "google",
                "country": "us"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SERP successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SerpEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/serp": {
      "post": {
        "tags": [
          "SERP"
        ],
        "operationId": "serpAlias",
        "summary": "Search engine results (alias)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SerpRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SERP successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SerpEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/map": {
      "post": {
        "tags": [
          "Map"
        ],
        "operationId": "mapSite",
        "summary": "List URLs on a site",
        "description": "Every URL of a site (sitemaps + homepage links), no page bodies. $0.0005 per site. Alias POST /v1/scraper/map.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MapRequest"
              },
              "example": {
                "url": "https://example.com",
                "limit": 100
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Map successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MapEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/map": {
      "post": {
        "tags": [
          "Map"
        ],
        "operationId": "mapSiteAlias",
        "summary": "List URLs on a site (alias)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MapRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Map successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MapEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/crawl": {
      "post": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlStart",
        "summary": "Start an async crawl",
        "description": "BFS from a seed URL (cap 500 pages, depth 10). Charged up front; unfetched pages refunded. $0.0003 per page. Alias POST /v1/scraper/crawl.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CrawlRequest"
              },
              "example": {
                "url": "https://example.com",
                "limit": 20,
                "depth": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Crawl started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrawlStartEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/crawl/{jobId}": {
      "get": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlStatus",
        "summary": "Poll a crawl job",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          },
          {
            "$ref": "#/components/parameters/includeContent"
          },
          {
            "$ref": "#/components/parameters/since"
          }
        ],
        "responses": {
          "200": {
            "description": "Job snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrawlPollEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlCancel",
        "summary": "Cancel a running crawl",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/crawl": {
      "post": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlStartAlias",
        "summary": "Start an async crawl (alias)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CrawlRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Crawl started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrawlStartEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/crawl/{jobId}": {
      "get": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlStatusAlias",
        "summary": "Poll a crawl job (alias)",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          },
          {
            "$ref": "#/components/parameters/includeContent"
          },
          {
            "$ref": "#/components/parameters/since"
          }
        ],
        "responses": {
          "200": {
            "description": "Job snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CrawlPollEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Crawl"
        ],
        "operationId": "crawlCancelAlias",
        "summary": "Cancel a running crawl (alias)",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/batch": {
      "post": {
        "tags": [
          "Batch"
        ],
        "operationId": "batchStart",
        "summary": "Scrape a list of known URLs",
        "description": "Up to 5,000 known URLs, async. Charged up front; failed share refunded. $0.0002 per URL. Alias POST /v1/scraper/batch.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "example": {
                "urls": [
                  "https://example.com",
                  "https://example.org"
                ],
                "format": "markdown"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/batch/{jobId}": {
      "get": {
        "tags": [
          "Batch"
        ],
        "operationId": "batchStatus",
        "summary": "Poll a batch job",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          },
          {
            "$ref": "#/components/parameters/includeContent"
          }
        ],
        "responses": {
          "200": {
            "description": "Job snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/batch": {
      "post": {
        "tags": [
          "Batch"
        ],
        "operationId": "batchStartAlias",
        "summary": "Scrape a list of known URLs (alias)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch started",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/batch/{jobId}": {
      "get": {
        "tags": [
          "Batch"
        ],
        "operationId": "batchStatusAlias",
        "summary": "Poll a batch job (alias)",
        "parameters": [
          {
            "$ref": "#/components/parameters/jobId"
          },
          {
            "$ref": "#/components/parameters/includeContent"
          }
        ],
        "responses": {
          "200": {
            "description": "Job snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/seo-audit": {
      "post": {
        "tags": [
          "SEO audit"
        ],
        "operationId": "seoAudit",
        "summary": "No-JS vs rendered audit",
        "description": "Fetches twice (pure HTTP and fully rendered) and returns both views plus the diff. $0.0012 per URL. Alias POST /v1/scraper/seo-audit.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SeoAuditRequest"
              },
              "example": {
                "url": "https://example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SEO audit successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SeoAuditEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/seo-audit": {
      "post": {
        "tags": [
          "SEO audit"
        ],
        "operationId": "seoAuditAlias",
        "summary": "No-JS vs rendered audit (alias)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SeoAuditRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SEO audit successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SeoAuditEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/collectors": {
      "get": {
        "tags": [
          "Collectors"
        ],
        "operationId": "listCollectors",
        "summary": "Catalog of ready-made scrapers",
        "description": "74 collectors with input_schema, examples, health and unit price. Catalog call is free.",
        "responses": {
          "200": {
            "description": "Catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/collectors/{slug}": {
      "get": {
        "tags": [
          "Collectors"
        ],
        "operationId": "getCollector",
        "summary": "One collector schema",
        "parameters": [
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "responses": {
          "200": {
            "description": "Collector",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/collectors/{slug}/run": {
      "post": {
        "tags": [
          "Collectors"
        ],
        "operationId": "runCollector",
        "summary": "Run a collector",
        "description": "Body is the collector's semantic input (never a URL list). Billed per delivered result, from $0.0005.",
        "parameters": [
          {
            "$ref": "#/components/parameters/slug"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectorRunRequest"
              },
              "example": {
                "query": "pizza restaurants",
                "location": "Brooklyn, NY",
                "country": "us",
                "max_results": 20
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Run complete",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectorRunEnvelope"
                }
              }
            }
          },
          "202": {
            "description": "Run accepted (async)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/collectors/runs": {
      "get": {
        "tags": [
          "Collectors"
        ],
        "operationId": "listCollectorRuns",
        "summary": "Your collector runs",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/collectors/runs/{runId}": {
      "get": {
        "tags": [
          "Collectors"
        ],
        "operationId": "getCollectorRun",
        "summary": "One collector run",
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run payload or CSV",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectorRunEnvelope"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/proxies": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "listProxies",
        "summary": "List proxy plans",
        "description": "List the account's proxy services (Residential Basic/Premium/Private, Mobile, Mobile V2, Datacenter, ISP, IPv6) with orderId, bandwidth left, expiry and whitelist. Use orderId on generate.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/planTypeQuery"
          },
          {
            "name": "active",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true = non-expired only; false = expired only; omit for all."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plan list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/proxies/generate": {
      "post": {
        "tags": [
          "Proxies"
        ],
        "operationId": "generateProxies",
        "summary": "Generate proxy endpoint strings",
        "description": "Ready-to-use proxy strings (credentials included) from an active plan. Same key as the Data API. Requires an orderId from GET /v1/public/proxies.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateProxiesRequest"
              },
              "example": {
                "orderId": "your_order_id",
                "protocol": "http",
                "format": "user:pass@host:port",
                "quantity": 10,
                "country": "us",
                "rotation": "rotating"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Proxy strings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateProxiesEnvelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/proxies/whitelist-ip": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "listWhitelistIp",
        "summary": "List whitelisted IPs",
        "description": "IP-auth whitelist for Residential Basic, Datacenter, ISP, IPv6, Mobile. Residential Premium/Private use user:pass and do not need this.",
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Whitelist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "Proxies"
        ],
        "operationId": "addWhitelistIp",
        "summary": "Whitelist an IP",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WhitelistIpRequest"
              },
              "example": {
                "orderId": "your_order_id",
                "ip": "203.0.113.7"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Whitelisted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "tags": [
          "Proxies"
        ],
        "operationId": "removeWhitelistIp",
        "summary": "Remove a whitelisted IP",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orderId",
                  "ip"
                ],
                "properties": {
                  "orderId": {
                    "type": "string"
                  },
                  "ip": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string",
                    "description": "Mobile also accepts an entry id."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Removed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/proxies/ip-info": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyIpInfo",
        "summary": "Look up an exit IP",
        "description": "Sticky sessions only. Rotating mode has no stable IP to look up.",
        "parameters": [
          {
            "name": "ip",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "IP to look up (?ip=x.x.x.x)."
          }
        ],
        "responses": {
          "200": {
            "description": "Geo of the IP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/geo/countries": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyGeoCountries",
        "summary": "Countries for a plan type",
        "parameters": [
          {
            "$ref": "#/components/parameters/planTypeRequired"
          }
        ],
        "responses": {
          "200": {
            "description": "Country list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/geo/states": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyGeoStates",
        "summary": "States/regions for a country",
        "parameters": [
          {
            "$ref": "#/components/parameters/planTypeRequired"
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "State list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/geo/cities": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyGeoCities",
        "summary": "Cities for a country",
        "parameters": [
          {
            "$ref": "#/components/parameters/planTypeRequired"
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "City list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/geo/asns": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyGeoAsns",
        "summary": "ASNs for targeting",
        "description": "Residential Basic and Datacenter Basic.",
        "parameters": [
          {
            "$ref": "#/components/parameters/planTypeRequired"
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ASN list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/geo/locations": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "proxyGeoLocations",
        "summary": "Full location tree (Residential Premium)",
        "parameters": [
          {
            "name": "planType",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "residentialpremium"
              ]
            },
            "description": "Only residentialpremium is supported."
          }
        ],
        "responses": {
          "200": {
            "description": "Location tree",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/generator/residential-premium/targeting-options": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "targetingResidentialPremium",
        "summary": "Residential Premium targeting tree",
        "responses": {
          "200": {
            "description": "Country → region → city → ISP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/generator/mobile/targeting-options": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "targetingMobile",
        "summary": "Mobile targeting tree",
        "responses": {
          "200": {
            "description": "Country → region → city → ISP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/public/generator/datacenter/targeting-options": {
      "get": {
        "tags": [
          "Proxies"
        ],
        "operationId": "targetingDatacenter",
        "summary": "Datacenter gateway list",
        "responses": {
          "200": {
            "description": "Static datacenter gateways",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/scraper/ai": {
      "post": {
        "tags": [
          "AI"
        ],
        "operationId": "aiAgent",
        "summary": "Prompt-guided extraction (AI Agent)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "schema": {
                    "type": "object",
                    "description": "Optional output shape"
                  }
                },
                "required": [
                  "url",
                  "prompt"
                ]
              },
              "example": {
                "url": "https://example.com/pricing",
                "prompt": "Extract every plan with name and monthly price"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Structured extraction result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/places-ai": {
      "post": {
        "tags": [
          "AI"
        ],
        "operationId": "placesAi",
        "summary": "Places by intent (AI-enriched local search)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string"
                  },
                  "location": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ]
              },
              "example": {
                "query": "specialty coffee",
                "location": "Milan, Italy",
                "country": "it"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Places with contact fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/shopping-ai": {
      "post": {
        "tags": [
          "AI"
        ],
        "operationId": "shoppingAi",
        "summary": "Shopping results by intent (AI-enriched)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  }
                },
                "required": [
                  "query"
                ]
              },
              "example": {
                "query": "espresso machine under 200",
                "country": "us"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Priced product results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/unlock": {
      "post": {
        "tags": [
          "Unlocker"
        ],
        "operationId": "unlockRequest",
        "summary": "Fetch a hard target through the unblocking pipeline — browser fingerprint, fresh-exit retries, headless-browser escalation (billed per GB)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Target URL"
                  },
                  "method": {
                    "type": "string",
                    "default": "GET",
                    "description": "Non-idempotent methods are sent exactly once (never retried)"
                  },
                  "headers": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Your own client's headers. Identity headers are replaced by the fingerprint's; auth/cookie/content-type/custom headers pass through"
                  },
                  "body": {
                    "type": "string",
                    "description": "Request body as UTF-8 text (use this OR bodyBase64)"
                  },
                  "bodyBase64": {
                    "type": "string",
                    "description": "Request body as base64, for binary payloads"
                  },
                  "country": {
                    "type": "string",
                    "description": "ISO 2-letter exit country (default: us)"
                  },
                  "state": {
                    "type": "string"
                  },
                  "city": {
                    "type": "string"
                  },
                  "rotation": {
                    "type": "string",
                    "enum": [
                      "rotating",
                      "sticky"
                    ],
                    "default": "rotating"
                  },
                  "sessionId": {
                    "type": "string",
                    "description": "Sticky session id — reuse it to keep one exit IP"
                  },
                  "sessionDuration": {
                    "type": "integer",
                    "description": "Sticky session lifetime in minutes (3–1440)"
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "premium",
                      "mobile"
                    ],
                    "default": "premium",
                    "description": "Which prepaid balance and exit pool serves the request"
                  },
                  "tlsProfile": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox",
                      "safari",
                      "safari_ios",
                      "edge",
                      "brave",
                      "mobile"
                    ]
                  },
                  "mobile": {
                    "type": "boolean",
                    "description": "Mobile Safari fingerprint (not the mobile exit pool — see tier)"
                  },
                  "render": {
                    "oneOf": [
                      {
                        "type": "string",
                        "enum": [
                          "html",
                          "png"
                        ]
                      },
                      {
                        "type": "boolean"
                      }
                    ],
                    "description": "'html'/'png'/true: run the page in a headless browser from the start (GET/HEAD only). false: TLS tier only, no escalation"
                  },
                  "autoRender": {
                    "type": "boolean",
                    "default": true,
                    "description": "Escalate a GET that every TLS attempt found blocked to a real browser"
                  },
                  "keepHeaders": {
                    "type": "boolean",
                    "default": false,
                    "description": "Send your identity headers verbatim instead of the fingerprint's"
                  },
                  "successStatusCodes": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    },
                    "description": "Origin statuses to accept as success — never treated as a block, never retried"
                  },
                  "timeoutMs": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 120000,
                    "default": 45000
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://www.example.com/product/123",
                "country": "us",
                "render": "html"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The origin's response plus unlock metadata. `blocked: true` means every tier came back with a challenge; `usage.bytes` is the traffic debited (all attempts).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer",
                      "description": "The origin's status code"
                    },
                    "headers": {
                      "type": "object"
                    },
                    "body": {
                      "type": "string",
                      "description": "UTF-8 text when the response is texty"
                    },
                    "bodyBase64": {
                      "type": "string"
                    },
                    "finalUrl": {
                      "type": "string"
                    },
                    "contentType": {
                      "type": "string",
                      "nullable": true
                    },
                    "profile": {
                      "type": "string",
                      "description": "TLS fingerprint that served the request"
                    },
                    "attempts": {
                      "type": "integer",
                      "description": "Attempts across every tier, browser escalation included"
                    },
                    "blocked": {
                      "type": "boolean"
                    },
                    "blockReason": {
                      "type": "string"
                    },
                    "rendered": {
                      "type": "boolean",
                      "description": "A headless browser produced the page"
                    },
                    "escalated": {
                      "type": "boolean",
                      "description": "The browser was tried because the TLS tier was blocked"
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "premium",
                        "mobile"
                      ]
                    },
                    "geo": {
                      "type": "object"
                    },
                    "usage": {
                      "type": "object",
                      "properties": {
                        "bytes": {
                          "type": "integer"
                        },
                        "unlock_gb_remaining": {
                          "type": "number"
                        },
                        "unlock_gb_purchased": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "402": {
            "description": "The tier's prepaid GB balance is exhausted or expired — buy more unlocker GB",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Replays your request (method, headers, body) through a residential exit under a real browser TLS fingerprint. A blocked GET is retried on a fresh exit under a different fingerprint family, then rendered by a real headless browser; every tier's output is verified, so a challenge page is reported as blocked:true. Billing is per GB moved through the exit, every attempt included (retries, blocked pages, the browser's page load), as the network meters it. No country means a US exit. The forward-proxy form of the same engine is unlock.quantumproxies.io:9000 (proxy sub-user credentials from the dashboard)."
      }
    },
    "/v1/scraper/serp/bulk": {
      "post": {
        "tags": [
          "SERP"
        ],
        "operationId": "serpBulk",
        "summary": "Async batch of SERP queries — returns a job id",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "queries": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "google",
                      "bing",
                      "duckduckgo"
                    ]
                  }
                },
                "required": [
                  "queries"
                ]
              },
              "example": {
                "queries": [
                  {
                    "query": "web scraping api"
                  },
                  {
                    "query": "serp api"
                  }
                ],
                "engine": "google"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted (job_id)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/serp/bulk/{jobId}": {
      "get": {
        "tags": [
          "SERP"
        ],
        "operationId": "serpBulkStatus",
        "summary": "SERP bulk job status & results",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status, results when done",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "tags": [
          "SERP"
        ],
        "operationId": "serpBulkCancel",
        "summary": "Cancel a SERP bulk job",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/datasets": {
      "post": {
        "tags": [
          "Datasets"
        ],
        "operationId": "datasetCreate",
        "summary": "Describe a table — the AI builds and fills it (per delivered row)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "request": {
                    "type": "string",
                    "description": "What the table should contain"
                  },
                  "max_rows": {
                    "type": "integer"
                  }
                },
                "required": [
                  "request"
                ]
              },
              "example": {
                "request": "All SaaS companies in Italy with a public pricing page: name, domain, starting price",
                "max_rows": 200
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dataset job (job_id) or rows when small",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "get": {
        "tags": [
          "Datasets"
        ],
        "operationId": "datasetList",
        "summary": "List your dataset jobs",
        "responses": {
          "200": {
            "description": "Dataset jobs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/datasets/{jobId}": {
      "get": {
        "tags": [
          "Datasets"
        ],
        "operationId": "datasetStatus",
        "summary": "Dataset job status & summary",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status, row count, schema",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "tags": [
          "Datasets"
        ],
        "operationId": "datasetDelete",
        "summary": "Delete a dataset job",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/datasets/{jobId}/download": {
      "get": {
        "tags": [
          "Datasets"
        ],
        "operationId": "datasetDownload",
        "summary": "Download dataset rows",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rows, in the requested format",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/parser/generate": {
      "post": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserGenerate",
        "summary": "Generate a reusable extraction schema for a page layout",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "instructions": {
                    "type": "string"
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://example-shop.com/product/123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parser schema (replay it free on matching pages)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/parser/presets": {
      "get": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresets",
        "summary": "List saved parser presets",
        "responses": {
          "200": {
            "description": "Presets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetSave",
        "summary": "Save a parser preset",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "schema": {
                    "type": "object"
                  }
                },
                "required": [
                  "name",
                  "schema"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/parser/presets/{id}": {
      "get": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetGet",
        "summary": "Read a preset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "put": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetUpdate",
        "summary": "Update a preset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "schema": {
                    "type": "object"
                  }
                },
                "required": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetDelete",
        "summary": "Delete a preset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/parser/presets/{id}/heal": {
      "post": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetHeal",
        "summary": "Self-heal a preset against a changed layout",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Healed schema",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/scraper/parser/presets/{id}/stats": {
      "get": {
        "tags": [
          "Parser"
        ],
        "operationId": "parserPresetStats",
        "summary": "Preset usage & success stats",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "usage",
        "summary": "Your Data API usage by day and tool",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                30,
                90
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Daily usage + totals",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/scraper/billing": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "billing",
        "summary": "Live prices, your tier and free-tier status",
        "responses": {
          "200": {
            "description": "Billing status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "qd_live_",
        "description": "Authorization Bearer qd_live_… One key covers Data APIs and proxy generation."
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Fallback if you cannot set Authorization. Do not put the key in the query string."
      }
    },
    "parameters": {
      "jobId": {
        "name": "jobId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "slug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "google_maps_places"
      },
      "includeContent": {
        "name": "include_content",
        "in": "query",
        "schema": {
          "type": "boolean"
        },
        "description": "false for a light status check; true for page bodies."
      },
      "since": {
        "name": "since",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Cursor / timestamp for incremental crawl polls."
      },
      "planTypeQuery": {
        "name": "planType",
        "in": "query",
        "schema": {
          "$ref": "#/components/schemas/PlanType"
        },
        "description": "Only services of this plan type."
      },
      "planTypeRequired": {
        "name": "planType",
        "in": "query",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/PlanType"
        }
      }
    },
    "responses": {
      "Error": {
        "description": "Envelope type error. Never billed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit. Back off on Retry-After.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait"
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      }
    },
    "schemas": {
      "Envelope": {
        "type": "object",
        "required": [
          "type",
          "message"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "response",
              "error"
            ]
          },
          "message": {
            "type": "string"
          },
          "payload": {
            "type": "object"
          },
          "pagination": {
            "type": "object"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "type",
          "message"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "error"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "cost_usd": {
            "type": "number"
          },
          "free_usd": {
            "type": "number"
          },
          "paid_usd": {
            "type": "number"
          }
        }
      },
      "ScrapeRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "description": "Page to fetch (http/https). Optional when you pass html."
          },
          "html": {
            "type": "string",
            "description": "Convert markup you already have (max 5MB). No fetch, no proxy bandwidth."
          },
          "format": {
            "type": "string",
            "enum": [
              "markdown",
              "html",
              "text",
              "raw"
            ],
            "default": "markdown"
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "render": {
            "type": "boolean",
            "default": false
          },
          "engine": {
            "type": "string",
            "enum": [
              "auto",
              "tls",
              "fetch",
              "render"
            ],
            "default": "auto"
          },
          "mobile": {
            "type": "boolean",
            "default": false
          },
          "screenshot": {
            "description": "true = viewport PNG, fullPage = whole page. Render mode.",
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string",
                "enum": [
                  "fullPage"
                ]
              }
            ]
          },
          "country": {
            "type": "string",
            "description": "ISO country code for the proxy exit."
          },
          "state": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "rotation": {
            "type": "string",
            "enum": [
              "rotating",
              "sticky"
            ],
            "default": "rotating"
          },
          "sessionId": {
            "type": "string",
            "maxLength": 64
          },
          "sessionDuration": {
            "type": "number",
            "default": 10,
            "minimum": 3,
            "maximum": 1440
          },
          "contentMode": {
            "type": "string",
            "enum": [
              "smart",
              "article",
              "full"
            ],
            "default": "smart"
          },
          "content_mode": {
            "type": "string",
            "description": "Alias of contentMode."
          },
          "include_links": {
            "type": "boolean",
            "default": false
          },
          "includeLinks": {
            "type": "boolean"
          },
          "waitMs": {
            "type": "number",
            "maximum": 15000
          },
          "waitForSelector": {
            "type": "string"
          },
          "scrollToBottom": {
            "type": "boolean",
            "default": false
          },
          "actions": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "xhr": {
            "type": "boolean",
            "default": false
          },
          "extract": {
            "type": "object",
            "additionalProperties": true
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "cookies": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "mode": {
            "type": "string",
            "enum": [
              "full",
              "summary"
            ],
            "default": "full"
          },
          "ai_prompt": {
            "type": "string"
          },
          "ai_schema": {
            "type": "object"
          }
        }
      },
      "ScrapeEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "finalUrl": {
                    "type": "string"
                  },
                  "status": {
                    "type": "integer"
                  },
                  "title": {
                    "type": "string"
                  },
                  "format": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "durationMs": {
                    "type": "number"
                  },
                  "engine": {
                    "type": "string"
                  },
                  "usage": {
                    "$ref": "#/components/schemas/Usage"
                  }
                }
              }
            }
          }
        ]
      },
      "SerpRequest": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Required except for ID-addressed verticals (place_details, product, flights, lens, reviews)."
          },
          "engine": {
            "type": "string",
            "enum": [
              "google",
              "bing",
              "duckduckgo"
            ],
            "default": "google"
          },
          "search_type": {
            "type": "string",
            "default": "search",
            "enum": [
              "search",
              "shopping",
              "images",
              "news",
              "places",
              "maps",
              "videos",
              "scholar",
              "jobs",
              "autocomplete",
              "place_details",
              "hotels",
              "flights",
              "events",
              "product",
              "lens",
              "reviews",
              "trends"
            ]
          },
          "type": {
            "type": "string",
            "description": "Alias of search_type (Google tbm/udm values accepted)."
          },
          "country": {
            "type": "string"
          },
          "gl": {
            "type": "string",
            "description": "Alias of country."
          },
          "lang": {
            "type": "string"
          },
          "hl": {
            "type": "string",
            "description": "Alias of lang."
          },
          "num": {
            "type": "number",
            "default": 10,
            "minimum": 1,
            "maximum": 100
          },
          "page": {
            "type": "number",
            "default": 1
          },
          "start": {
            "type": "number"
          },
          "device": {
            "type": "string",
            "enum": [
              "desktop",
              "mobile"
            ],
            "default": "desktop"
          },
          "brd_mobile": {
            "type": "integer",
            "description": "Alias of device mobile when set to 1."
          },
          "render": {
            "type": "boolean"
          },
          "location": {
            "type": "string"
          },
          "uule": {
            "type": "string"
          },
          "safe": {
            "type": "string",
            "enum": [
              "active",
              "off"
            ]
          },
          "nfpr": {
            "type": "boolean"
          },
          "google_params": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "place_id": {
            "type": "string"
          },
          "data_id": {
            "type": "string"
          },
          "product_id": {
            "type": "string"
          }
        }
      },
      "SerpEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "organic": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "usage": {
                    "$ref": "#/components/schemas/Usage"
                  }
                }
              }
            }
          }
        ]
      },
      "MapRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "limit": {
            "type": "number",
            "default": 100,
            "maximum": 5000
          },
          "search": {
            "type": "string"
          },
          "includeSubdomains": {
            "type": "boolean",
            "default": false
          },
          "sitemapOnly": {
            "type": "boolean",
            "default": false
          },
          "group_by": {
            "type": "string",
            "enum": [
              "path"
            ]
          },
          "country": {
            "type": "string"
          }
        }
      },
      "MapEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "links": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "count": {
                    "type": "integer"
                  },
                  "total": {
                    "type": "integer"
                  },
                  "usage": {
                    "$ref": "#/components/schemas/Usage"
                  }
                }
              }
            }
          }
        ]
      },
      "CrawlRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "limit": {
            "type": "number",
            "default": 50,
            "maximum": 500
          },
          "depth": {
            "type": "number",
            "default": 3,
            "maximum": 10
          },
          "format": {
            "type": "string",
            "enum": [
              "markdown",
              "html",
              "text"
            ],
            "default": "markdown"
          },
          "contentMode": {
            "type": "string",
            "enum": [
              "smart",
              "article",
              "full"
            ],
            "default": "smart"
          },
          "render": {
            "type": "boolean",
            "default": false
          },
          "sameDomain": {
            "type": "boolean",
            "default": true
          },
          "allowSubdomains": {
            "type": "boolean",
            "default": false
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "country": {
            "type": "string"
          }
        }
      },
      "CrawlStartEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "running",
                      "completed",
                      "failed",
                      "cancelled"
                    ]
                  },
                  "seed": {
                    "type": "string"
                  },
                  "statusUrl": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      },
      "CrawlPollEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          }
        ]
      },
      "BatchRequest": {
        "type": "object",
        "required": [
          "urls"
        ],
        "properties": {
          "urls": {
            "type": "array",
            "maxItems": 5000,
            "items": {
              "type": "string",
              "maxLength": 2048
            }
          },
          "format": {
            "type": "string",
            "enum": [
              "markdown",
              "html",
              "text"
            ],
            "default": "markdown"
          },
          "engine": {
            "type": "string",
            "enum": [
              "auto",
              "tls",
              "fetch",
              "render"
            ],
            "default": "auto"
          },
          "render": {
            "type": "boolean",
            "default": false
          },
          "extract": {
            "type": "object",
            "additionalProperties": true
          },
          "contentMode": {
            "type": "string",
            "enum": [
              "smart",
              "article",
              "full"
            ],
            "default": "smart"
          },
          "mode": {
            "type": "string",
            "enum": [
              "full",
              "summary"
            ],
            "default": "full"
          },
          "concurrency": {
            "type": "number",
            "default": 5,
            "maximum": 20
          },
          "webhook": {
            "type": "string"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "SeoAuditRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "no_render": {
            "type": "boolean",
            "default": false
          },
          "noRender": {
            "type": "boolean"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "SeoAuditEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          }
        ]
      },
      "CollectorRunRequest": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "max_results": {
            "type": "integer"
          },
          "country": {
            "type": "string"
          },
          "lang": {
            "type": "string"
          },
          "async": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "CollectorRunEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "run_id": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "count": {
                    "type": "integer"
                  },
                  "results": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "usage": {
                    "$ref": "#/components/schemas/Usage"
                  }
                }
              }
            }
          }
        ]
      },
      "PlanType": {
        "type": "string",
        "enum": [
          "residentialbasic",
          "residentialpremium",
          "resiprivate",
          "isp",
          "datacenter",
          "datacentertraffic",
          "ipv6",
          "mobile",
          "mobile_v2"
        ]
      },
      "GenerateProxiesRequest": {
        "type": "object",
        "required": [
          "orderId"
        ],
        "properties": {
          "orderId": {
            "type": "string",
            "description": "From GET /v1/public/proxies."
          },
          "protocol": {
            "type": "string",
            "enum": [
              "http",
              "socks5"
            ],
            "default": "http"
          },
          "format": {
            "type": "string",
            "enum": [
              "user:pass@host:port",
              "host:port:user:pass",
              "http://user:pass@host:port",
              "socks5://user:pass@host:port"
            ],
            "default": "user:pass@host:port"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "default": 10
          },
          "country": {
            "type": "string",
            "description": "Country code, lowercase, e.g. us."
          },
          "state": {
            "type": "string",
            "description": "Region slug (Residential Premium and Mobile V2). Alias region."
          },
          "region": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "rotation": {
            "type": "string",
            "enum": [
              "rotating",
              "sticky",
              "static"
            ],
            "default": "rotating",
            "description": "static is IPv6 only."
          },
          "sessionTime": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1440,
            "default": 10,
            "description": "Sticky duration in minutes. Residential Basic/Datacenter minimum 3."
          },
          "isp": {
            "type": "string",
            "description": "Residential Premium / Mobile V2 ISP code from the location tree."
          },
          "asn": {
            "type": "string",
            "description": "Residential/Datacenter Basic, e.g. AS12345."
          },
          "strict": {
            "type": "boolean",
            "description": "Residential/Datacenter Basic — allow nearby fallback."
          },
          "filter": {
            "type": "string",
            "enum": [
              "speed",
              "speed-quality",
              "quality"
            ]
          },
          "ip": {
            "type": "string",
            "description": "Mobile V2 — a whitelisted IP to fetch the IP-auth list instead of user:pass."
          },
          "gateway": {
            "type": "string",
            "enum": [
              "ww",
              "us",
              "eu",
              "as"
            ],
            "default": "ww"
          },
          "isExtension": {
            "type": "boolean",
            "default": false,
            "description": "Unique hostname prefix for Chrome extension cache-busting."
          }
        }
      },
      "GenerateProxiesEnvelope": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Envelope"
          },
          {
            "type": "object",
            "properties": {
              "payload": {
                "type": "object",
                "properties": {
                  "proxies": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "WhitelistIpRequest": {
        "type": "object",
        "required": [
          "orderId",
          "ip"
        ],
        "properties": {
          "orderId": {
            "type": "string"
          },
          "ip": {
            "type": "string",
            "description": "IPv4 to whitelist."
          },
          "action": {
            "type": "string",
            "enum": [
              "add",
              "update"
            ],
            "description": "Mobile — update edits an existing entry."
          },
          "ports_count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "protocol": {
            "type": "string",
            "enum": [
              "HTTP",
              "SOCKS5"
            ]
          },
          "country": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "isp": {
            "type": "string"
          },
          "sticky": {
            "type": "boolean"
          },
          "ttl": {
            "type": "integer",
            "description": "Mobile sticky TTL in seconds."
          }
        }
      }
    }
  }
}
