{
  "openapi": "3.1.0",
  "info": {
    "title": "QuantumProxies API",
    "version": "2026-10-07",
    "summary": "Scrape, search, crawl, unlock, run collectors and build datasets — one host, one Bearer key, one JSON envelope.",
    "description": "This specification is generated from the application source (route handlers, auth middleware, billing config). Every endpoint answers the same envelope: `{\"type\":\"response\",\"message\":\"…\",\"payload\":{…}}` on success and `{\"type\":\"error\",\"message\":\"…\",\"payload\":{…}}` on failure. Data API calls are pay-per-success: a blocked page, a target 4xx/5xx, a timeout or an error on our side is never charged. Billed responses carry `payload.usage` (`cost_usd`, `free_usd`, `paid_usd`, `balance`). Prices are referenced by key (`x-price-key`) and resolved from `pricing.json`; rate limits per tier live in `tiers.json`. Brand placeholders (`quantumproxies.io`, `QuantumProxies`) are resolved from `brands.json`.",
    "contact": {
      "name": "QuantumProxies support",
      "url": "https://quantumproxies.io/"
    },
    "termsOfService": "https://quantumproxies.io/terms/"
  },
  "servers": [
    {
      "url": "https://api.quantumproxies.io/v1",
      "description": "Primary API host. Short aliases (/scrape, /serp, /map, /crawl, /batch, /seo-audit, /serp/bulk and their job ids) are rewritten to the /scraper/* paths at the edge."
    },
    {
      "url": "https://app.quantumproxies.io/api/v1",
      "description": "Same API on the dashboard host (no short aliases)."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Scrape",
      "description": "One URL in, Markdown/HTML/text out, with optional structured and AI extraction."
    },
    {
      "name": "Search",
      "description": "Structured search-engine results (Google, Bing, DuckDuckGo) and async multi-page jobs."
    },
    {
      "name": "Map & Crawl",
      "description": "URL discovery for a whole site and asynchronous site crawls."
    },
    {
      "name": "Batch",
      "description": "Many known URLs scraped asynchronously."
    },
    {
      "name": "Web Unlocker",
      "description": "Replay any HTTP request through a residential exit with a real browser fingerprint; prepaid per GB."
    },
    {
      "name": "AI extraction",
      "description": "Natural-language agents that drive the scraper and return JSON."
    },
    {
      "name": "AI visibility",
      "description": "Can AI assistants read and cite a page?"
    },
    {
      "name": "SEO audit",
      "description": "No-JS vs rendered view of a page and the diff between them."
    },
    {
      "name": "Collectors",
      "description": "Ready-made, versioned scrapers on a semantic input; billed per delivered row. The catalog is dynamic: read it from GET /scraper/collectors."
    },
    {
      "name": "Datasets",
      "description": "Prompt-driven dataset builder: one prompt, a validated table."
    },
    {
      "name": "Parser presets",
      "description": "Generate CSS selectors once with an LLM, replay them for free, let them self-heal."
    },
    {
      "name": "Proxies",
      "description": "List your proxy plans, generate endpoint strings, manage IP whitelists."
    },
    {
      "name": "Account",
      "description": "Usage, billing status and platform settings."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Data API",
      "tags": [
        "Scrape",
        "Search",
        "Map & Crawl",
        "Batch",
        "Web Unlocker"
      ]
    },
    {
      "name": "AI",
      "tags": [
        "AI extraction",
        "AI visibility",
        "SEO audit"
      ]
    },
    {
      "name": "Collectors & datasets",
      "tags": [
        "Collectors",
        "Datasets",
        "Parser presets"
      ]
    },
    {
      "name": "Proxies",
      "tags": [
        "Proxies"
      ]
    },
    {
      "name": "Account",
      "tags": [
        "Account"
      ]
    }
  ],
  "x-mcp-tools": {
    "$comment": "Tools exposed by the hosted MCP server (tools/list on https://api.quantumproxies.io/mcp, 2026-10-07) and the REST endpoint each one calls. Same key, same prices.",
    "tools": [
      {
        "name": "scrape",
        "endpoint": "POST /scraper/extract"
      },
      {
        "name": "search",
        "endpoint": "POST /scraper/serp"
      },
      {
        "name": "search_and_read",
        "endpoint": "POST /scraper/serp + POST /scraper/extract"
      },
      {
        "name": "search_bulk",
        "endpoint": "POST /scraper/serp/bulk"
      },
      {
        "name": "search_bulk_status",
        "endpoint": "GET /scraper/serp/bulk/{jobId}"
      },
      {
        "name": "map",
        "endpoint": "POST /scraper/map"
      },
      {
        "name": "crawl",
        "endpoint": "POST /scraper/crawl"
      },
      {
        "name": "crawl_status",
        "endpoint": "GET /scraper/crawl/{jobId}"
      },
      {
        "name": "batch",
        "endpoint": "POST /scraper/batch"
      },
      {
        "name": "batch_status",
        "endpoint": "GET /scraper/batch/{jobId}"
      },
      {
        "name": "unlock",
        "endpoint": "POST /scraper/unlock"
      },
      {
        "name": "ai_visibility",
        "endpoint": "POST /scraper/ai-visibility"
      },
      {
        "name": "seo_audit",
        "endpoint": "POST /scraper/seo-audit"
      },
      {
        "name": "list_collectors",
        "endpoint": "GET /scraper/collectors"
      },
      {
        "name": "run_collector",
        "endpoint": "POST /scraper/collectors/{slug}/run"
      },
      {
        "name": "collector_run_status",
        "endpoint": "GET /scraper/collectors/runs/{runId}"
      },
      {
        "name": "create_dataset",
        "endpoint": "POST /scraper/datasets"
      },
      {
        "name": "dataset_status",
        "endpoint": "GET /scraper/datasets/{jobId}"
      },
      {
        "name": "generate_parser",
        "endpoint": "POST /scraper/parser/generate"
      },
      {
        "name": "list_parser_presets",
        "endpoint": "GET /scraper/parser/presets"
      },
      {
        "name": "save_parser_preset",
        "endpoint": "POST /scraper/parser/presets"
      },
      {
        "name": "heal_parser_preset",
        "endpoint": "POST /scraper/parser/presets/{id}/heal"
      },
      {
        "name": "parser_preset_stats",
        "endpoint": "GET /scraper/parser/presets/{id}/stats"
      },
      {
        "name": "list_proxies",
        "endpoint": "GET /public/proxies"
      },
      {
        "name": "generate_proxies",
        "endpoint": "POST /public/proxies/generate"
      },
      {
        "name": "proxy_locations",
        "endpoint": "POST /public/proxies/generate (targeting options)"
      },
      {
        "name": "whitelist_ip",
        "endpoint": "POST /public/proxies/whitelist-ip"
      },
      {
        "name": "report",
        "endpoint": "(MCP only: usage report of the session)"
      }
    ]
  },
  "x-brands": "brands.json",
  "x-pricing": "pricing.json",
  "x-tiers": "tiers.json",
  "x-rate-limits": {
    "description": "Per API key. Two windows apply: the tier's requests/minute (tiers.json → rateLimitPerMin) and an hourly window of max(1000, rateLimitPerMin × 60). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (hourly window); a 429 also carries Retry-After. Plan-level limiters (per-minute budget, browser-render concurrency) add X-RateLimit-Scope and X-RateLimit-Plan to their 429s.",
    "per_tier": "tiers.json"
  },
  "x-excluded": [
    {
      "path": "/scraper/extract/demo",
      "method": "POST",
      "reason": "Landing-page playground: requires a Turnstile token or a signed guard header issued by the public site, IP-capped (8/min, 15/day). Not callable from customer code."
    },
    {
      "path": "/scraper/ai/demo",
      "method": "POST",
      "reason": "Landing-page playground of the AI agent: Turnstile/guard-gated, IP-capped. Not callable from customer code."
    },
    {
      "path": "/scraper/ai-visibility/demo",
      "method": "POST",
      "reason": "Free tool behind /tools/ai-visibility-audit/: Turnstile/guard-gated, 6/min and 5/day per IP, one query on one engine. Not callable from customer code."
    },
    {
      "path": "/scraper/pdf/demo",
      "method": "POST",
      "reason": "Free tool behind /tools/pdf-to-markdown/: Turnstile/guard-gated, multipart upload, daily IP cap. No key-based equivalent exists as a separate endpoint (documents are handled by /scraper/extract)."
    },
    {
      "path": "/scraper/places-ai/demo",
      "method": "POST",
      "reason": "Landing-page playground: Turnstile/guard-gated, capped searches. Not callable from customer code."
    },
    {
      "path": "/scraper/shopping-ai/demo",
      "method": "POST",
      "reason": "Landing-page playground: Turnstile/guard-gated, capped searches. Not callable from customer code."
    },
    {
      "path": "/scraper/collectors/{slug}/demo",
      "method": "POST",
      "reason": "'Try it' widget on the public collector pages: signed guard header, CORS-locked to the brand sites, 5 rows, 8/min and 10/day per IP. Not callable from customer code."
    },
    {
      "path": "/scraper/collectors/{slug}/demo",
      "method": "OPTIONS",
      "reason": "CORS preflight of the widget endpoint above."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer qp_live_YOUR_API_KEY`. Keys are `qd_live_`/`qp_live_` followed by 64 hex characters and are created on the dashboard API keys page. Only this header is read: there is no `x-api-key` fallback and keys are never accepted in the query string. A disabled, expired or unknown key, or a banned account, answers 401."
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "description": "Requests allowed in the current hourly window for this key.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Requests left in the window.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Reset": {
        "description": "ISO-8601 instant when the window resets.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying (429 only).",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Scope": {
        "description": "Which limiter answered: a plan budget scope, `render-concurrency` or `capacity` (plan-level 429s only).",
        "schema": {
          "type": "string"
        }
      },
      "X-RateLimit-Plan": {
        "description": "The plan the limiter applied (plan-level 429s only).",
        "schema": {
          "type": "string"
        }
      }
    },
    "parameters": {
      "jobId": {
        "name": "jobId",
        "in": "path",
        "required": true,
        "description": "Job id returned by the POST that started it.",
        "schema": {
          "type": "string"
        },
        "example": "job_8f2c1a"
      },
      "presetId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Preset id returned when it was created.",
        "schema": {
          "type": "string"
        },
        "example": "pst_7Qk3"
      },
      "runId": {
        "name": "runId",
        "in": "path",
        "required": true,
        "description": "Collector run id (10–40 alphanumeric characters).",
        "schema": {
          "type": "string",
          "pattern": "^[a-z0-9]{10,40}$"
        },
        "example": "cmgfq2x1b0001"
      },
      "slug": {
        "name": "slug",
        "in": "path",
        "required": true,
        "description": "Collector slug from the catalog.",
        "schema": {
          "type": "string"
        },
        "example": "google_maps_places"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed input. `message` names the parameter and the rule it broke.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "Invalid format. Must be one of: markdown, html, text (or data_format markdown/screenshot, format raw)"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, malformed, unknown, disabled or expired API key; or the account is not active.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "Missing or invalid Authorization header. Use: Authorization: Bearer qp_live_YOUR_API_KEY"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "The free tier plus wallet balance cannot cover the worst-case estimate of this call, or the account's monthly spend cap is reached. Nothing was run or charged.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "insufficient_funds": {
                "value": {
                  "type": "error",
                  "message": "Your free tier for this month is used up and your balance can't cover this call (estimated $0.002). Add pay-as-you-go credit or pick a plan — your API key stays the same: https://app.quantumproxies.io/plans?utm_source=api&utm_medium=402&utm_campaign=free-tier",
                  "payload": {
                    "code": "INSUFFICIENT_FUNDS",
                    "balance": 0,
                    "free_remaining": 0,
                    "estimated_cost": 0.002,
                    "plans_url": "https://app.quantumproxies.io/plans?utm_source=api&utm_medium=402&utm_campaign=free-tier",
                    "billing_mode": "free_first"
                  }
                }
              },
              "budget_reached": {
                "value": {
                  "type": "error",
                  "message": "Monthly Data API budget reached (50.00 of 50.00 USD). Raise the budget in Billing → Spend controls, or wait for the 1st of next month.",
                  "payload": {
                    "code": "BUDGET_REACHED",
                    "budget_usd": 50,
                    "spent_usd": 50
                  }
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "No proxy pool is available to serve the call (no house plan and no residential/datacenter/IPv6 plan on the account).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "Scraper API is not available: no proxy credentials found. Contact support or purchase a residential, datacenter or IPv6 plan."
            }
          }
        }
      },
      "NotFound": {
        "description": "Unknown id — or an id that belongs to another account (ownership failures answer 404, never 403, so ids cannot be probed).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "Job not found"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Key rate limit (hourly window), plan per-minute budget, browser-render concurrency, or pool capacity. Back off on Retry-After.",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/X-RateLimit-Limit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/X-RateLimit-Remaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/X-RateLimit-Reset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-RateLimit-Scope": {
            "$ref": "#/components/headers/X-RateLimit-Scope"
          },
          "X-RateLimit-Plan": {
            "$ref": "#/components/headers/X-RateLimit-Plan"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "key_window": {
                "value": {
                  "type": "error",
                  "message": "Rate limit exceeded. Resets in 23 minutes.",
                  "payload": {
                    "rateLimit": 1200,
                    "requestCount": 1200,
                    "resetAt": "2026-10-07T15:00:00.000Z"
                  }
                }
              },
              "render_concurrency": {
                "value": {
                  "type": "error",
                  "message": "Render concurrency limit reached: the payg plan runs 1 browser render(s) at a time. Wait for one to finish and retry in 5s, or submit the URLs as a batch job.",
                  "payload": {
                    "code": "render_concurrency_limit",
                    "plan": "payg",
                    "limit": {
                      "class": "render",
                      "concurrent": 1
                    },
                    "retry_after": 5
                  }
                }
              }
            }
          }
        }
      },
      "ServerError": {
        "description": "Our side: the scraper service is unavailable or the call timed out. Never billed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "Scraper service unavailable. Please try again later."
            }
          }
        }
      },
      "ServiceDisabled": {
        "description": "The Data API group is switched off for non-admin keys (early-access kill switch).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "message": "This API is temporarily unavailable while we finalize pricing. Contact support for early access."
            }
          }
        }
      }
    },
    "schemas": {
      "Envelope": {
        "type": "object",
        "description": "Success envelope shared by every endpoint.",
        "required": [
          "type",
          "message",
          "payload"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "response"
          },
          "message": {
            "type": "string"
          },
          "payload": {
            "type": "object"
          },
          "pagination": {
            "type": "object",
            "description": "Empty `{}` unless the endpoint pages (SERP mirrors its own pagination here)."
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "description": "Error envelope. `payload` is present only when the error carries structured detail (codes, balances, limits).",
        "required": [
          "type",
          "message"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "error"
          },
          "message": {
            "type": "string"
          },
          "payload": {
            "type": "object"
          }
        }
      },
      "Usage": {
        "type": "object",
        "description": "What the call cost. Present only on billed calls (absent when billing is off for the account or the key is an admin key).",
        "required": [
          "cost_usd",
          "free_usd",
          "paid_usd"
        ],
        "properties": {
          "cost_usd": {
            "type": "number",
            "description": "Total cost of the call, USD, after the tier discount."
          },
          "free_usd": {
            "type": "number",
            "description": "Portion covered by the monthly free allowance."
          },
          "paid_usd": {
            "type": "number",
            "description": "Portion debited from the wallet."
          },
          "balance": {
            "type": "number",
            "description": "Wallet balance after the debit, present only when the wallet was touched."
          }
        }
      },
      "Geo": {
        "type": "object",
        "description": "Echo of the geo-targeting the call used.",
        "properties": {
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "rotation": {
            "type": "string",
            "enum": [
              "rotating",
              "sticky"
            ]
          }
        }
      },
      "GeoValue": {
        "type": "string",
        "description": "Country code or place name: letters, digits, spaces, dots, hyphens, underscores; max 56 characters. `all` means no targeting.",
        "pattern": "^([a-zA-Z0-9 ._-]{1,56}|all)$",
        "examples": [
          "us",
          "it",
          "all"
        ]
      },
      "ExtractSchema": {
        "type": "object",
        "description": "Structured-extraction schema: field name → CSS selector, or an object with `selector`, optional `attr` (attribute to read instead of text) and `all` (true = every match as an array).",
        "additionalProperties": {
          "oneOf": [
            {
              "type": "string",
              "description": "CSS selector; the element's text is returned."
            },
            {
              "type": "object",
              "properties": {
                "selector": {
                  "type": "string"
                },
                "attr": {
                  "type": "string"
                },
                "all": {
                  "type": "boolean"
                }
              },
              "required": [
                "selector"
              ]
            }
          ]
        },
        "examples": [
          {
            "title": "h1",
            "price": ".price",
            "image": {
              "selector": "img.hero",
              "attr": "src"
            },
            "features": {
              "selector": "li.feature",
              "all": true
            }
          }
        ]
      },
      "PageAction": {
        "type": "object",
        "description": "One interaction before capture (render tier). Shapes are enforced by the scraper service; at most 20 actions, each a plain object. A `fetchResource` action must be last: the matching network response becomes the result body.",
        "examples": [
          {
            "click": "#accept"
          },
          {
            "scroll": "bottom"
          },
          {
            "wait": 1500
          },
          {
            "fetchResource": {
              "pattern": "/api/items"
            }
          }
        ]
      },
      "ForwardHeaders": {
        "description": "Extra headers replayed to the target. Either a JSON object (name → value) or a raw `Header: Value` block, one per line (lines starting with `//` or `#` are ignored). Max 32 headers, names must be RFC 7230 tokens, values ≤ 4096 characters; hop-by-hop and framing headers (host, content-length, transfer-encoding, connection, …) are rejected.",
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          {
            "type": "string"
          }
        ]
      },
      "PageMetadata": {
        "type": "object",
        "description": "Meta/OpenGraph data of an HTML page (keys depend on what the page declares).",
        "properties": {
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "canonical": {
            "type": [
              "string",
              "null"
            ]
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "appState": {
            "description": "The page's own hydration state (Next/Nuxt/JSON islands), present only when `app_state` was requested."
          }
        },
        "additionalProperties": true
      },
      "ExtractResult": {
        "type": "object",
        "description": "Payload of a scrape. Optional fields appear only when requested (`data`, `links`, `screenshot`, `xhr`, `formats`, `contents`, `chunks`, `highlights`, `ai`).",
        "required": [
          "url",
          "finalUrl",
          "status",
          "format",
          "content",
          "bytes",
          "durationMs"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string",
            "description": "URL after redirects."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status the target answered."
          },
          "contentType": {
            "type": [
              "string",
              "null"
            ]
          },
          "format": {
            "type": "string",
            "enum": [
              "markdown",
              "html",
              "text"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "metadata": {
            "$ref": "#/components/schemas/PageMetadata"
          },
          "content": {
            "type": "string",
            "description": "The page in the requested format (empty in `mode: summary`)."
          },
          "contents": {
            "type": "object",
            "description": "One entry per requested `content_modes` value.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "chunks": {
            "type": "array",
            "description": "Segmented output when `chunk` was requested.",
            "items": {
              "type": "object"
            }
          },
          "highlights": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bytes": {
            "type": "integer",
            "description": "Proxy bandwidth the fetch used — the metered part of the price."
          },
          "durationMs": {
            "type": "integer"
          },
          "engine": {
            "type": "string",
            "enum": [
              "tls",
              "fetch",
              "render"
            ],
            "description": "Engine that actually served the page; decides between the `extract` and `extract_render` price."
          },
          "attempts": {
            "type": "integer"
          },
          "escalated": {
            "type": "boolean",
            "description": "True when `engine: auto` escalated from the TLS tier to the browser."
          },
          "blockReason": {
            "type": "string",
            "description": "Present when the final page was an anti-bot block (the call is then not charged)."
          },
          "tlsProfile": {
            "type": "string"
          },
          "jsLikely": {
            "type": "boolean",
            "description": "Content came out near-empty but the HTML is a JS app shell: retry with `render: true`."
          },
          "screenshot": {
            "type": "string",
            "description": "Base64 PNG, render tier only."
          },
          "xhr": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "resource": {
            "type": "object",
            "description": "The network response captured by a `fetchResource` action; its body is `content`."
          },
          "data": {
            "type": "object",
            "description": "Values of the `extract` schema (or of the `presetId` parser)."
          },
          "formats": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "links": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "documentKind": {
            "type": "string",
            "description": "Set when the URL was a binary document converted to text (pdf, docx, xlsx, csv)."
          },
          "ai": {
            "type": "object",
            "description": "AI extraction result (`ai_prompt`/`ai_schema`): `data`, `truncated`, `model`, `usage`; or `error` when the model step failed (the scrape itself still succeeded).",
            "properties": {
              "data": {},
              "truncated": {
                "type": "boolean"
              },
              "model": {
                "type": "string"
              },
              "usage": {
                "type": "object"
              },
              "error": {
                "type": "string"
              }
            }
          },
          "geo": {
            "$ref": "#/components/schemas/Geo"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "additionalProperties": true
      },
      "OrganicResult": {
        "type": "object",
        "required": [
          "rank",
          "title",
          "link"
        ],
        "properties": {
          "rank": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "link": {
            "type": "string"
          },
          "redirect_link": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_link": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": [
              "string",
              "null"
            ],
            "description": "Registrable host, e.g. wikipedia.org."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "date": {
            "type": [
              "string",
              "null"
            ]
          },
          "snippet_highlighted_words": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sitelinks": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "rich_snippet": {
            "type": "object"
          }
        }
      },
      "SerpResult": {
        "type": "object",
        "description": "Search result in the common SERP-API JSON shape (drop-in for most existing SERP clients). Vertical arrays are always present (empty when the vertical did not apply); the single-object verticals (`place_results`, `product_results`, `trends`, `trending`, `knowledge_graph`, …) are null when absent.",
        "required": [
          "search_metadata",
          "search_parameters",
          "organic",
          "pagination"
        ],
        "properties": {
          "search_metadata": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "engine": {
                "type": "string"
              },
              "search_url": {
                "type": "string"
              },
              "created_at": {
                "type": "string"
              },
              "total_time_taken": {
                "type": "number"
              },
              "attempts": {
                "type": "integer"
              },
              "bytes": {
                "type": "integer"
              },
              "from_cache": {
                "type": "boolean",
                "description": "Served from the 24h result cache — identical requests are free."
              },
              "path": {
                "type": "string",
                "enum": [
                  "http",
                  "farm",
                  "sei",
                  "render"
                ],
                "description": "Winning fetch tier. `http` bills the `serp` price; anything else bills `serp_render` (Google only)."
              },
              "paging": {
                "type": "object"
              }
            }
          },
          "search_parameters": {
            "type": "object",
            "properties": {
              "engine": {
                "type": "string"
              },
              "q": {
                "type": "string"
              },
              "search_type": {
                "type": "string"
              },
              "device": {
                "type": "string"
              },
              "country": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "language": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "page": {
                "type": "integer"
              }
            }
          },
          "general": {
            "type": "object"
          },
          "retries": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "organic": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrganicResult"
            }
          },
          "ads": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "shopping": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "news": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "places": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "scholar": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "jobs_results": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "suggestions": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "trends": {
            "type": [
              "object",
              "null"
            ]
          },
          "trending": {
            "type": [
              "object",
              "null"
            ]
          },
          "place_results": {
            "type": [
              "object",
              "null"
            ]
          },
          "properties": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Google Hotels property cards."
          },
          "flights_results": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "events_results": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "product_results": {
            "type": [
              "object",
              "null"
            ]
          },
          "visual_matches": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "reviews_results": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "serpapi_pagination": {
            "type": "object",
            "properties": {
              "next_page_token": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "inline_videos": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "immersive_products": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "perspectives": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "related": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "related_searches": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "refine_this_search": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "refine_search_filters": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "things_to_know": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "people_also_ask": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "related_questions": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "knowledge": {
            "type": [
              "object",
              "null"
            ]
          },
          "knowledge_graph": {
            "type": [
              "object",
              "null"
            ]
          },
          "featured_snippet": {
            "type": [
              "object",
              "null"
            ]
          },
          "ai_overview": {
            "type": [
              "string",
              "null"
            ]
          },
          "ai_overview_references": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "answer_box": {
            "type": [
              "object",
              "null"
            ]
          },
          "weather": {
            "type": [
              "object",
              "null"
            ]
          },
          "flights": {
            "type": [
              "object",
              "null"
            ]
          },
          "currency": {
            "type": [
              "object",
              "null"
            ]
          },
          "pagination": {
            "type": "object",
            "properties": {
              "current": {
                "type": "integer"
              },
              "next": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "total_pages": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "other_pages": {
                "type": "object"
              },
              "available_pages": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "has_next": {
                "type": "boolean"
              }
            }
          },
          "html": {
            "type": "string",
            "description": "Full page HTML, only with `include_html: true`."
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "additionalProperties": true
      },
      "MapResult": {
        "type": "object",
        "required": [
          "url",
          "count",
          "total",
          "summary",
          "sources",
          "durationMs"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Up to `limit` URLs (omitted with `group_by`)."
          },
          "count": {
            "type": "integer",
            "description": "How many URLs `links` holds."
          },
          "total": {
            "type": "integer",
            "description": "URLs discovered site-wide (can exceed `count`)."
          },
          "summary": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "URLs per first path segment."
          },
          "groups": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Path tree with counts (depth 2), only with `group_by: path`."
          },
          "sources": {
            "type": "object",
            "properties": {
              "sitemap": {
                "type": "integer"
              },
              "homepage": {
                "type": "integer"
              }
            }
          },
          "durationMs": {
            "type": "integer"
          },
          "geo": {
            "type": "object",
            "properties": {
              "country": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "JobStarted": {
        "type": "object",
        "description": "Answer of a POST that started an async job.",
        "required": [
          "id",
          "status",
          "statusUrl"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "statusUrl": {
            "type": "string",
            "description": "Dashboard-host path to poll (prefix it with the app host, or call the same path on the API host without `/api`)."
          },
          "usage": {
            "$ref": "#/components/schemas/Usage",
            "description": "The up-front charge on the requested volume; the unfetched share is refunded when the job settles."
          }
        },
        "additionalProperties": true
      },
      "CrawlPage": {
        "type": "object",
        "required": [
          "url",
          "status",
          "depth"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "depth": {
            "type": "integer"
          },
          "content": {
            "type": "string",
            "description": "Omitted when polled with `include_content=false`."
          },
          "error": {
            "type": "string"
          }
        }
      },
      "CrawlJob": {
        "type": "object",
        "required": [
          "id",
          "status",
          "seed",
          "limit",
          "depth",
          "format",
          "pagesCrawled",
          "pagesQueued",
          "pages",
          "nextCursor",
          "hasMore"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed",
              "cancelled"
            ]
          },
          "seed": {
            "type": "string"
          },
          "limit": {
            "type": "integer"
          },
          "depth": {
            "type": "integer"
          },
          "format": {
            "type": "string"
          },
          "pagesCrawled": {
            "type": "integer"
          },
          "pagesQueued": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          },
          "pages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrawlPage"
            }
          },
          "nextCursor": {
            "type": "integer",
            "description": "Pass as `since` on the next poll to receive only newer pages."
          },
          "hasMore": {
            "type": "boolean",
            "description": "Finished pages beyond `nextCursor` were withheld (byte budget or cursor)."
          },
          "createdAt": {
            "type": "integer",
            "description": "Unix ms."
          },
          "finishedAt": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "BatchItem": {
        "type": "object",
        "required": [
          "url",
          "status"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "content": {
            "type": "string",
            "description": "Only with `include_content=true` and not in `mode: summary`."
          },
          "data": {
            "type": "object",
            "description": "Values of the `extract` schema."
          },
          "engine": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Summary mode."
          },
          "canonical": {
            "type": [
              "string",
              "null"
            ],
            "description": "Summary mode."
          },
          "contentLength": {
            "type": "integer",
            "description": "Summary mode: characters of the converted content."
          },
          "bytes": {
            "type": "integer"
          },
          "blockReason": {
            "type": "string",
            "description": "Anti-bot block: the URL counts as failed and is refunded."
          }
        }
      },
      "BatchJob": {
        "type": "object",
        "required": [
          "id",
          "status",
          "total",
          "completed",
          "failed",
          "items",
          "nextCursor",
          "hasMore"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "cancelled",
              "failed"
            ]
          },
          "total": {
            "type": "integer"
          },
          "completed": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          },
          "contentTruncated": {
            "type": "boolean",
            "description": "The job hit its memory budget; later items carry metadata only."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            }
          },
          "nextCursor": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "integer"
          },
          "finishedAt": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "SerpBulkJob": {
        "type": "object",
        "required": [
          "id",
          "status",
          "query",
          "total",
          "completed",
          "failed",
          "pages",
          "organic",
          "nextCursor"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "cancelled",
              "failed"
            ]
          },
          "query": {
            "type": "string"
          },
          "total": {
            "type": "integer",
            "description": "Pages requested (`max_pages`)."
          },
          "completed": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "page": {
                  "type": "integer"
                },
                "organic_count": {
                  "type": "integer"
                },
                "bytes": {
                  "type": "integer"
                },
                "path": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "error": {
                  "type": "string"
                }
              }
            }
          },
          "organic": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrganicResult"
            },
            "description": "Merged, de-duplicated, re-ranked across pages (from `since` onwards)."
          },
          "related_searches": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "ai_overview": {
            "type": [
              "string",
              "null"
            ]
          },
          "search_metadata": {
            "type": "object"
          },
          "search_parameters": {
            "type": "object"
          },
          "pagination": {
            "type": "object"
          },
          "available_pages": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "nextCursor": {
            "type": "integer"
          },
          "createdAt": {
            "type": "integer"
          },
          "finishedAt": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "additionalProperties": true
      },
      "UnlockResult": {
        "type": "object",
        "description": "The target's response, replayed. `bodyBase64` is always present; `body` only when the content type is text-like (html, xml, text, json, javascript).",
        "required": [
          "status",
          "bodyBase64",
          "blocked",
          "rendered",
          "escalated",
          "tier",
          "usage"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "description": "HTTP status the origin answered."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "body": {
            "type": "string"
          },
          "bodyBase64": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string"
          },
          "contentType": {
            "type": [
              "string",
              "null"
            ]
          },
          "profile": {
            "type": "string",
            "description": "TLS fingerprint profile that won."
          },
          "attempts": {
            "type": "integer"
          },
          "blocked": {
            "type": "boolean",
            "description": "Every tier came back with a challenge or refusal; the payload is that page, for inspection."
          },
          "blockReason": {
            "type": "string"
          },
          "blockClass": {
            "type": "string",
            "enum": [
              "js_challenge",
              "captcha",
              "access_denied",
              "rate_limited",
              "fingerprint",
              "geo",
              "timeout",
              "unknown"
            ]
          },
          "vendor": {
            "type": "string",
            "description": "Anti-bot vendor when recognised."
          },
          "clearance": {
            "type": "string",
            "enum": [
              "hit",
              "miss",
              "minted",
              "stale",
              "off"
            ],
            "description": "What the engine did with its per-tenant clearance cache."
          },
          "setCookie": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cookies": {
            "type": "object",
            "description": "Full cookie jar, only with `returnCookies: true`."
          },
          "hint": {
            "type": "string"
          },
          "exitSessionId": {
            "type": "string"
          },
          "strategy": {
            "type": "object",
            "properties": {
              "startTier": {
                "type": "string",
                "enum": [
                  "tls",
                  "browser"
                ]
              },
              "hedged": {
                "type": "boolean"
              }
            }
          },
          "rendered": {
            "type": "boolean"
          },
          "escalated": {
            "type": "boolean"
          },
          "tier": {
            "type": "string",
            "enum": [
              "premium",
              "mobile"
            ]
          },
          "geo": {
            "$ref": "#/components/schemas/Geo"
          },
          "usage": {
            "type": "object",
            "description": "Unlocker usage is metered in bytes against the tier's prepaid GB, not the wallet.",
            "properties": {
              "bytes": {
                "type": "integer",
                "description": "Bytes the exit network moved for this call — every attempt and tier, not only the body returned."
              },
              "unlock_gb_remaining": {
                "type": "number"
              },
              "unlock_gb_purchased": {
                "type": "number"
              }
            }
          }
        }
      },
      "AiAgentResult": {
        "type": "object",
        "required": [
          "data",
          "steps",
          "model"
        ],
        "properties": {
          "data": {
            "description": "The extracted JSON (shape follows the task)."
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "One entry per page the agent fetched."
          },
          "searches": {
            "type": "integer"
          },
          "mapped": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "bytes": {
            "type": "integer"
          },
          "usage": {
            "description": "LLM token usage (`input_tokens`, `output_tokens`) merged with the billing block (`cost_usd`, `free_usd`, `paid_usd`)."
          }
        },
        "additionalProperties": true
      },
      "AiFinderResult": {
        "type": "object",
        "description": "Shared shape of the AI Places and AI Shopping finders.",
        "properties": {
          "places": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Places finder only."
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Shopping finder only."
          },
          "total": {
            "type": "integer"
          },
          "enriched": {
            "type": "integer",
            "description": "Places finder only: knowledge-panel lookups performed."
          },
          "queries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The searches the model crafted."
          },
          "searches": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "summary": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "usage": {
            "description": "LLM token usage merged with the billing block."
          }
        },
        "additionalProperties": true
      },
      "AiVisibilityResult": {
        "type": "object",
        "required": [
          "url",
          "finalUrl",
          "domain",
          "score",
          "checks",
          "topFixes",
          "access",
          "content",
          "structure"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          },
          "score": {
            "type": "object",
            "properties": {
              "overall": {
                "type": "number"
              },
              "pillars": {
                "type": "object",
                "additionalProperties": {
                  "type": "number"
                }
              },
              "scoredPillars": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "blockers": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Checks whose failure caps the overall (blocked crawler, noindex, no text)."
              },
              "uncapped": {
                "type": "number"
              }
            }
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "pillar": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "weight": {
                  "type": "number"
                },
                "title": {
                  "type": "string"
                },
                "detail": {
                  "type": "string"
                },
                "fix": {
                  "type": "string"
                },
                "evidence": {}
              }
            }
          },
          "topFixes": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "access": {
            "type": "object",
            "description": "robots.txt verdict per AI crawler, Content-Signal, sitemaps, llms.txt, the fetch that identified itself as an AI crawler."
          },
          "content": {
            "type": "object",
            "description": "No-JS vs rendered view, readability metrics."
          },
          "structure": {
            "type": "object",
            "description": "JSON-LD types, entities, author, dates, heading outline."
          },
          "retrievability": {
            "type": "object",
            "description": "Google rank for the page's own H1 question and index status (2 SERPs), unless `no_retrieval`."
          },
          "citations": {
            "type": "object",
            "description": "Only with `queries`: `rows` (one per query × engine: cited / mentioned / rank / error), `usage`, share of voice."
          },
          "offsite": {
            "type": "object",
            "description": "Only with `offsite: true`: brand presence per platform."
          },
          "geo": {
            "type": "object"
          },
          "billing": {
            "type": "object",
            "properties": {
              "citation_calls_billed": {
                "type": "integer"
              },
              "offsite_serps_billed": {
                "type": "integer"
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        },
        "additionalProperties": true
      },
      "SeoView": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "canonical": {
            "type": [
              "string",
              "null"
            ]
          },
          "h1": {
            "type": [
              "string",
              "null"
            ]
          },
          "wordCount": {
            "type": "integer"
          },
          "hasContent": {
            "type": "boolean"
          }
        }
      },
      "SeoAuditResult": {
        "type": "object",
        "required": [
          "url",
          "finalUrl",
          "noJs",
          "render",
          "diff",
          "meta",
          "durationMs"
        ],
        "properties": {
          "url": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string"
          },
          "noJs": {
            "$ref": "#/components/schemas/SeoView"
          },
          "render": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SeoView"
              },
              {
                "type": "object",
                "properties": {
                  "error": {
                    "type": "string"
                  }
                },
                "required": [
                  "error"
                ]
              }
            ],
            "description": "Rendered view, or `{error}` when the render pass was skipped or failed (then the call bills the plain scrape price)."
          },
          "diff": {
            "type": "object",
            "properties": {
              "titleChanged": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "descriptionChanged": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "h1OnlyInRender": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "canonicalMissingNoJs": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "contentOnlyInJs": {
                "type": [
                  "boolean",
                  "null"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "robots": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "ogTitle": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "ogUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "twitterCard": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "jsonldTypes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "durationMs": {
            "type": "integer"
          },
          "geo": {
            "type": "object"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "CollectorHealth": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "healthy",
              "degraded",
              "unknown"
            ]
          },
          "checked_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "latency_ms": {
            "type": [
              "integer",
              "null"
            ]
          },
          "result_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "success_rate_24h": {
            "type": [
              "number",
              "null"
            ]
          },
          "last_ok_at": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CollectorCatalogEntry": {
        "type": "object",
        "description": "One collector. `input_schema` is a JSON Schema object (what to POST to `run_url`); `output_schema.fields` lists the columns of every delivered row.",
        "required": [
          "slug",
          "name",
          "version",
          "category",
          "unit",
          "price",
          "max_results",
          "input_schema",
          "output_schema",
          "examples",
          "health",
          "run_url"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "search",
              "seo",
              "social",
              "apps",
              "real_estate",
              "local",
              "jobs",
              "news",
              "ecommerce",
              "travel",
              "leads",
              "company",
              "classifieds",
              "finance",
              "dev",
              "knowledge",
              "gaming",
              "osint",
              "research"
            ]
          },
          "category_label": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "unit": {
            "type": "string",
            "description": "What one billed result is (place, review, job, …)."
          },
          "engines": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "serp",
                "extract",
                "map",
                "ai"
              ]
            }
          },
          "price": {
            "type": "object",
            "properties": {
              "list_usd": {
                "type": "number"
              },
              "your_usd": {
                "type": "number",
                "description": "List price × your tier discount — what you pay per delivered result."
              },
              "price_key": {
                "type": "string",
                "description": "The pricing.json key (`collector_<slug>`, or `collector_result` as fallback)."
              },
              "per_1k_usd": {
                "type": "number"
              },
              "min_billable_results": {
                "type": "integer",
                "description": "Floor in units for a run that delivers anything; 0 = pure per-row."
              },
              "min_run_usd": {
                "type": "number"
              }
            }
          },
          "max_results": {
            "type": "integer",
            "description": "Hard cap on rows per run."
          },
          "input_schema": {
            "type": "object",
            "description": "JSON Schema (type object, properties, required, additionalProperties: false)."
          },
          "output_schema": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "nullable": {
                      "type": "boolean"
                    },
                    "description": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "examples": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "input": {
                  "type": "object"
                }
              }
            }
          },
          "health_input": {
            "type": "object"
          },
          "health": {
            "$ref": "#/components/schemas/CollectorHealth"
          },
          "run_url": {
            "type": "string"
          },
          "changelog": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "version": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                },
                "notes": {
                  "type": "string"
                }
              }
            },
            "description": "Single-collector view only."
          },
          "health_history": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Single-collector view only: last 24 probes."
          }
        }
      },
      "CollectorRun": {
        "type": "object",
        "required": [
          "run_id",
          "slug",
          "version",
          "status",
          "input",
          "count",
          "partial",
          "cost",
          "error",
          "created_at",
          "started_at",
          "finished_at"
        ],
        "properties": {
          "run_id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "done",
              "failed"
            ]
          },
          "input": {
            "type": "object"
          },
          "count": {
            "type": "integer",
            "description": "Delivered rows."
          },
          "partial": {
            "type": "boolean",
            "description": "The run stopped before `max_results` (deadline, a page failed, …)."
          },
          "partial_reason": {
            "type": "string"
          },
          "cost": {
            "type": "object",
            "properties": {
              "usd": {
                "type": "number"
              },
              "unit_usd": {
                "type": "number"
              },
              "unit": {
                "type": "string"
              },
              "billed": {
                "type": "boolean"
              }
            }
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "error_kind": {
            "type": "string",
            "enum": [
              "input"
            ],
            "description": "`input` = retrying the same input cannot help (HTTP 422)."
          },
          "dropped": {
            "type": "object",
            "description": "Lead collectors only: rows withheld by the removal list, your exclusion list or because already delivered to you."
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Delivered rows (columns per `output_schema`). Absent in list views."
          },
          "failed": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "deduplicated": {
            "type": "boolean",
            "description": "An identical run inside the dedup window was served instead of starting a new one — nothing new was charged."
          },
          "created_at": {
            "type": "string"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "DatasetSummary": {
        "type": "object",
        "description": "One row of the dataset list.",
        "properties": {
          "id": {
            "type": "string"
          },
          "jobId": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "prompt": {
            "type": "string"
          },
          "columns": {
            "type": "string",
            "description": "JSON-encoded column list."
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed",
              "cancelled",
              "budget_reached",
              "expired"
            ]
          },
          "rowCount": {
            "type": "integer"
          },
          "billableRows": {
            "type": "integer"
          },
          "refresh": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "purgedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "costUsd": {
            "type": [
              "number",
              "null"
            ],
            "description": "Real cost once settled (budget charge minus refund); null while running."
          },
          "stored": {
            "type": "boolean",
            "description": "Rows are stored and the run can be reopened/exported."
          },
          "storedRows": {
            "type": [
              "integer",
              "null"
            ]
          },
          "storedBytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "purged": {
            "type": "boolean"
          },
          "dropped": {
            "type": [
              "object",
              "null"
            ]
          }
        }
      },
      "DatasetJob": {
        "type": "object",
        "description": "Live job view (from the service) or the stored view of a finished run (`source: storage`, no progress/steps).",
        "required": [
          "id",
          "status",
          "prompt",
          "columns",
          "row_count",
          "billable_rows"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed",
              "cancelled",
              "budget_reached"
            ]
          },
          "prompt": {
            "type": "string"
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "files": {
            "type": [
              "object",
              "null"
            ]
          },
          "progress": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "queries_run": {
                "type": "integer"
              },
              "sites_mapped": {
                "type": "integer"
              },
              "pages_scraped": {
                "type": "integer"
              },
              "pages_failed": {
                "type": "integer"
              },
              "rows": {
                "type": "integer"
              },
              "dropped_offtarget": {
                "type": "integer"
              },
              "cost_so_far_usd": {
                "type": "number"
              }
            }
          },
          "limits": {
            "type": "object",
            "properties": {
              "max_rows": {
                "type": "integer"
              },
              "max_pages": {
                "type": "integer"
              },
              "max_cost_usd": {
                "type": "number"
              }
            }
          },
          "entity": {
            "type": [
              "string",
              "null"
            ]
          },
          "billable": {
            "type": "object",
            "properties": {
              "row_fees_usd": {
                "type": "number"
              },
              "unit_usd": {
                "type": "number"
              }
            }
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "phase": {
                  "type": "string",
                  "enum": [
                    "plan",
                    "search",
                    "map",
                    "scrape",
                    "extract",
                    "consolidate"
                  ]
                },
                "detail": {
                  "type": "string"
                },
                "ts": {
                  "type": "integer"
                }
              }
            }
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fields": {
                  "type": "object"
                },
                "_source_url": {
                  "type": "string"
                },
                "_fetched_at": {
                  "type": "string"
                },
                "confidence": {
                  "type": "number"
                },
                "billed_fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "fee_usd": {
                  "type": "number"
                },
                "low_confidence": {
                  "type": "boolean"
                }
              }
            },
            "description": "Omitted with `mode=summary`; from `since` onwards otherwise."
          },
          "dropped": {
            "type": [
              "object",
              "null"
            ]
          },
          "row_count": {
            "type": "integer"
          },
          "billable_rows": {
            "type": "integer"
          },
          "nextCursor": {
            "type": "integer"
          },
          "createdAt": {},
          "finishedAt": {},
          "error": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "storage"
            ]
          },
          "purged": {
            "type": "boolean"
          },
          "rowsUnavailable": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "ParserPreset": {
        "type": "object",
        "required": [
          "id",
          "name",
          "parser",
          "version",
          "autoHeal",
          "createdAt",
          "updatedAt",
          "stats",
          "history"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string"
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "render": {
            "type": "boolean"
          },
          "parser": {
            "$ref": "#/components/schemas/ExtractSchema"
          },
          "version": {
            "type": "integer"
          },
          "autoHeal": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "integer"
          },
          "lastHealAt": {
            "type": [
              "integer",
              "null"
            ]
          },
          "stats": {
            "type": "object",
            "properties": {
              "runs": {
                "type": "integer"
              },
              "lastRunAt": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "fields": {
                "type": "object"
              },
              "recent": {
                "type": "array",
                "items": {
                  "type": "number"
                }
              }
            }
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "version": {
                  "type": "integer"
                },
                "parser": {
                  "type": "object"
                },
                "at": {
                  "type": "integer"
                },
                "reason": {
                  "type": "string"
                },
                "coverage": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "PresetStatsView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "runs": {
            "type": "integer"
          },
          "lastRunAt": {
            "type": [
              "integer",
              "null"
            ]
          },
          "successRateByField": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "recentCoverage": {
            "type": [
              "number",
              "null"
            ]
          },
          "decayed": {
            "type": "boolean"
          },
          "autoHeal": {
            "type": "boolean"
          },
          "lastHealAt": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "HealResult": {
        "type": "object",
        "required": [
          "healed",
          "reason",
          "version"
        ],
        "properties": {
          "healed": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "coverageBefore": {
            "type": [
              "number",
              "null"
            ]
          },
          "coverageAfter": {
            "type": "number"
          },
          "parser": {
            "$ref": "#/components/schemas/ExtractSchema"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "GenerateParserResult": {
        "type": "object",
        "required": [
          "parser",
          "report",
          "missed",
          "coverage"
        ],
        "properties": {
          "parser": {
            "$ref": "#/components/schemas/ExtractSchema",
            "description": "Ready to pass as `extract` on any later scrape of this layout."
          },
          "report": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "selector": {
                  "type": "string"
                },
                "sample": {},
                "missed": {
                  "type": "boolean"
                }
              }
            }
          },
          "missed": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coverage": {
            "type": "number",
            "description": "Fraction of requested fields that produced a value (0–1). 0 = not charged."
          },
          "repaired": {
            "type": "boolean"
          },
          "usage": {}
        },
        "additionalProperties": true
      },
      "ProxyPlan": {
        "type": "object",
        "description": "One proxy service on the account. `orderId` is what the generate and whitelist endpoints take.",
        "properties": {
          "id": {
            "type": "string"
          },
          "orderId": {
            "type": "string"
          },
          "planName": {
            "type": "string"
          },
          "planType": {
            "type": "string",
            "enum": [
              "residentialbasic",
              "residentialpremium",
              "resiprivate",
              "isp",
              "isppremium",
              "datacenter",
              "datacentertraffic",
              "ipv6",
              "mobile",
              "mobile_v2"
            ]
          },
          "planTypeName": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "proxyId": {
            "type": "string",
            "description": "Absent for Premium ISP plans (which carry `tier: premium` instead)."
          },
          "tier": {
            "type": "string"
          },
          "bandwidth": {
            "type": "number",
            "description": "GB purchased; 0 = unlimited."
          },
          "bandwidthGB": {
            "type": "number"
          },
          "bandwidthLeft": {
            "type": "number"
          },
          "bandwidthLeftGB": {
            "type": "number"
          },
          "bandwidthUsed": {
            "type": "number"
          },
          "bandwidthUsedGB": {
            "type": "number"
          },
          "bandwidthUsagePercent": {
            "type": "integer"
          },
          "isUnlimited": {
            "type": "boolean"
          },
          "expiry": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "isActive": {
            "type": "boolean"
          },
          "isExpired": {
            "type": "boolean"
          },
          "daysRemaining": {
            "type": "integer"
          },
          "hoursRemaining": {
            "type": "integer"
          },
          "ips": {
            "type": "integer"
          },
          "whitelistSlots": {
            "type": "integer"
          },
          "whitelistedIPs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "region": {
            "type": "string"
          },
          "speed": {},
          "highConcurrency": {
            "type": "boolean"
          },
          "highPriority": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "GeneratedProxies": {
        "type": "object",
        "required": [
          "orderId",
          "quantity",
          "protocol",
          "format",
          "rotation",
          "sessionTime",
          "geoTargeting",
          "proxies"
        ],
        "properties": {
          "orderId": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "protocol": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "rotation": {
            "type": "string"
          },
          "sessionTime": {
            "type": "integer"
          },
          "geoTargeting": {
            "type": "object",
            "properties": {
              "country": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "state": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "city": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "proxies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ready-to-use proxy strings in the requested `format` (credentials included)."
          },
          "rotatingProxy": {
            "type": "string",
            "description": "Plans that expose a single rotating endpoint."
          },
          "bandwidth": {
            "type": "number"
          },
          "bandwidthLeft": {
            "type": "number"
          },
          "trafficUsed": {
            "type": "number"
          },
          "whitelist": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ips": {
            "type": "integer"
          },
          "daysRemaining": {
            "type": "integer"
          },
          "hoursRemaining": {
            "type": "integer"
          },
          "port": {},
          "gateway": {
            "type": "string",
            "enum": [
              "ww",
              "us",
              "eu",
              "as"
            ]
          },
          "region": {
            "type": "string"
          },
          "ip": {
            "type": "string"
          },
          "ipAddresses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "currentIpInfo": {
            "type": [
              "object",
              "null"
            ]
          },
          "expiry": {}
        },
        "additionalProperties": true
      },
      "IpInfo": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "countryCode": {
            "type": "string"
          },
          "flag": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "regionCode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "zip": {
            "type": "string"
          },
          "lat": {
            "type": "number"
          },
          "lon": {
            "type": "number"
          },
          "timezone": {
            "type": "string"
          },
          "isp": {
            "type": "string"
          },
          "org": {
            "type": "string"
          },
          "as": {
            "type": "string"
          }
        }
      },
      "UsageDay": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "requests": {
            "type": "integer"
          },
          "by_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Requests per query type (extract, google, bing, map, crawl, batch, unlock, ai, …)."
          },
          "proxy_kb": {
            "type": "number"
          },
          "ai_cost_usd": {
            "type": "number"
          },
          "billed_usd": {
            "type": "number",
            "description": "Wallet part of the spend (total − free)."
          },
          "free_usd": {
            "type": "number"
          }
        }
      },
      "BillingStatus": {
        "type": "object",
        "properties": {
          "billing_enabled": {
            "type": "boolean"
          },
          "billed": {
            "type": "boolean",
            "description": "Whether this key's calls are charged (false for admin keys or when billing is off)."
          },
          "balance": {
            "type": "number"
          },
          "tier": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "discount_pct": {
                "type": "number"
              },
              "rate_limit_per_min": {
                "type": "integer"
              }
            }
          },
          "billing_mode": {
            "type": "object",
            "properties": {
              "preference": {
                "type": "string"
              },
              "effective": {
                "type": "string",
                "enum": [
                  "free_first",
                  "balance"
                ]
              },
              "reason": {
                "type": "string"
              },
              "available": {
                "type": "boolean"
              },
              "free_first_rate_limit_per_min": {
                "type": "integer"
              },
              "balance_rate_limit_per_min": {
                "type": "integer"
              },
              "effective_rate_limit_per_min": {
                "type": "integer"
              }
            }
          },
          "free_monthly_usd": {
            "type": "number"
          },
          "free_remaining_usd": {
            "type": "number"
          },
          "free_tier_blocked_reason": {
            "type": "string",
            "description": "Why the allowance is 0 (e.g. `disposable_email`); absent when conceded."
          },
          "ai_token_markup": {
            "type": "number"
          },
          "prices_usd": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            },
            "description": "The live price list with your tier discount applied — keyed like pricing.json."
          }
        }
      },
      "TrialConfig": {
        "type": "object",
        "required": [
          "brand",
          "enabled",
          "perIpPerDay",
          "perDay",
          "tools"
        ],
        "properties": {
          "brand": {
            "type": "string",
            "enum": [
              "QP",
              "QD"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "perIpPerDay": {
            "type": "integer"
          },
          "perDay": {
            "type": "integer"
          },
          "tools": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/scraper/extract": {
      "post": {
        "operationId": "scrapeUrl",
        "tags": [
          "Scrape"
        ],
        "summary": "Scrape one URL",
        "description": "Fetches one page through the residential pool and returns it as Markdown, HTML or text. Starts on a TLS-fingerprint tier (fast, cheap) and, with `engine: auto`, escalates to a stealth headless browser only when the target blocks; `render: true` (or `engine: render`, `screenshot`, `xhr`, `reveal_hidden`) forces the browser. Binary documents (PDF, DOCX, XLSX, CSV) are converted to text. Optional structured extraction (`extract` CSS schema or a stored `presetId`) and AI extraction (`ai_prompt`/`ai_schema`) run on the same fetch. Pass `html` instead of `url` to convert markup you already have (no fetch, no proxy bandwidth). What it does not do: it does not solve interactive captchas, and `mode: summary` returns no page content (so it cannot be combined with AI extraction). Billed per successful page by the engine that served it, plus a per-GB bandwidth component with a per-call cap; AI extraction adds the `ai_extract` fee plus marked-up LLM tokens. A page flagged as blocked or a target status ≥ 400 is not charged.",
        "x-aliases": [
          "/scrape"
        ],
        "x-price-key": "extract",
        "x-price-keys": [
          "extract",
          "extract_render",
          "ai_extract"
        ],
        "x-pricing-note": "`extract` when the TLS/fetch tier served the page, `extract_render` when the browser did; both carry a perGb meter and a capUsd ceiling (pricing.json → meters). `ai_extract` + LLM tokens × ai_token_markup when ai_prompt/ai_schema is used. The pre-check reserves the worst case (render price unless engine is pinned to tls/fetch without render).",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "http/https URL to scrape. Required unless `html` is given."
                  },
                  "html": {
                    "type": "string",
                    "description": "Markup to convert instead of fetching (max 5 MB)."
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "markdown",
                      "html",
                      "text",
                      "raw"
                    ],
                    "default": "markdown",
                    "description": "`raw` is an alias of `html`. Defaults to markdown (also when AI extraction is requested)."
                  },
                  "formats": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "markdown",
                        "html",
                        "text"
                      ]
                    },
                    "maxItems": 3,
                    "description": "Extra formats returned together under `payload.formats`."
                  },
                  "data_format": {
                    "type": "string",
                    "enum": [
                      "markdown",
                      "screenshot"
                    ],
                    "description": "Compatibility alias: `markdown` sets format, `screenshot` sets `screenshot: fullPage`."
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "tls",
                      "fetch",
                      "render"
                    ],
                    "default": "auto",
                    "description": "`auto` starts on the TLS tier and escalates to the browser on a block; `tls`/`fetch` never escalate; `render` forces the browser."
                  },
                  "autoEscalate": {
                    "type": "boolean",
                    "description": "Allow/forbid the auto engine's escalation to the browser (ignored once the plan's render budget is spent)."
                  },
                  "tlsProfile": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "TLS fingerprint profile for the TLS tier (opaque to the API; see /scraper/unlock for the known names)."
                  },
                  "render": {
                    "type": "boolean",
                    "default": false,
                    "description": "Force the stealth headless browser (JS execution). Bills the render rate."
                  },
                  "mobile": {
                    "type": "boolean",
                    "default": false,
                    "description": "Mobile viewport and user agent."
                  },
                  "waitMs": {
                    "type": "number",
                    "description": "Extra wait after load before capture, render tier (clamped by the service, max 15000)."
                  },
                  "waitForSelector": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "Wait until this CSS selector appears (render tier)."
                  },
                  "scrollToBottom": {
                    "type": "boolean",
                    "default": false,
                    "description": "Auto-scroll to trigger lazy-loaded content (render tier)."
                  },
                  "actions": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "$ref": "#/components/schemas/PageAction"
                    }
                  },
                  "screenshot": {
                    "oneOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "string",
                        "enum": [
                          "fullPage"
                        ]
                      }
                    ],
                    "description": "`true` = viewport PNG, `fullPage` = whole page; forces render. Returned base64 under `screenshot`."
                  },
                  "xhr": {
                    "type": "boolean",
                    "description": "Record the page's XHR/fetch traffic under `xhr` (forces render). Use it to discover which API to target with a `fetchResource` action."
                  },
                  "expect": {
                    "type": "object",
                    "description": "Assertion that the page is the real one: `element` (CSS selector, ≤512 chars) and/or `text` (≤512 chars) must be present, otherwise the fetch is treated as blocked and retried.",
                    "properties": {
                      "element": {
                        "type": "string"
                      },
                      "text": {
                        "type": "string"
                      }
                    }
                  },
                  "extract": {
                    "$ref": "#/components/schemas/ExtractSchema"
                  },
                  "presetId": {
                    "type": "string",
                    "description": "Run a stored parser preset instead of an inline `extract` schema; the run is scored per field for self-healing. 404 if the preset is not yours."
                  },
                  "contentMode": {
                    "type": "string",
                    "enum": [
                      "smart",
                      "article",
                      "full"
                    ],
                    "default": "smart",
                    "description": "`smart` = whole page minus nav/footer/cookie chrome; `article` = Readability main article; `full` = entire body. Alias `content_mode`."
                  },
                  "content_modes": {
                    "type": "array",
                    "maxItems": 3,
                    "items": {
                      "type": "string",
                      "enum": [
                        "smart",
                        "article",
                        "full"
                      ]
                    },
                    "description": "Return several content modes at once under `contents`. Alias `contentModes`."
                  },
                  "fullPage": {
                    "type": "boolean",
                    "description": "Legacy: `true` = contentMode full."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "full",
                      "summary"
                    ],
                    "default": "full",
                    "description": "`summary` drops the content and returns only metadata (title, description, canonical, contentLength, engine, bytes) — the light view for audits over many pages."
                  },
                  "include_links": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also return de-duplicated absolute links under `links`. Alias `includeLinks`."
                  },
                  "app_state": {
                    "oneOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "string",
                        "enum": [
                          "auto",
                          "raw"
                        ]
                      }
                    ],
                    "description": "Mine the page's own hydration state (Next/Nuxt/JSON islands) into `metadata.appState`. `true`/`auto` = pruned to the informative parts; `raw` = full blobs. Alias `appState`."
                  },
                  "parser": {
                    "type": "object",
                    "description": "Caller CSS rules: `include` (scope the content), `exclude` (drop site-specific chrome), `keep` (protect sections from smart stripping). Each an array of ≤25 selectors, ≤200 chars each.",
                    "properties": {
                      "include": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "exclude": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "keep": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "reveal_hidden": {
                    "type": "boolean",
                    "description": "Render tier: open `<details>`/accordions and click through tabs, capturing every panel. Alias `revealHidden`."
                  },
                  "output": {
                    "type": "object",
                    "description": "Markdown shaping; every key also accepted flat (snake_case) at the top level, flat wins.",
                    "properties": {
                      "frontmatter": {
                        "type": "boolean"
                      },
                      "toc": {
                        "type": "boolean"
                      },
                      "linksMode": {
                        "type": "string",
                        "enum": [
                          "inline",
                          "footnote",
                          "strip"
                        ]
                      },
                      "maxTokens": {
                        "type": "number",
                        "minimum": 200,
                        "maximum": 2000000
                      },
                      "imagesMode": {
                        "type": "string",
                        "enum": [
                          "inline",
                          "alt",
                          "strip"
                        ]
                      },
                      "query": {
                        "type": "string",
                        "maxLength": 512,
                        "description": "Relevance filter for LLM-oriented output."
                      },
                      "highlights": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 20,
                        "description": "Most query-relevant passages to return (requires `query`)."
                      },
                      "summarySections": {
                        "type": "boolean"
                      },
                      "chunk": {
                        "type": "object",
                        "properties": {
                          "by": {
                            "type": "string",
                            "enum": [
                              "heading",
                              "sentence",
                              "tokens"
                            ]
                          },
                          "size": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 100000
                          },
                          "overlap": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 100000
                          }
                        }
                      }
                    }
                  },
                  "frontmatter": {
                    "type": "boolean"
                  },
                  "links_mode": {
                    "type": "string",
                    "enum": [
                      "inline",
                      "footnote",
                      "strip"
                    ]
                  },
                  "toc": {
                    "type": "boolean"
                  },
                  "max_tokens": {
                    "type": "number",
                    "minimum": 200,
                    "maximum": 2000000
                  },
                  "images_mode": {
                    "type": "string",
                    "enum": [
                      "inline",
                      "alt",
                      "strip"
                    ]
                  },
                  "query": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "highlights": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20
                  },
                  "chunk": {
                    "type": "object"
                  },
                  "summary_sections": {
                    "type": "boolean"
                  },
                  "ai_prompt": {
                    "type": "string",
                    "description": "Natural-language instruction: the LLM turns the page into structured JSON under `payload.ai.data`."
                  },
                  "ai_schema": {
                    "type": "object",
                    "description": "JSON Schema the AI output must follow (deterministic shape). Either `ai_prompt` or `ai_schema` (or both) enables AI extraction."
                  },
                  "headers": {
                    "$ref": "#/components/schemas/ForwardHeaders"
                  },
                  "cookies": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "maxProperties": 50,
                    "description": "name → value cookies sent to the target."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  },
                  "state": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Requires `country`."
                  },
                  "city": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Requires `country`."
                  },
                  "rotation": {
                    "type": "string",
                    "enum": [
                      "rotating",
                      "sticky"
                    ],
                    "default": "rotating",
                    "description": "New exit IP per request, or keep one IP for the session. Any other value is treated as `rotating`."
                  },
                  "sessionId": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Sticky session id (generated if omitted)."
                  },
                  "sessionDuration": {
                    "type": "number",
                    "description": "Sticky session lifetime in minutes (clamped by the proxy layer, 3–1440, default 10)."
                  }
                }
              },
              "example": {
                "url": "https://example.com/pricing",
                "format": "markdown",
                "country": "us",
                "extract": {
                  "title": "h1",
                  "price": ".price"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Page fetched. `engine` says which tier served it and therefore which price applied.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/ExtractResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Extraction successful",
                  "payload": {
                    "url": "https://example.com/pricing",
                    "finalUrl": "https://example.com/pricing",
                    "status": 200,
                    "contentType": "text/html; charset=utf-8",
                    "format": "markdown",
                    "title": "Pricing — Example",
                    "metadata": {
                      "description": "Simple, transparent pricing.",
                      "canonical": "https://example.com/pricing",
                      "language": "en"
                    },
                    "content": "# Pricing\n\nStarter — $9/month …",
                    "data": {
                      "title": "Pricing",
                      "price": "$9"
                    },
                    "engine": "tls",
                    "attempts": 1,
                    "escalated": false,
                    "bytes": 48213,
                    "durationMs": 1240,
                    "geo": {
                      "country": "us",
                      "state": null,
                      "city": null,
                      "rotation": "rotating"
                    },
                    "usage": {
                      "cost_usd": 0.0002,
                      "free_usd": 0.0002,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "`presetId` does not resolve to one of your presets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Preset not found",
                  "payload": {
                    "url": "https://example.com/"
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Extraction failed on our side or timed out (70 s budget). Never billed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Extraction timed out",
                  "payload": {
                    "url": "https://example.com/"
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/extract' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com/pricing\",\"format\":\"markdown\",\"country\":\"us\",\"extract\":{\"title\":\"h1\",\"price\":\".price\"}}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/extract',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com/pricing\",\n        \"format\": \"markdown\",\n        \"country\": \"us\",\n        \"extract\": {\n            \"title\": \"h1\",\n            \"price\": \".price\"\n        }\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/extract\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/pricing\",\n    \"format\": \"markdown\",\n    \"country\": \"us\",\n    \"extract\": {\n      \"title\": \"h1\",\n      \"price\": \".price\"\n    }\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/extract');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com/pricing',\n    'format' => 'markdown',\n    'country' => 'us',\n    'extract' => [\n      'title' => 'h1',\n      'price' => '.price'\n    ]\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/serp": {
      "post": {
        "operationId": "searchSerp",
        "tags": [
          "Search"
        ],
        "summary": "Structured search results",
        "description": "One search on Google, Bing or DuckDuckGo through the residential pool, returned as JSON in the common SERP-API shape: organic results, ads, People Also Ask, related searches, knowledge panels, AI Overview and 17 Google verticals (`search_type`). Google renders by default so JS-only blocks are populated; pass `render: false` for the cheaper HTTP tier. Identical requests are served from a 24h cache for free (`search_metadata.from_cache`). It does not paginate on your behalf: request one `page` at a time and read `pagination.available_pages`/`has_next`, or use `/scraper/serp/bulk`. Billed per successful search by the tier that served it (`search_metadata.path`); blocked searches answer 429 and cost nothing; `autocomplete` and `reviews` always bill the request price.",
        "x-aliases": [
          "/serp"
        ],
        "x-price-key": "serp",
        "x-price-keys": [
          "serp",
          "serp_render"
        ],
        "x-pricing-note": "Google (except autocomplete/reviews): `serp` when search_metadata.path is `http`, `serp_render` otherwise; Bing/DuckDuckGo: always `serp`. The pre-check reserves `serp_render` for Google.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Search query. Required except for ID-addressed verticals: `place_details` with `place_id`/`data_id`, `product` with `product_id`, `flights`, `lens`, `trends` (no query = trending searches), `reviews` with `data_id`."
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "google",
                      "bing",
                      "duckduckgo"
                    ],
                    "default": "google"
                  },
                  "search_type": {
                    "type": "string",
                    "enum": [
                      "search",
                      "shopping",
                      "images",
                      "news",
                      "places",
                      "maps",
                      "videos",
                      "scholar",
                      "jobs",
                      "autocomplete",
                      "place_details",
                      "hotels",
                      "flights",
                      "events",
                      "product",
                      "lens",
                      "reviews",
                      "trends"
                    ],
                    "default": "search",
                    "description": "Vertical. Alias `type`; Google aliases `tbm` (shop/isch/nws/lcl/vid) and `udm` (28/2/12/1/7) are mapped too."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Proxy exit and engine locale. Alias `gl`."
                  },
                  "lang": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "UI language, e.g. `en`, `it`. Alias `hl`."
                  },
                  "num": {
                    "type": "number",
                    "description": "Results to request (clamped to 1–100 by the service; Google serves ~10 per page and merges pages — see `search_metadata.paging`)."
                  },
                  "page": {
                    "type": "number",
                    "description": "Result page, 1-based."
                  },
                  "start": {
                    "type": "number",
                    "description": "Result offset (alternative to `page`)."
                  },
                  "device": {
                    "type": "string",
                    "enum": [
                      "desktop",
                      "mobile"
                    ],
                    "default": "desktop",
                    "description": "Alias `brd_mobile: 1`."
                  },
                  "render": {
                    "type": "boolean",
                    "description": "Google: renders by default; `false` pins the cheaper HTTP tier. Bing/DuckDuckGo never render by default."
                  },
                  "browser": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox",
                      "safari"
                    ],
                    "description": "Browser profile for the render tier. Alias `brd_browser`."
                  },
                  "safe": {
                    "type": "string",
                    "enum": [
                      "active",
                      "off"
                    ],
                    "description": "SafeSearch."
                  },
                  "nfpr": {
                    "oneOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "integer",
                        "enum": [
                          1
                        ]
                      }
                    ],
                    "description": "Disable auto-corrected results."
                  },
                  "location": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Human-readable search location (\"Milan, Italy\"), encoded to uule server-side."
                  },
                  "uule": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "Encoded uule token OR raw `lat,lon[,radius]`."
                  },
                  "google_params": {
                    "type": "object",
                    "maxProperties": 24,
                    "description": "Escape hatch: extra Google URL params (keys ≤40 chars of letters, digits, `.`, `-`, `_`; values strings ≤512 chars or numbers)."
                  },
                  "jobs": {
                    "type": "boolean",
                    "description": "Jobs box on the main SERP. Alias `ibp: \"htl;jobs\"`."
                  },
                  "place_id": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "`place_details`."
                  },
                  "data_id": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "`place_details` / `reviews` (feature id 0x…:0x…)."
                  },
                  "product_id": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      }
                    ],
                    "description": "`product`: the seller list of one shopping result."
                  },
                  "departure_id": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "`flights`: airport/city code."
                  },
                  "arrival_id": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "outbound_date": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "YYYY-MM-DD."
                  },
                  "return_date": {
                    "type": "string",
                    "maxLength": 10
                  },
                  "check_in_date": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "`hotels`."
                  },
                  "check_out_date": {
                    "type": "string",
                    "maxLength": 10
                  },
                  "adults": {
                    "type": "number",
                    "description": "`hotels`, clamped 1–30."
                  },
                  "children_ages": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "maxItems": 10
                  },
                  "free_cancellation": {
                    "type": "boolean"
                  },
                  "accommodation_type": {
                    "type": "string",
                    "enum": [
                      "hotels",
                      "vacation_rentals"
                    ]
                  },
                  "currency": {
                    "type": "string",
                    "maxLength": 8,
                    "description": "`hotels`/`flights` price currency (USD, EUR…)."
                  },
                  "gps_coordinates": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "`maps`: `lat,lon[,zoom]`."
                  },
                  "image_url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "`lens`: http(s) URL of the image to search by."
                  },
                  "exact_matches": {
                    "type": "boolean",
                    "description": "`lens`."
                  },
                  "sort_by": {
                    "type": "string",
                    "enum": [
                      "relevance",
                      "newest",
                      "highest_rating",
                      "lowest_rating"
                    ],
                    "description": "`reviews`."
                  },
                  "filter": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "`reviews`: keyword filter."
                  },
                  "next_page_token": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "`reviews`: continuation token from `serpapi_pagination`."
                  },
                  "wait_for": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "Render tier: CSS selector to wait for before capture."
                  },
                  "include_html": {
                    "type": "boolean",
                    "description": "Also return the page HTML under `html` (scripts stripped)."
                  },
                  "product_ids": {
                    "type": "boolean",
                    "description": "`shopping`: resolve product ids for each result (slower)."
                  }
                }
              },
              "example": {
                "query": "best coffee grinder",
                "engine": "google",
                "country": "us",
                "lang": "en",
                "num": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search succeeded. The envelope's `pagination` mirrors `payload.pagination`.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/SerpResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "SERP successful",
                  "payload": {
                    "search_metadata": {
                      "status": "Success",
                      "engine": "google",
                      "search_url": "https://www.google.com/search?q=best+coffee+grinder&gl=us&hl=en",
                      "created_at": "2026-10-07T09:12:44.000Z",
                      "total_time_taken": 2.8,
                      "attempts": 1,
                      "bytes": 212544,
                      "path": "http"
                    },
                    "search_parameters": {
                      "engine": "google",
                      "q": "best coffee grinder",
                      "search_type": "search",
                      "device": "desktop",
                      "country": "us",
                      "language": "en",
                      "page": 1
                    },
                    "organic": [
                      {
                        "rank": 1,
                        "title": "The 6 Best Coffee Grinders of 2026",
                        "link": "https://example.com/reviews/coffee-grinders",
                        "display_link": "example.com › reviews",
                        "source": "example.com",
                        "description": "We tested 24 burr grinders…",
                        "date": "12 Sep 2026"
                      }
                    ],
                    "ads": [],
                    "people_also_ask": [
                      {
                        "question": "Is a burr grinder worth it?"
                      }
                    ],
                    "related_searches": [
                      {
                        "query": "best coffee grinder under 100"
                      }
                    ],
                    "ai_overview": null,
                    "knowledge_graph": null,
                    "pagination": {
                      "current": 1,
                      "next": 2,
                      "total_pages": null,
                      "other_pages": {
                        "2": "https://www.google.com/search?q=best+coffee+grinder&start=10"
                      },
                      "available_pages": [
                        1,
                        2,
                        3,
                        4,
                        5
                      ],
                      "has_next": true
                    },
                    "usage": {
                      "cost_usd": 0.0005,
                      "free_usd": 0.0005,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {
                    "current": 1,
                    "next": 2,
                    "total_pages": null,
                    "available_pages": [
                      1,
                      2,
                      3,
                      4,
                      5
                    ],
                    "has_next": true
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "description": "Key/plan rate limit, or the engine blocked every attempt (retryable, never billed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/serp' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\":\"best coffee grinder\",\"engine\":\"google\",\"country\":\"us\",\"lang\":\"en\",\"num\":10}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/serp',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"query\": \"best coffee grinder\",\n        \"engine\": \"google\",\n        \"country\": \"us\",\n        \"lang\": \"en\",\n        \"num\": 10\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/serp\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"query\": \"best coffee grinder\",\n    \"engine\": \"google\",\n    \"country\": \"us\",\n    \"lang\": \"en\",\n    \"num\": 10\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/serp');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'query' => 'best coffee grinder',\n    'engine' => 'google',\n    'country' => 'us',\n    'lang' => 'en',\n    'num' => 10\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/serp/bulk": {
      "post": {
        "operationId": "startSerpBulk",
        "tags": [
          "Search"
        ],
        "summary": "Start a multi-page search job",
        "description": "Paginates one query across up to 10 result pages asynchronously, riding real pagination on one session. Returns a job id immediately; poll `GET /scraper/serp/bulk/{jobId}` for the merged, de-duplicated organic results as pages land, or pass a `webhook` to receive the finished job. Only web-type verticals (search, news, videos, images, shopping) are supported here. Charged up front for `max_pages`; pages the query does not have are refunded when the job settles.",
        "x-aliases": [
          "/serp/bulk"
        ],
        "x-price-key": "serp_render",
        "x-price-keys": [
          "serp",
          "serp_render"
        ],
        "x-pricing-note": "Google: `serp_render` × max_pages up front; Bing/DuckDuckGo: `serp` × max_pages. Unfetched pages refunded at settlement.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "google",
                      "bing",
                      "duckduckgo"
                    ],
                    "default": "google"
                  },
                  "search_type": {
                    "type": "string",
                    "enum": [
                      "search",
                      "news",
                      "videos",
                      "images",
                      "shopping"
                    ],
                    "default": "search",
                    "description": "Alias `type`."
                  },
                  "max_pages": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 5
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Alias `gl`."
                  },
                  "lang": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "Alias `hl`."
                  },
                  "device": {
                    "type": "string",
                    "enum": [
                      "desktop",
                      "mobile"
                    ],
                    "description": "Alias `brd_mobile: 1`."
                  },
                  "render": {
                    "type": "boolean"
                  },
                  "wait_for": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "browser": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox",
                      "safari"
                    ]
                  },
                  "safe": {
                    "type": "string",
                    "enum": [
                      "active",
                      "off"
                    ]
                  },
                  "nfpr": {
                    "oneOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "integer",
                        "enum": [
                          1
                        ]
                      }
                    ]
                  },
                  "uule": {
                    "type": "string",
                    "maxLength": 512
                  },
                  "location": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "google_params": {
                    "type": "object",
                    "maxProperties": 24
                  },
                  "webhook": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Public http(s) URL that receives the finished job by POST."
                  }
                }
              },
              "example": {
                "query": "best coffee grinder",
                "engine": "google",
                "country": "us",
                "max_pages": 3
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/JobStarted"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Bulk SERP started",
                  "payload": {
                    "id": "sb_4d1e9c",
                    "status": "running",
                    "query": "best coffee grinder",
                    "total": 3,
                    "completed": 0,
                    "statusUrl": "/api/v1/scraper/serp/bulk/sb_4d1e9c",
                    "usage": {
                      "cost_usd": 0.006,
                      "free_usd": 0.006,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/serp/bulk' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\":\"best coffee grinder\",\"engine\":\"google\",\"country\":\"us\",\"max_pages\":3}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/serp/bulk',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"query\": \"best coffee grinder\",\n        \"engine\": \"google\",\n        \"country\": \"us\",\n        \"max_pages\": 3\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/serp/bulk\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"query\": \"best coffee grinder\",\n    \"engine\": \"google\",\n    \"country\": \"us\",\n    \"max_pages\": 3\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/serp/bulk');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'query' => 'best coffee grinder',\n    'engine' => 'google',\n    'country' => 'us',\n    'max_pages' => 3\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/serp/bulk/{jobId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "get": {
        "operationId": "getSerpBulk",
        "tags": [
          "Search"
        ],
        "summary": "Poll a multi-page search job",
        "description": "Progress and merged organic results of a bulk search job you own. Pass the previous response's `nextCursor` as `since` to receive only new rows. Jobs are kept about an hour after they finish. Free to poll.",
        "x-aliases": [
          "/serp/bulk/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Organic cursor from the previous poll's `nextCursor`."
          }
        ],
        "responses": {
          "200": {
            "description": "Job view.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/SerpBulkJob"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Bulk SERP status",
                  "payload": {
                    "id": "sb_4d1e9c",
                    "status": "completed",
                    "query": "best coffee grinder",
                    "total": 3,
                    "completed": 3,
                    "failed": 0,
                    "pages": [
                      {
                        "page": 1,
                        "organic_count": 10,
                        "bytes": 210331,
                        "path": "http"
                      },
                      {
                        "page": 2,
                        "organic_count": 10,
                        "bytes": 198002,
                        "path": "http"
                      },
                      {
                        "page": 3,
                        "organic_count": 9,
                        "bytes": 190114,
                        "path": "http"
                      }
                    ],
                    "organic": [
                      {
                        "rank": 1,
                        "title": "The 6 Best Coffee Grinders of 2026",
                        "link": "https://example.com/reviews/coffee-grinders",
                        "display_link": "example.com",
                        "description": "…"
                      }
                    ],
                    "related_searches": [],
                    "ai_overview": null,
                    "nextCursor": 29,
                    "createdAt": 1759828364000,
                    "finishedAt": 1759828391000
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "cancelSerpBulk",
        "tags": [
          "Search"
        ],
        "summary": "Cancel a multi-page search job",
        "description": "Stops a running bulk search job you own. Pages never fetched are refunded at settlement.",
        "x-aliases": [
          "/serp/bulk/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Bulk SERP cancelled",
                  "payload": {
                    "id": "sb_4d1e9c",
                    "status": "cancelled"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/serp/bulk/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/map": {
      "post": {
        "operationId": "mapSite",
        "tags": [
          "Map & Crawl"
        ],
        "summary": "Discover a site's URLs",
        "description": "Merges robots.txt sitemaps, /sitemap.xml (nested indexes included) and same-domain homepage links into one de-duplicated list, synchronously. Returns up to `limit` URLs plus the site-wide `total` and a per-section `summary`; `group_by: path` returns the path tree instead of the list. It does not fetch page bodies — pair it with /scraper/batch for that. One flat price per call.",
        "x-aliases": [
          "/map"
        ],
        "x-price-key": "map",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Seed URL."
                  },
                  "limit": {
                    "type": "number",
                    "default": 100,
                    "description": "Max URLs to return (service cap 5000)."
                  },
                  "search": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Only return URLs containing this substring."
                  },
                  "includeSubdomains": {
                    "type": "boolean",
                    "default": false
                  },
                  "sitemapOnly": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip the homepage link scrape."
                  },
                  "group_by": {
                    "type": "string",
                    "enum": [
                      "path"
                    ],
                    "description": "Return the path tree with counts instead of the URL list. Alias `groupBy`."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  }
                }
              },
              "example": {
                "url": "https://example.com",
                "limit": 100,
                "search": "blog"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "URLs discovered.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/MapResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Map successful",
                  "payload": {
                    "url": "https://example.com",
                    "links": [
                      "https://example.com/blog/",
                      "https://example.com/blog/how-to-scrape"
                    ],
                    "count": 100,
                    "total": 2417,
                    "summary": {
                      "/blog": 1988,
                      "/docs": 240,
                      "/": 1
                    },
                    "sources": {
                      "sitemap": 2410,
                      "homepage": 42
                    },
                    "durationMs": 3120,
                    "geo": {
                      "country": null
                    },
                    "usage": {
                      "cost_usd": 0.0005,
                      "free_usd": 0.0005,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/map' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com\",\"limit\":100,\"search\":\"blog\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/map',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com\",\n        \"limit\": 100,\n        \"search\": \"blog\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/map\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com\",\n    \"limit\": 100,\n    \"search\": \"blog\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/map');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com',\n    'limit' => 100,\n    'search' => 'blog'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/crawl": {
      "post": {
        "operationId": "startCrawl",
        "tags": [
          "Map & Crawl"
        ],
        "summary": "Start a site crawl",
        "description": "Breadth-first crawl from a seed URL through the residential pool, each page converted to the requested format. Returns a job id immediately; poll `GET /scraper/crawl/{jobId}`. Charged up front on `limit` pages (render price per page with `render: true`); unfetched or failed pages are refunded when the job settles. A render crawl takes one browser-render token at submission and its pages then queue on the plan's render concurrency.",
        "x-aliases": [
          "/crawl"
        ],
        "x-price-key": "crawl_page",
        "x-price-keys": [
          "crawl_page",
          "extract_render"
        ],
        "x-pricing-note": "`crawl_page` × min(limit, 500) up front, or `extract_render` × pages when render is true. Refund of the unfetched share at settlement.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Seed URL."
                  },
                  "limit": {
                    "type": "number",
                    "default": 50,
                    "description": "Max pages (cap 500). Billed on this up front."
                  },
                  "depth": {
                    "type": "number",
                    "default": 3,
                    "description": "Max link depth from the seed (cap 10)."
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "markdown",
                      "html",
                      "text"
                    ],
                    "default": "markdown"
                  },
                  "contentMode": {
                    "type": "string",
                    "enum": [
                      "smart",
                      "article",
                      "full"
                    ],
                    "default": "smart",
                    "description": "Alias `content_mode`."
                  },
                  "render": {
                    "type": "boolean",
                    "default": false,
                    "description": "Render every page with the stealth browser (slower, rendered rate)."
                  },
                  "sameDomain": {
                    "type": "boolean",
                    "default": true
                  },
                  "allowSubdomains": {
                    "type": "boolean",
                    "default": false
                  },
                  "include": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 256
                    },
                    "description": "URL substrings/globs to include, e.g. [\"/guides/*\"]."
                  },
                  "exclude": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 256
                    }
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  }
                }
              },
              "example": {
                "url": "https://docs.example.com",
                "limit": 50,
                "depth": 3,
                "include": [
                  "/guides/*"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Crawl started.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/JobStarted"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Crawl started",
                  "payload": {
                    "id": "cr_d5b8a1",
                    "status": "running",
                    "seed": "https://docs.example.com/",
                    "limit": 50,
                    "depth": 3,
                    "format": "markdown",
                    "pagesCrawled": 0,
                    "pagesQueued": 1,
                    "statusUrl": "/api/v1/scraper/crawl/cr_d5b8a1",
                    "usage": {
                      "cost_usd": 0.015,
                      "free_usd": 0.015,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/crawl' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://docs.example.com\",\"limit\":50,\"depth\":3,\"include\":[\"/guides/*\"]}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/crawl',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://docs.example.com\",\n        \"limit\": 50,\n        \"depth\": 3,\n        \"include\": [\n            \"/guides/*\"\n        ]\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/crawl\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://docs.example.com\",\n    \"limit\": 50,\n    \"depth\": 3,\n    \"include\": [\n      \"/guides/*\"\n    ]\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/crawl');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://docs.example.com',\n    'limit' => 50,\n    'depth' => 3,\n    'include' => ['/guides/*']\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/crawl/{jobId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "get": {
        "operationId": "getCrawl",
        "tags": [
          "Map & Crawl"
        ],
        "summary": "Poll a crawl job",
        "description": "Progress and crawled pages of a job you own. Use `since` (the previous `nextCursor`) to page a large crawl and `include_content=false` for cheap status checks. Jobs are kept about an hour after they finish. Free to poll.",
        "x-aliases": [
          "/crawl/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Page cursor from the previous poll's `nextCursor`."
          },
          {
            "name": "include_content",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "Omit to get the full job; `false` strips page content."
          }
        ],
        "responses": {
          "200": {
            "description": "Job view.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/CrawlJob"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Crawl status",
                  "payload": {
                    "id": "cr_d5b8a1",
                    "status": "completed",
                    "seed": "https://docs.example.com/",
                    "limit": 50,
                    "depth": 3,
                    "format": "markdown",
                    "pagesCrawled": 37,
                    "pagesQueued": 0,
                    "pages": [
                      {
                        "url": "https://docs.example.com/guides/getting-started",
                        "status": 200,
                        "title": "Getting started",
                        "depth": 1,
                        "content": "# Getting started\n…"
                      }
                    ],
                    "nextCursor": 37,
                    "hasMore": false,
                    "createdAt": 1759828364000,
                    "finishedAt": 1759828512000
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "cancelCrawl",
        "tags": [
          "Map & Crawl"
        ],
        "summary": "Cancel a crawl job",
        "description": "Stops a running crawl you own; pages never fetched are refunded at settlement.",
        "x-aliases": [
          "/crawl/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Crawl cancelled",
                  "payload": {
                    "id": "cr_d5b8a1",
                    "status": "cancelled"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/crawl/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/batch": {
      "post": {
        "operationId": "startBatch",
        "tags": [
          "Batch"
        ],
        "summary": "Scrape many URLs asynchronously",
        "description": "Up to 5,000 URLs you already know, with shared options, run concurrently through the residential pool. Returns a job id immediately; poll `GET /scraper/batch/{jobId}` or pass a `webhook` to receive the finished job by POST. Charged up front per URL (render price with `render: true` or `engine: render`); the failed/blocked share is refunded when the job settles. A render batch takes one browser-render token at submission.",
        "x-aliases": [
          "/batch"
        ],
        "x-price-key": "batch_url",
        "x-price-keys": [
          "batch_url",
          "extract_render"
        ],
        "x-pricing-note": "`batch_url` × urls up front (or `extract_render` × urls when rendering). Failed URLs refunded at settlement.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "urls"
                ],
                "properties": {
                  "urls": {
                    "type": "array",
                    "minItems": 1,
                    "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,
                    "description": "Force the headless browser for every URL."
                  },
                  "extract": {
                    "$ref": "#/components/schemas/ExtractSchema"
                  },
                  "contentMode": {
                    "type": "string",
                    "enum": [
                      "smart",
                      "article",
                      "full"
                    ],
                    "default": "smart",
                    "description": "Alias `content_mode`."
                  },
                  "fullPage": {
                    "type": "boolean",
                    "description": "Legacy: contentMode full."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "full",
                      "summary"
                    ],
                    "default": "full",
                    "description": "`summary` stores per-URL metadata only (title, description, canonical, contentLength)."
                  },
                  "concurrency": {
                    "type": "number",
                    "default": 5,
                    "minimum": 1,
                    "maximum": 20,
                    "description": "Simultaneous fetches (clamped 1–20; your tier's batch concurrency also applies)."
                  },
                  "webhook": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Public http(s) URL that receives the finished job by POST."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  }
                }
              },
              "example": {
                "urls": [
                  "https://example.com/a",
                  "https://example.com/b"
                ],
                "format": "markdown",
                "mode": "summary"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch started.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/JobStarted"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Batch started",
                  "payload": {
                    "id": "bt_91ac07",
                    "status": "running",
                    "total": 2,
                    "completed": 0,
                    "failed": 0,
                    "statusUrl": "/api/v1/scraper/batch/bt_91ac07",
                    "usage": {
                      "cost_usd": 0.0004,
                      "free_usd": 0.0004,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/batch' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"urls\":[\"https://example.com/a\",\"https://example.com/b\"],\"format\":\"markdown\",\"mode\":\"summary\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/batch',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"urls\": [\n            \"https://example.com/a\",\n            \"https://example.com/b\"\n        ],\n        \"format\": \"markdown\",\n        \"mode\": \"summary\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/batch\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"urls\": [\n      \"https://example.com/a\",\n      \"https://example.com/b\"\n    ],\n    \"format\": \"markdown\",\n    \"mode\": \"summary\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/batch');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'urls' => ['https://example.com/a', 'https://example.com/b'],\n    'format' => 'markdown',\n    'mode' => 'summary'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/batch/{jobId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "get": {
        "operationId": "getBatch",
        "tags": [
          "Batch"
        ],
        "summary": "Poll a batch job",
        "description": "Progress and per-URL results of a job you own. Polls return metadata only unless `include_content=true`; pass the previous `nextCursor` as `since` to receive only newer items. Jobs are kept about an hour after they finish. Free to poll.",
        "x-aliases": [
          "/batch/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Item cursor from the previous poll's `nextCursor`."
          },
          {
            "name": "include_content",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "`true` includes each item's page content."
          }
        ],
        "responses": {
          "200": {
            "description": "Job view.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/BatchJob"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Batch status",
                  "payload": {
                    "id": "bt_91ac07",
                    "status": "completed",
                    "total": 2,
                    "completed": 2,
                    "failed": 0,
                    "contentTruncated": false,
                    "items": [
                      {
                        "url": "https://example.com/a",
                        "status": 200,
                        "title": "Page A",
                        "description": "…",
                        "canonical": "https://example.com/a",
                        "contentLength": 5120,
                        "engine": "tls",
                        "bytes": 31870
                      },
                      {
                        "url": "https://example.com/b",
                        "status": 200,
                        "title": "Page B",
                        "description": null,
                        "canonical": null,
                        "contentLength": 2210,
                        "engine": "tls",
                        "bytes": 12003
                      }
                    ],
                    "nextCursor": 2,
                    "hasMore": false,
                    "createdAt": 1759828364000,
                    "finishedAt": 1759828370000
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "cancelBatch",
        "tags": [
          "Batch"
        ],
        "summary": "Cancel a batch job",
        "description": "Stops a running batch you own; URLs never fetched are refunded at settlement.",
        "x-aliases": [
          "/batch/{jobId}"
        ],
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Batch cancelled",
                  "payload": {
                    "id": "bt_91ac07",
                    "status": "cancelled"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/batch/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/unlock": {
      "post": {
        "operationId": "unlockRequest",
        "tags": [
          "Web Unlocker"
        ],
        "summary": "Replay a request through the Web Unlocker",
        "description": "Send a request the way your own HTTP client would (url, method, headers, body) and get it back replayed through a residential (or mobile) exit under a real browser TLS fingerprint. GET/HEAD/OPTIONS retry on a fresh exit IP under a different fingerprint when blocked and finally escalate to a headless browser that answers JavaScript challenges; any other method gets exactly one attempt (a response means the target saw it, and replaying a POST could double-submit). A still-blocked page is returned with `blocked: true`, `blockClass` and `vendor`, never as a silent success; `failOnBlock: true` turns that into a 502. It does not solve interactive captchas. This is the same engine as the CONNECT forward proxy, without the proxy protocol — no certificate to install. Billing is different from every other Data API call: it is metered in bytes against the tier's prepaid Web Unlocker GB (`premium` = residential exits, `mobile` = mobile exits), not the wallet, and every attempt counts — retries, a blocked page, the browser escalation's page load.",
        "x-price-key": "unlock_request",
        "x-pricing-note": "Flat base is 0; the whole charge is the `unlock_request` perGb meter applied to `usage.bytes`, debited from the prepaid unlocker GB of the chosen tier. No wallet charge, no free tier. 402 when the tier's GB are exhausted or expired.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "method": {
                    "type": "string",
                    "pattern": "^[A-Za-z]{1,16}$",
                    "default": "GET"
                  },
                  "headers": {
                    "$ref": "#/components/schemas/ForwardHeaders",
                    "description": "Headers your own client would send. Most are replaced by a coherent browser fingerprint (User-Agent, Accept, Sec-Fetch-*); auth, cookie, content-type and custom headers are forwarded verbatim. `keepHeaders: true` forwards everything as-is."
                  },
                  "body": {
                    "type": "string",
                    "description": "Request body as UTF-8 text (JSON, form data…). Use this OR `bodyBase64`."
                  },
                  "bodyBase64": {
                    "type": "string",
                    "description": "Request body as base64 for binary payloads. Max 8 MB decoded."
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "premium",
                      "mobile"
                    ],
                    "default": "premium",
                    "description": "Which prepaid pool pays and which exits are used. Anything other than `mobile` is `premium`."
                  },
                  "tlsProfile": {
                    "type": "string",
                    "enum": [
                      "chrome",
                      "firefox",
                      "safari",
                      "safari_ios",
                      "edge",
                      "brave",
                      "mobile"
                    ],
                    "default": "chrome"
                  },
                  "mobile": {
                    "type": "boolean",
                    "default": false,
                    "description": "Mobile Safari fingerprint (fingerprint only — the product tier is `tier`)."
                  },
                  "render": {
                    "oneOf": [
                      {
                        "type": "string",
                        "enum": [
                          "html",
                          "png"
                        ]
                      },
                      {
                        "type": "boolean"
                      }
                    ],
                    "description": "`html`/`png` (or `true` = html) runs the page in a headless browser instead of the TLS tier, GET/HEAD only, one render token. `false` pins the TLS tier: a blocked page is returned as-is, never escalated."
                  },
                  "autoRender": {
                    "type": "boolean",
                    "default": true,
                    "description": "Escalate a blocked GET to the browser."
                  },
                  "keepHeaders": {
                    "type": "boolean",
                    "default": false
                  },
                  "successStatusCodes": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "integer",
                      "minimum": 100,
                      "maximum": 599
                    },
                    "description": "Origin statuses to accept as success — never treated as a block, never retried."
                  },
                  "timeoutMs": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 120000,
                    "description": "Per-attempt timeout at the target (capped by the service's 90 s total budget)."
                  },
                  "failOnBlock": {
                    "type": "boolean",
                    "default": false,
                    "description": "502 instead of a 200 with `blocked: true`. GB are debited either way."
                  },
                  "waitForSelector": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Browser tier: CSS selector to wait for before capture."
                  },
                  "waitMs": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 15000
                  },
                  "returnCookies": {
                    "type": "boolean",
                    "default": false,
                    "description": "Return the origin's cookie jar under `cookies`."
                  },
                  "cookies": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "maxProperties": 50,
                    "description": "Cookies merged into the Cookie header sent to the target (e.g. a clearance obtained earlier)."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  },
                  "state": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Requires `country`."
                  },
                  "city": {
                    "$ref": "#/components/schemas/GeoValue",
                    "description": "Requires `country`."
                  },
                  "rotation": {
                    "type": "string",
                    "enum": [
                      "rotating",
                      "sticky"
                    ],
                    "default": "rotating"
                  },
                  "sessionId": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Sticky session id — reuse it across calls to keep one exit IP."
                  },
                  "sessionDuration": {
                    "type": "number",
                    "description": "Sticky session lifetime in minutes."
                  }
                }
              },
              "example": {
                "url": "https://example.com/api/search?q=shoes",
                "method": "GET",
                "headers": {
                  "Accept": "application/json"
                },
                "country": "us",
                "tier": "premium"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The origin's response (possibly a block page, see `blocked`).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/UnlockResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Unlocker request successful",
                  "payload": {
                    "status": 200,
                    "headers": {
                      "content-type": "application/json; charset=utf-8",
                      "cache-control": "no-store"
                    },
                    "body": "{\"results\":[{\"id\":1,\"name\":\"Runner\"}]}",
                    "bodyBase64": "eyJyZXN1bHRzIjpbeyJpZCI6MSwibmFtZSI6IlJ1bm5lciJ9XX0=",
                    "finalUrl": "https://example.com/api/search?q=shoes",
                    "contentType": "application/json; charset=utf-8",
                    "profile": "chrome",
                    "attempts": 1,
                    "blocked": false,
                    "clearance": "miss",
                    "exitSessionId": "s_2f91",
                    "strategy": {
                      "startTier": "tls",
                      "hedged": false
                    },
                    "rendered": false,
                    "escalated": false,
                    "tier": "premium",
                    "geo": {
                      "country": "us",
                      "state": null,
                      "city": null,
                      "rotation": "rotating"
                    },
                    "usage": {
                      "bytes": 18432,
                      "unlock_gb_remaining": 4.98,
                      "unlock_gb_purchased": 5
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "The tier's prepaid unlocker GB are exhausted or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Web Unlocker premium bandwidth exhausted. Buy more unlocker GB to keep using it.",
                  "payload": {
                    "tier": "premium",
                    "unlock_gb_remaining": 0,
                    "unlock_gb_purchased": 5,
                    "expires_at": "2026-11-01T00:00:00.000Z",
                    "expired": false
                  }
                }
              }
            }
          },
          "403": {
            "description": "No exit pool for the requested tier (e.g. no mobile unlocker GB on the account).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "502": {
            "description": "Only with `failOnBlock: true`: every tier came back blocked. Same diagnostics as the 200 form; the GB moved are debited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Target blocked the request: js_challenge",
                  "payload": {
                    "status": 403,
                    "blockReason": "js_challenge",
                    "blockClass": "js_challenge",
                    "vendor": "cloudflare",
                    "attempts": 3,
                    "rendered": true,
                    "escalated": true,
                    "usage": {
                      "bytes": 90112,
                      "unlock_gb_remaining": 4.97,
                      "unlock_gb_purchased": 5
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/unlock' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com/api/search?q=shoes\",\"method\":\"GET\",\"headers\":{\"Accept\":\"application/json\"},\"country\":\"us\",\"tier\":\"premium\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/unlock',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com/api/search?q=shoes\",\n        \"method\": \"GET\",\n        \"headers\": {\n            \"Accept\": \"application/json\"\n        },\n        \"country\": \"us\",\n        \"tier\": \"premium\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/unlock\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/api/search?q=shoes\",\n    \"method\": \"GET\",\n    \"headers\": {\n      \"Accept\": \"application/json\"\n    },\n    \"country\": \"us\",\n    \"tier\": \"premium\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/unlock');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com/api/search?q=shoes',\n    'method' => 'GET',\n    'headers' => [\n      'Accept' => 'application/json'\n    ],\n    'country' => 'us',\n    'tier' => 'premium'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/unlock/ca": {
      "get": {
        "operationId": "downloadUnlockerCa",
        "tags": [
          "Web Unlocker"
        ],
        "summary": "Download the unlocker CA certificate",
        "description": "The interception CA used by the Web Unlocker forward proxy (CONNECT mode). The proxy terminates your TLS to read and rewrite the request, so an HTTP client that keeps certificate verification on must trust this file for the target host (`curl --proxy-cacert qp-unlocker-ca.pem --cacert qp-unlocker-ca.pem …`). Not needed for POST /scraper/unlock, nor for the proxy's direct mode. Public by nature, kept behind the key so downloads are attributable. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "PEM certificate (attachment `qp-unlocker-ca.pem`, cacheable 1h).",
            "content": {
              "application/x-pem-file": {
                "schema": {
                  "type": "string"
                },
                "example": "-----BEGIN CERTIFICATE-----\nMIIB…\n-----END CERTIFICATE-----\n"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "description": "The certificate could not be fetched from the unlocker service right now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Unlocker certificate is temporarily unavailable"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/unlock/ca' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/unlock/ca',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\nr.raise_for_status()\nopen(\"response.out\", \"wb\").write(r.content)",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/unlock/ca\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst bytes = Buffer.from(await res.arrayBuffer());\nrequire(\"node:fs\").writeFileSync(\"response.out\", bytes);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/unlock/ca');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\nfile_put_contents('response.out', $raw);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/ai": {
      "post": {
        "operationId": "aiAgent",
        "tags": [
          "AI extraction"
        ],
        "summary": "Natural-language scraping agent",
        "description": "Describe a task in plain English; a model drives the scraper API as a tool — formats the request, fetches the page(s) through residential proxies, can search and map when the task needs it, and returns the extracted JSON under `data` with the pages it visited under `steps`. Use it when you do not want to write selectors or a schema; use /scraper/extract with `extract`/`ai_schema` when you already know the page. Not deterministic and not the cheapest path for repeated layouts (see /scraper/parser/generate). Billed as the `ai_extract` base fee plus one `extract` per page fetched, `serp` per search, `map` per map, plus LLM tokens × ai_token_markup, capped at the `ai_extract` meter's capUsd; the pre-check reserves that cap.",
        "x-price-key": "ai_extract",
        "x-price-keys": [
          "ai_extract",
          "extract",
          "serp",
          "map"
        ],
        "x-pricing-note": "ai_extract + steps × extract + searches × serp + mapped × map + tokens × ai_token_markup, capped at meters.ai_extract.capUsd.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "task"
                ],
                "properties": {
                  "task": {
                    "type": "string",
                    "description": "Plain-English instruction, e.g. \"get every product with its name and price from this page\"."
                  },
                  "url": {
                    "type": "string",
                    "description": "Starting URL, if the task does not already contain one."
                  }
                }
              },
              "example": {
                "task": "Get every plan and its monthly price",
                "url": "https://example.com/pricing"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extraction finished.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/AiAgentResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "AI extraction successful",
                  "payload": {
                    "data": {
                      "plans": [
                        {
                          "name": "Starter",
                          "price_usd": 9
                        },
                        {
                          "name": "Growth",
                          "price_usd": 29
                        }
                      ]
                    },
                    "steps": [
                      {
                        "url": "https://example.com/pricing",
                        "status": 200,
                        "engine": "tls"
                      }
                    ],
                    "searches": 0,
                    "mapped": 0,
                    "model": "gpt-4o-mini",
                    "bytes": 48213,
                    "usage": {
                      "input_tokens": 3120,
                      "output_tokens": 180,
                      "cost_usd": 0.0019,
                      "free_usd": 0.0019,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "Missing task, or the agent reported a client-side problem (bad URL, page unusable).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Agent failure or the AI agent is not configured on this instance. Never billed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/ai' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"task\":\"Get every plan and its monthly price\",\"url\":\"https://example.com/pricing\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/ai',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"task\": \"Get every plan and its monthly price\",\n        \"url\": \"https://example.com/pricing\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/ai\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"task\": \"Get every plan and its monthly price\",\n    \"url\": \"https://example.com/pricing\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/ai');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'task' => 'Get every plan and its monthly price',\n    'url' => 'https://example.com/pricing'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/places-ai": {
      "post": {
        "operationId": "aiPlacesFinder",
        "tags": [
          "AI extraction"
        ],
        "summary": "AI Places Finder",
        "description": "Describe what you are looking for (\"find every car repair shop in Naples\"); the model crafts the Google local queries, paginates, de-duplicates and returns the aggregated businesses, optionally enriched from each knowledge panel (phone, website, hours, full address). For a deterministic, per-row-priced alternative use the `google_maps_places` collector. Billed as the `places_ai` base plus `serp_render` per search run plus LLM tokens × ai_token_markup, capped at the `places_ai` meter's capUsd; the pre-check reserves that cap.",
        "x-price-key": "places_ai",
        "x-price-keys": [
          "places_ai",
          "serp_render"
        ],
        "x-pricing-note": "places_ai + searches × serp_render + tokens × ai_token_markup, capped at meters.places_ai.capUsd.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "task"
                ],
                "properties": {
                  "task": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "description": "ISO country override for the proxy exit and `gl`."
                  },
                  "enrich": {
                    "type": "boolean",
                    "default": true,
                    "description": "Fill phone/website/hours/address from each business's knowledge panel."
                  },
                  "max_enrich": {
                    "type": "number",
                    "default": 15,
                    "description": "Knowledge-panel lookups budget (cap 30)."
                  }
                }
              },
              "example": {
                "task": "find every car repair shop in Naples",
                "country": "it",
                "max_enrich": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Places found.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/AiFinderResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Places search successful",
                  "payload": {
                    "places": [
                      {
                        "name": "Autofficina Esposito",
                        "rating": 4.6,
                        "reviews": 212,
                        "address": "Via Toledo 12, 80134 Napoli NA",
                        "phone": "+39 081 000 0000",
                        "website": "https://example.it"
                      }
                    ],
                    "total": 38,
                    "enriched": 10,
                    "queries": [
                      "autofficina Napoli",
                      "meccanico Napoli"
                    ],
                    "summary": "38 repair shops across central Naples.",
                    "model": "gpt-4o-mini",
                    "usage": {
                      "input_tokens": 9800,
                      "output_tokens": 2200,
                      "cost_usd": 0.0218,
                      "free_usd": 0.0218,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Finder failure or not configured on this instance. Never billed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/places-ai' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"task\":\"find every car repair shop in Naples\",\"country\":\"it\",\"max_enrich\":10}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/places-ai',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"task\": \"find every car repair shop in Naples\",\n        \"country\": \"it\",\n        \"max_enrich\": 10\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/places-ai\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"task\": \"find every car repair shop in Naples\",\n    \"country\": \"it\",\n    \"max_enrich\": 10\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/places-ai');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'task' => 'find every car repair shop in Naples',\n    'country' => 'it',\n    'max_enrich' => 10\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/shopping-ai": {
      "post": {
        "operationId": "aiShoppingFinder",
        "tags": [
          "AI extraction"
        ],
        "summary": "AI Shopping Finder",
        "description": "Describe the product (\"find the cheapest Nintendo Switch OLED in Italy\"); the model crafts Google Shopping queries, paginates, de-duplicates and returns the aggregated products with merchant and price. For a deterministic alternative use /scraper/serp with `search_type: shopping` or the `google_shopping` collector. Billed as the `shopping_ai` base plus `serp_render` per search plus LLM tokens × ai_token_markup, capped at the `shopping_ai` meter's capUsd; the pre-check reserves that cap.",
        "x-price-key": "shopping_ai",
        "x-price-keys": [
          "shopping_ai",
          "serp_render"
        ],
        "x-pricing-note": "shopping_ai + searches × serp_render + tokens × ai_token_markup, capped at meters.shopping_ai.capUsd.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "task"
                ],
                "properties": {
                  "task": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "description": "ISO country override for the proxy exit, `gl` and currency."
                  }
                }
              },
              "example": {
                "task": "cheapest Nintendo Switch OLED",
                "country": "it"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Products found.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/AiFinderResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Shopping search successful",
                  "payload": {
                    "products": [
                      {
                        "title": "Nintendo Switch OLED Bianco",
                        "price": "€ 299,00",
                        "merchant": "Example Store",
                        "link": "https://example.it/p/switch-oled"
                      }
                    ],
                    "total": 24,
                    "queries": [
                      "Nintendo Switch OLED prezzo"
                    ],
                    "searches": [
                      {
                        "query": "Nintendo Switch OLED prezzo",
                        "results": 24
                      }
                    ],
                    "summary": "Lowest price €299 at Example Store.",
                    "model": "gpt-4o-mini",
                    "usage": {
                      "input_tokens": 7100,
                      "output_tokens": 900,
                      "cost_usd": 0.0121,
                      "free_usd": 0.0121,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "description": "Finder failure or not configured on this instance. Never billed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/shopping-ai' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"task\":\"cheapest Nintendo Switch OLED\",\"country\":\"it\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/shopping-ai',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"task\": \"cheapest Nintendo Switch OLED\",\n        \"country\": \"it\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/shopping-ai\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"task\": \"cheapest Nintendo Switch OLED\",\n    \"country\": \"it\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/shopping-ai');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'task' => 'cheapest Nintendo Switch OLED',\n    'country' => 'it'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/ai-visibility": {
      "post": {
        "operationId": "aiVisibilityAudit",
        "tags": [
          "AI visibility"
        ],
        "summary": "AI visibility audit",
        "description": "Answers one question about a page — can an AI assistant read it, and does it cite it? — on two levels. On-page (always): AI crawler access from the real robots.txt (24 bots), Content-Signal, a fetch that identifies itself as an AI crawler, noindex/nosnippet/noai directives, text without JavaScript, structured data and resolvable entities, citable form (questions, opening answer, lists/tables, numbers, chunk-sized sections), dated and authored content — scored per pillar with blockers that cap the total and the evidence behind every check. Citations (only when `queries` is given): the questions are really asked to Perplexity, ChatGPT, Claude, Google AI Overview, Bing Copilot and a DeepSeek-over-Google-SERP engine, and the answer reports who is cited or at least mentioned, plus share of voice against `competitors`. It does not change the page and the citation panel is capped at 10 queries per call and a daily per-account cap on LLM engine calls. Billed as the on-page audit fee plus one `ai_visibility_citation` per (query × engine) that actually answered, plus `serp` for the 2 retrievability SERPs and the 5 offsite SERPs when run.",
        "x-price-key": "ai_visibility",
        "x-price-keys": [
          "ai_visibility",
          "ai_visibility_citation",
          "serp"
        ],
        "x-pricing-note": "ai_visibility + answered (query × engine) × ai_visibility_citation + (2 retrieval + 5 offsite) × serp, only for SERPs that answered. Pre-check reserves the worst case.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "queries": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "string"
                    },
                    "description": "Questions to ask the engines. Absent = on-page audit only."
                  },
                  "engines": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "perplexity",
                        "openai",
                        "anthropic",
                        "aio",
                        "copilot",
                        "deepseek"
                      ]
                    },
                    "description": "Subset of engines for the citation panel; default all six. `deepseek` = our Google top-10 handed to DeepSeek (cheapest)."
                  },
                  "competitors": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "string"
                    },
                    "description": "Domains to name explicitly in the share of voice."
                  },
                  "brand": {
                    "type": "string",
                    "maxLength": 80,
                    "description": "Name to look for in answer text (\"mentioned\")."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  },
                  "no_render": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip the rendered pass (cheaper). Alias `noRender`."
                  },
                  "no_bot_fetch": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip the extra request that identifies as an AI crawler. Alias `noBotFetch`."
                  },
                  "no_retrieval": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip the 2 retrievability SERPs (rank for the page's own H1 question, index status). Alias `noRetrieval`."
                  },
                  "offsite": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also search the brand on YouTube, Reddit, Wikipedia, LinkedIn and review sites (5 SERPs)."
                  }
                }
              },
              "example": {
                "url": "https://example.com/blog/how-to-choose-a-proxy",
                "queries": [
                  "how do I choose a residential proxy provider?"
                ],
                "engines": [
                  "perplexity",
                  "aio"
                ],
                "brand": "Example"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audit finished. `billing` says how many citation calls and SERPs were charged.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/AiVisibilityResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "AI visibility audit successful",
                  "payload": {
                    "url": "https://example.com/blog/how-to-choose-a-proxy",
                    "finalUrl": "https://example.com/blog/how-to-choose-a-proxy",
                    "domain": "example.com",
                    "score": {
                      "overall": 71,
                      "pillars": {
                        "access": 90,
                        "content": 68,
                        "structure": 60,
                        "citability": 66
                      },
                      "scoredPillars": [
                        "access",
                        "content",
                        "structure",
                        "citability"
                      ],
                      "blockers": [],
                      "uncapped": 71
                    },
                    "checks": [
                      {
                        "id": "robots_gptbot",
                        "pillar": "access",
                        "status": "pass",
                        "weight": 8,
                        "title": "GPTBot allowed",
                        "detail": "robots.txt does not disallow GPTBot.",
                        "evidence": {
                          "rule": null
                        }
                      }
                    ],
                    "topFixes": [
                      {
                        "id": "author_resolvable",
                        "status": "fail",
                        "title": "Author not resolvable",
                        "fix": "Add an author Person node with url or sameAs."
                      }
                    ],
                    "access": {
                      "robotsTxtFound": true,
                      "robotsTxtUrl": "https://example.com/robots.txt",
                      "blockedCritical": [],
                      "sitemaps": [
                        "https://example.com/sitemap.xml"
                      ],
                      "llmsTxt": false
                    },
                    "content": {
                      "contentOnlyInJs": false,
                      "fkGrade": 9.1
                    },
                    "structure": {
                      "jsonldTypes": [
                        "Article"
                      ],
                      "hasAuthor": true,
                      "authorResolvable": false
                    },
                    "citations": {
                      "rows": [
                        {
                          "query": "how do I choose a residential proxy provider?",
                          "engine": "perplexity",
                          "cited": false,
                          "mentioned": true,
                          "rank": null,
                          "citedDomains": [
                            "competitor.example"
                          ]
                        }
                      ],
                      "usage": {
                        "perplexity": {
                          "searches": 1
                        }
                      }
                    },
                    "geo": {
                      "country": null
                    },
                    "billing": {
                      "citation_calls_billed": 2,
                      "offsite_serps_billed": 2
                    },
                    "usage": {
                      "cost_usd": 0.023,
                      "free_usd": 0.023,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "description": "Key/plan rate limit, or the account's daily cap on external AI-engine calls (payload: limit, remaining, reset_at, requested).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/ai-visibility' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com/blog/how-to-choose-a-proxy\",\"queries\":[\"how do I choose a residential proxy provider?\"],\"engines\":[\"perplexity\",\"aio\"],\"brand\":\"Example\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/ai-visibility',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com/blog/how-to-choose-a-proxy\",\n        \"queries\": [\n            \"how do I choose a residential proxy provider?\"\n        ],\n        \"engines\": [\n            \"perplexity\",\n            \"aio\"\n        ],\n        \"brand\": \"Example\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/ai-visibility\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/blog/how-to-choose-a-proxy\",\n    \"queries\": [\n      \"how do I choose a residential proxy provider?\"\n    ],\n    \"engines\": [\n      \"perplexity\",\n      \"aio\"\n    ],\n    \"brand\": \"Example\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/ai-visibility');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com/blog/how-to-choose-a-proxy',\n    'queries' => ['how do I choose a residential proxy provider?'],\n    'engines' => ['perplexity', 'aio'],\n    'brand' => 'Example'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/seo-audit": {
      "post": {
        "operationId": "seoAudit",
        "tags": [
          "SEO audit"
        ],
        "summary": "No-JS vs rendered SEO audit",
        "description": "Fetches a URL twice — once as a pure HTTP bot (no JavaScript) and once fully rendered — and returns what search engines see in each view, the diff (title/description changes, H1 or content only after JS, missing canonical) and the bot-facing meta (robots, OpenGraph, JSON-LD types). It is a page-level technical check, not a site crawl or a keyword tool. The full audit takes one browser-render token; with `no_render` only the no-JS view is produced and the call bills the plain scrape price. If the render pass fails on our side you still get the no-JS view at the plain scrape price.",
        "x-aliases": [
          "/seo-audit"
        ],
        "x-price-key": "seo_audit",
        "x-price-keys": [
          "seo_audit",
          "extract"
        ],
        "x-pricing-note": "seo_audit when the render pass ran; extract when no_render is true or the render pass errored.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  },
                  "no_render": {
                    "type": "boolean",
                    "default": false,
                    "description": "Skip the rendered pass. Alias `noRender`."
                  }
                }
              },
              "example": {
                "url": "https://example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audit finished.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/SeoAuditResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "SEO audit successful",
                  "payload": {
                    "url": "https://example.com",
                    "finalUrl": "https://example.com/",
                    "noJs": {
                      "status": 200,
                      "title": "Example Domain",
                      "description": null,
                      "canonical": null,
                      "h1": "Example Domain",
                      "wordCount": 28,
                      "hasContent": false
                    },
                    "render": {
                      "status": 200,
                      "title": "Example Domain",
                      "description": null,
                      "canonical": null,
                      "h1": "Example Domain",
                      "wordCount": 28,
                      "hasContent": false
                    },
                    "diff": {
                      "titleChanged": false,
                      "descriptionChanged": false,
                      "h1OnlyInRender": false,
                      "canonicalMissingNoJs": true,
                      "contentOnlyInJs": false
                    },
                    "meta": {
                      "robots": null,
                      "ogTitle": null,
                      "ogUrl": null,
                      "twitterCard": null,
                      "jsonldTypes": []
                    },
                    "durationMs": 4210,
                    "geo": {
                      "country": null
                    },
                    "usage": {
                      "cost_usd": 0.0012,
                      "free_usd": 0.0012,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/seo-audit' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/seo-audit',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/seo-audit\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/seo-audit');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/collectors": {
      "get": {
        "operationId": "listCollectors",
        "tags": [
          "Collectors"
        ],
        "summary": "Collector catalog",
        "description": "Every ready-made collector with its identity and version, semantic `input_schema` (JSON Schema — what to POST to `run_url`), full `output_schema`, examples, hourly health probe and YOUR price per delivered result (list price × tier discount). The catalog is the source of truth: collectors are added and versioned without an API change, so read it rather than hard-coding slugs. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "search",
                "seo",
                "social",
                "apps",
                "real_estate",
                "local",
                "jobs",
                "news",
                "ecommerce",
                "travel",
                "leads",
                "company",
                "classifieds",
                "finance",
                "dev",
                "knowledge",
                "gaming",
                "osint",
                "research"
              ]
            },
            "description": "Only collectors of this category."
          }
        ],
        "responses": {
          "200": {
            "description": "Catalog.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "collectors": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/CollectorCatalogEntry"
                              }
                            },
                            "billing": {
                              "type": "object",
                              "properties": {
                                "enabled": {
                                  "type": "boolean"
                                },
                                "discount_multiplier": {
                                  "type": "number"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collectors",
                  "payload": {
                    "collectors": [
                      {
                        "slug": "google_maps_places",
                        "name": "Google Maps places",
                        "version": "1.1.0",
                        "category": "local",
                        "category_label": "Local & Maps",
                        "tagline": "Businesses for a keyword in a location — name, rating, address, phone, website, coordinates.",
                        "description": "Searches Google's local results for a keyword in a location and delivers de-duplicated place records with contact and geo fields.",
                        "unit": "place",
                        "engines": [
                          "serp"
                        ],
                        "price": {
                          "list_usd": 0.001,
                          "your_usd": 0.001,
                          "price_key": "collector_google_maps_places",
                          "per_1k_usd": 1,
                          "min_billable_results": 0,
                          "min_run_usd": 0
                        },
                        "max_results": 300,
                        "input_schema": {
                          "type": "object",
                          "properties": {
                            "query": {
                              "type": "string",
                              "title": "Keyword",
                              "minLength": 2,
                              "maxLength": 120,
                              "examples": [
                                "pizza restaurants"
                              ]
                            },
                            "location": {
                              "type": "string",
                              "title": "Location",
                              "minLength": 2,
                              "maxLength": 120,
                              "examples": [
                                "Brooklyn, NY"
                              ]
                            },
                            "country": {
                              "type": "string",
                              "format": "country"
                            },
                            "lang": {
                              "type": "string",
                              "format": "lang"
                            },
                            "max_results": {
                              "type": "integer",
                              "default": 20,
                              "minimum": 1,
                              "maximum": 300
                            },
                            "enrich_details": {
                              "type": "boolean",
                              "default": true
                            }
                          },
                          "required": [
                            "query",
                            "location"
                          ],
                          "additionalProperties": false
                        },
                        "output_schema": {
                          "fields": [
                            {
                              "name": "rank",
                              "type": "integer",
                              "description": "1-based position across the merged pages."
                            },
                            {
                              "name": "name",
                              "type": "string",
                              "description": "Business name."
                            },
                            {
                              "name": "rating",
                              "type": "number",
                              "nullable": true,
                              "description": "Star rating (1–5)."
                            },
                            {
                              "name": "place_id",
                              "type": "string",
                              "nullable": true,
                              "description": "Google place id."
                            }
                          ]
                        },
                        "examples": [
                          {
                            "title": "Pizza in Brooklyn",
                            "input": {
                              "query": "pizza restaurants",
                              "location": "Brooklyn, NY",
                              "country": "us",
                              "max_results": 20
                            }
                          }
                        ],
                        "health_input": {
                          "query": "pizza",
                          "location": "Brooklyn, NY",
                          "country": "us",
                          "max_results": 10
                        },
                        "health": {
                          "status": "healthy",
                          "checked_at": "2026-10-07T08:00:12.000Z",
                          "latency_ms": 6210,
                          "result_count": 10,
                          "error": null,
                          "success_rate_24h": 1,
                          "last_ok_at": "2026-10-07T08:00:12.000Z"
                        },
                        "run_url": "/api/v1/scraper/collectors/google_maps_places/run"
                      }
                    ],
                    "billing": {
                      "enabled": true,
                      "discount_multiplier": 1
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/collectors' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/collectors',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/collectors\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/collectors');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/collectors/{slug}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/slug"
        }
      ],
      "get": {
        "operationId": "getCollector",
        "tags": [
          "Collectors"
        ],
        "summary": "One collector",
        "description": "The catalog entry of one collector plus its changelog and the last 24 health probes. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Collector.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "collector": {
                              "$ref": "#/components/schemas/CollectorCatalogEntry"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collector",
                  "payload": {
                    "collector": {
                      "slug": "google_maps_places",
                      "name": "Google Maps places",
                      "version": "1.1.0",
                      "category": "local",
                      "category_label": "Local & Maps",
                      "tagline": "Businesses for a keyword in a location.",
                      "description": "…",
                      "unit": "place",
                      "engines": [
                        "serp"
                      ],
                      "price": {
                        "list_usd": 0.001,
                        "your_usd": 0.001,
                        "price_key": "collector_google_maps_places",
                        "per_1k_usd": 1,
                        "min_billable_results": 0,
                        "min_run_usd": 0
                      },
                      "max_results": 300,
                      "input_schema": {
                        "type": "object",
                        "properties": {},
                        "required": [
                          "query",
                          "location"
                        ],
                        "additionalProperties": false
                      },
                      "output_schema": {
                        "fields": []
                      },
                      "examples": [],
                      "health_input": {},
                      "health": {
                        "status": "healthy",
                        "checked_at": "2026-10-07T08:00:12.000Z",
                        "latency_ms": 6210,
                        "result_count": 10,
                        "error": null,
                        "success_rate_24h": 1,
                        "last_ok_at": "2026-10-07T08:00:12.000Z"
                      },
                      "run_url": "/api/v1/scraper/collectors/google_maps_places/run",
                      "changelog": [
                        {
                          "version": "1.1.0",
                          "date": "2026-08-21",
                          "notes": "Paginates past offset 240."
                        }
                      ],
                      "health_history": [
                        {
                          "checked_at": "2026-10-07T08:00:12.000Z",
                          "ok": true,
                          "latency_ms": 6210,
                          "result_count": 10,
                          "error": null
                        }
                      ]
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Unknown slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Unknown collector \"foo\""
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/collectors/{slug}/run": {
      "parameters": [
        {
          "$ref": "#/components/parameters/slug"
        }
      ],
      "post": {
        "operationId": "runCollector",
        "tags": [
          "Collectors"
        ],
        "summary": "Run a collector",
        "description": "The body is the collector's semantic input exactly as published in its `input_schema` (flat, or wrapped as `{\"input\": {...}}`), plus runner options: `async: true` forces background processing (also `mode: \"async\"` or `wait: false`). Short runs answer synchronously with the rows; long ones (the collector decides from the input size) answer 202 with a `statusUrl` to poll. Identical input re-sent inside the dedup window returns the existing run (`deduplicated: true`) — nothing new is created or charged. Per-account brakes (runs per hour, concurrent runs, failure streak) answer 429 with Retry-After. Billed per DELIVERED row at the collector's unit price × your tier discount (some collectors have a small per-run floor, see `price.min_billable_results`); zero rows = zero charge, failed runs are never billed. The worst case (unit × max_results) must be covered by free tier + balance or the run is refused with 402.",
        "x-price-key": "collector_result",
        "x-pricing-note": "Per delivered row: pricing.json key `collector_<slug>` when it exists, else `collector_result`. GET /scraper/collectors returns the resolved key and your discounted price for every collector.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "The collector's `input_schema` fields (validated against it: unknown keys are rejected, `max_results` is clamped to the collector's cap) plus the runner options below.",
                "properties": {
                  "async": {
                    "type": "boolean",
                    "default": false,
                    "description": "Force background processing (202 + statusUrl)."
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "async"
                    ],
                    "description": "Alias of `async: true`."
                  },
                  "wait": {
                    "type": "boolean",
                    "description": "`false` = alias of `async: true`."
                  },
                  "input": {
                    "type": "object",
                    "description": "Optional wrapper for the collector input."
                  }
                },
                "additionalProperties": true
              },
              "example": {
                "query": "pizza restaurants",
                "location": "Brooklyn, NY",
                "country": "us",
                "max_results": 20
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Synchronous run finished with rows.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/CollectorRun"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collector run complete",
                  "payload": {
                    "run_id": "cmgfq2x1b0001",
                    "slug": "google_maps_places",
                    "version": "1.1.0",
                    "status": "done",
                    "input": {
                      "query": "pizza restaurants",
                      "location": "Brooklyn, NY",
                      "country": "us",
                      "max_results": 20
                    },
                    "count": 20,
                    "partial": false,
                    "cost": {
                      "usd": 0.02,
                      "unit_usd": 0.001,
                      "unit": "place",
                      "billed": true
                    },
                    "error": null,
                    "results": [
                      {
                        "rank": 1,
                        "name": "Joe's Pizza",
                        "rating": 4.5,
                        "reviews": 3120,
                        "category": "Pizza restaurant",
                        "address": "7 Carmine St, New York, NY 10014",
                        "phone": "+1 212-366-1182",
                        "website": "joespizzanyc.com",
                        "latitude": 40.7306,
                        "longitude": -74.0027,
                        "place_id": "ChIJ…",
                        "data_id": "0x89c259…:0x…",
                        "found_by": "pizza restaurants Brooklyn, NY"
                      }
                    ],
                    "notes": [],
                    "created_at": "2026-10-07T09:20:01.000Z",
                    "started_at": "2026-10-07T09:20:01.000Z",
                    "finished_at": "2026-10-07T09:20:14.000Z",
                    "usage": {
                      "cost_usd": 0.02,
                      "free_usd": 0.02,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "202": {
            "description": "Run queued (or an identical run already in progress): poll `statusUrl`.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "run_id": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "queued",
                                "running"
                              ]
                            },
                            "statusUrl": {
                              "type": "string"
                            },
                            "deduplicated": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collector run queued",
                  "payload": {
                    "run_id": "cmgfq2x1b0001",
                    "status": "queued",
                    "statusUrl": "/api/v1/scraper/collectors/runs/cmgfq2x1b0001"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "Input does not match the collector's `input_schema` (`payload.errors`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Invalid input: location is required",
                  "payload": {
                    "errors": [
                      "location is required"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "description": "Unknown slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "Input that can never resolve (documentation placeholder, undelegated TLD) — before or after the run; retrying the same input cannot help. Not billed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Invalid input: example.com is a documentation placeholder",
                  "payload": {
                    "errors": [
                      "example.com is a documentation placeholder"
                    ],
                    "error_kind": "input"
                  }
                }
              }
            }
          },
          "424": {
            "description": "The run failed at the source (blocked, timed out, layout changed). JSON body with `run_id` and `error`; not billed, safe to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Collector run failed",
                  "payload": {
                    "run_id": "cmgfq2x1b0002",
                    "slug": "google_maps_places",
                    "version": "1.1.0",
                    "status": "failed",
                    "input": {},
                    "count": 0,
                    "partial": false,
                    "cost": {
                      "usd": 0,
                      "unit_usd": 0.001,
                      "unit": "place",
                      "billed": false
                    },
                    "error": "source timed out after 3 attempts",
                    "created_at": "2026-10-07T09:20:01.000Z",
                    "started_at": "2026-10-07T09:20:01.000Z",
                    "finished_at": "2026-10-07T09:21:01.000Z"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Key/plan rate limit, or a per-account collector brake (`payload.code`: RUNS_PER_HOUR, CONCURRENT_RUNS, FAIL_STREAK, USER_PAUSED) with Retry-After.",
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Too many collector runs this hour.",
                  "payload": {
                    "code": "RUNS_PER_HOUR",
                    "limit": 60,
                    "in_last_hour": 60,
                    "retry_after": 900,
                    "plan": "payg"
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places/run' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\":\"pizza restaurants\",\"location\":\"Brooklyn, NY\",\"country\":\"us\",\"max_results\":20}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places/run',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"query\": \"pizza restaurants\",\n        \"location\": \"Brooklyn, NY\",\n        \"country\": \"us\",\n        \"max_results\": 20\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places/run\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"query\": \"pizza restaurants\",\n    \"location\": \"Brooklyn, NY\",\n    \"country\": \"us\",\n    \"max_results\": 20\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/collectors/google_maps_places/run');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'query' => 'pizza restaurants',\n    'location' => 'Brooklyn, NY',\n    'country' => 'us',\n    'max_results' => 20\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/collectors/runs": {
      "get": {
        "operationId": "listCollectorRuns",
        "tags": [
          "Collectors"
        ],
        "summary": "Your collector runs",
        "description": "Newest first, without result rows. Page with `next_cursor`. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "`next_cursor` from the previous page."
          },
          {
            "name": "slug",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Only runs of this collector."
          }
        ],
        "responses": {
          "200": {
            "description": "Runs.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "runs": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/CollectorRun"
                              }
                            },
                            "next_cursor": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collector runs",
                  "payload": {
                    "runs": [
                      {
                        "run_id": "cmgfq2x1b0001",
                        "slug": "google_maps_places",
                        "version": "1.1.0",
                        "status": "done",
                        "input": {
                          "query": "pizza restaurants",
                          "location": "Brooklyn, NY"
                        },
                        "count": 20,
                        "partial": false,
                        "cost": {
                          "usd": 0.02,
                          "unit_usd": 0.001,
                          "unit": "place",
                          "billed": true
                        },
                        "error": null,
                        "created_at": "2026-10-07T09:20:01.000Z",
                        "started_at": "2026-10-07T09:20:01.000Z",
                        "finished_at": "2026-10-07T09:20:14.000Z"
                      }
                    ],
                    "next_cursor": null
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/collectors/runs' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/collectors/runs',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/collectors/runs\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/collectors/runs');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/collectors/runs/{runId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/runId"
        }
      ],
      "get": {
        "operationId": "getCollectorRun",
        "tags": [
          "Collectors"
        ],
        "summary": "One run with its rows",
        "description": "The run you own with its delivered results. `format=csv` streams the rows as CSV (columns follow the collector's `output_schema`). Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv"
              ]
            },
            "description": "`csv` returns a file instead of the JSON envelope."
          }
        ],
        "responses": {
          "200": {
            "description": "Run view (JSON) or CSV file.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/CollectorRun"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Collector run",
                  "payload": {
                    "run_id": "cmgfq2x1b0001",
                    "slug": "google_maps_places",
                    "version": "1.1.0",
                    "status": "done",
                    "input": {
                      "query": "pizza restaurants",
                      "location": "Brooklyn, NY",
                      "country": "us",
                      "max_results": 20
                    },
                    "count": 20,
                    "partial": false,
                    "cost": {
                      "usd": 0.02,
                      "unit_usd": 0.001,
                      "unit": "place",
                      "billed": true
                    },
                    "error": null,
                    "results": [
                      {
                        "rank": 1,
                        "name": "Joe's Pizza"
                      }
                    ],
                    "created_at": "2026-10-07T09:20:01.000Z",
                    "started_at": "2026-10-07T09:20:01.000Z",
                    "finished_at": "2026-10-07T09:20:14.000Z",
                    "usage": {
                      "cost_usd": 0.02,
                      "free_usd": 0.02,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "example": "rank,name,rating,reviews,category,address,phone,website\n1,Joe's Pizza,4.5,3120,Pizza restaurant,\"7 Carmine St, New York, NY 10014\",+1 212-366-1182,joespizzanyc.com\n"
              }
            }
          },
          "400": {
            "description": "Malformed run id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/collectors/runs/cmgfq2x1b0001' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/collectors/runs/cmgfq2x1b0001',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/collectors/runs/cmgfq2x1b0001\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/collectors/runs/cmgfq2x1b0001');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/datasets": {
      "get": {
        "operationId": "listDatasets",
        "tags": [
          "Datasets"
        ],
        "summary": "Your recent dataset runs",
        "description": "The last 20 runs, newest first, with status reconciled against the live job for runs still marked running, the settled cost, and whether the rows are still stored. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Datasets.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "datasets": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/DatasetSummary"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Datasets",
                  "payload": {
                    "datasets": [
                      {
                        "id": "cmgf0",
                        "jobId": "ds_7a1c22",
                        "name": null,
                        "prompt": "Car rental companies in Bologna with phone and website",
                        "columns": "[{\"name\":\"company\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"phone\"},{\"name\":\"website\",\"type\":\"url\"}]",
                        "country": "it",
                        "status": "completed",
                        "rowCount": 42,
                        "billableRows": 40,
                        "refresh": false,
                        "createdAt": "2026-10-06T14:02:11.000Z",
                        "completedAt": "2026-10-06T14:09:40.000Z",
                        "purgedAt": null,
                        "costUsd": 1.86,
                        "stored": true,
                        "storedRows": 42,
                        "storedBytes": 18311,
                        "purged": false,
                        "dropped": null
                      }
                    ]
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/datasets' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/datasets',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "post": {
        "operationId": "createDataset",
        "tags": [
          "Datasets"
        ],
        "summary": "Build a dataset from a prompt",
        "description": "One plain-language prompt → a structured dataset. The service plans queries, searches, maps and scrapes, extracts the requested columns and returns validated rows; `refresh: true` re-reads a known URL set (`refreshUrls`) without discovery at a reduced row fee. Returns a job id immediately; poll `GET /scraper/datasets/{jobId}`, download the file, or pass a `webhook` (public host only, delivered after settlement with the hygiene filters applied). Billing is value-based: the run's budget `limits.max_cost_usd` (default $5, max $500, min $0.05) is charged up front and the unspent share is refunded at settlement, so you pay only for delivered, validated records (`dataset_row`, or `dataset_row_refresh` on a refresh) plus premium columns found (email, phone, deep) plus the pipeline units consumed. Low-confidence rows, off-target pages and blocked pages are never billed.",
        "x-price-key": "dataset_row",
        "x-price-keys": [
          "dataset_row",
          "dataset_row_refresh"
        ],
        "x-pricing-note": "max_cost_usd charged up front, refunded down to actual spend. Actual spend = delivered validated rows × dataset_row (dataset_row_refresh on refresh) + premium field fees + metered pipeline units (serp/map/extract/AI).",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "What the dataset is."
                  },
                  "columns": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "name"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "string",
                            "number",
                            "email",
                            "phone",
                            "url",
                            "boolean",
                            "deep"
                          ],
                          "description": "`email`, `phone` and `deep` are premium (billed only when found)."
                        },
                        "description": {
                          "type": "string"
                        }
                      }
                    },
                    "description": "Omit to let the planner infer columns from the prompt."
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  },
                  "sources": {
                    "type": "object",
                    "properties": {
                      "include": {
                        "type": "array",
                        "maxItems": 50,
                        "items": {
                          "type": "string"
                        }
                      },
                      "exclude": {
                        "type": "array",
                        "maxItems": 50,
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "description": "Domain allow/deny lists."
                  },
                  "limits": {
                    "type": "object",
                    "properties": {
                      "max_rows": {
                        "type": "integer"
                      },
                      "max_pages": {
                        "type": "integer"
                      },
                      "max_cost_usd": {
                        "type": "number",
                        "minimum": 0.05,
                        "maximum": 500,
                        "default": 5
                      }
                    }
                  },
                  "webhook": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Public http(s) URL that receives the finished, filtered dataset by POST."
                  },
                  "refresh": {
                    "type": "boolean",
                    "default": false
                  },
                  "refreshUrls": {
                    "type": "array",
                    "maxItems": 1000,
                    "items": {
                      "type": "string",
                      "maxLength": 2048
                    },
                    "description": "Required with `refresh: true`."
                  }
                }
              },
              "example": {
                "prompt": "Car rental companies in Bologna with phone and website",
                "columns": [
                  {
                    "name": "company",
                    "type": "string"
                  },
                  {
                    "name": "phone",
                    "type": "phone"
                  },
                  {
                    "name": "website",
                    "type": "url"
                  }
                ],
                "country": "it",
                "limits": {
                  "max_rows": 50,
                  "max_cost_usd": 3
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dataset job started.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/JobStarted"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Dataset started",
                  "payload": {
                    "id": "ds_7a1c22",
                    "status": "running",
                    "prompt": "Car rental companies in Bologna with phone and website",
                    "columns": [
                      {
                        "name": "company",
                        "type": "string"
                      },
                      {
                        "name": "phone",
                        "type": "phone"
                      },
                      {
                        "name": "website",
                        "type": "url"
                      }
                    ],
                    "limits": {
                      "max_rows": 50,
                      "max_pages": 200,
                      "max_cost_usd": 3
                    },
                    "statusUrl": "/api/v1/scraper/datasets/ds_7a1c22",
                    "usage": {
                      "cost_usd": 3,
                      "free_usd": 2,
                      "paid_usd": 1,
                      "balance": 9
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "description": "The Data API group is off for your key, or the dataset builder is not enabled on this instance (configuration, not a transient error).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/datasets' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\":\"Car rental companies in Bologna with phone and website\",\"columns\":[{\"name\":\"company\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"phone\"},{\"name\":\"website\",\"type\":\"url\"}],\"country\":\"it\",\"limits\":{\"max_rows\":50,\"max_cost_usd\":3}}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/datasets',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"prompt\": \"Car rental companies in Bologna with phone and website\",\n        \"columns\": [\n            {\n                \"name\": \"company\",\n                \"type\": \"string\"\n            },\n            {\n                \"name\": \"phone\",\n                \"type\": \"phone\"\n            },\n            {\n                \"name\": \"website\",\n                \"type\": \"url\"\n            }\n        ],\n        \"country\": \"it\",\n        \"limits\": {\n            \"max_rows\": 50,\n            \"max_cost_usd\": 3\n        }\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"prompt\": \"Car rental companies in Bologna with phone and website\",\n    \"columns\": [\n      {\n        \"name\": \"company\",\n        \"type\": \"string\"\n      },\n      {\n        \"name\": \"phone\",\n        \"type\": \"phone\"\n      },\n      {\n        \"name\": \"website\",\n        \"type\": \"url\"\n      }\n    ],\n    \"country\": \"it\",\n    \"limits\": {\n      \"max_rows\": 50,\n      \"max_cost_usd\": 3\n    }\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'prompt' => 'Car rental companies in Bologna with phone and website',\n    'columns' => [[\n      'name' => 'company',\n      'type' => 'string'\n    ], [\n      'name' => 'phone',\n      'type' => 'phone'\n    ], [\n      'name' => 'website',\n      'type' => 'url'\n    ]],\n    'country' => 'it',\n    'limits' => [\n      'max_rows' => 50,\n      'max_cost_usd' => 3\n    ]\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/datasets/{jobId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "get": {
        "operationId": "getDataset",
        "tags": [
          "Datasets"
        ],
        "summary": "Poll a dataset job",
        "description": "Progress, the collection trace (`steps`) and the rows so far, filtered for you (removal list, your exclusion list, rows already delivered to you). A run the service has already forgotten (about an hour after it finishes) is served from storage (`source: storage`, no progress/steps). Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Row cursor from the previous poll's `nextCursor`."
          },
          {
            "name": "mode",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "summary"
              ]
            },
            "description": "`summary` omits rows."
          }
        ],
        "responses": {
          "200": {
            "description": "Job view.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/DatasetJob"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Dataset status",
                  "payload": {
                    "id": "ds_7a1c22",
                    "status": "completed",
                    "prompt": "Car rental companies in Bologna with phone and website",
                    "columns": [
                      {
                        "name": "company",
                        "type": "string"
                      },
                      {
                        "name": "phone",
                        "type": "phone"
                      },
                      {
                        "name": "website",
                        "type": "url"
                      }
                    ],
                    "files": null,
                    "progress": {
                      "queries_run": 6,
                      "sites_mapped": 12,
                      "pages_scraped": 58,
                      "pages_failed": 3,
                      "rows": 42,
                      "dropped_offtarget": 4,
                      "cost_so_far_usd": 1.86
                    },
                    "limits": {
                      "max_rows": 50,
                      "max_pages": 200,
                      "max_cost_usd": 3
                    },
                    "entity": "car rental company",
                    "billable": {
                      "row_fees_usd": 1.62,
                      "unit_usd": 0.24
                    },
                    "steps": [
                      {
                        "phase": "plan",
                        "detail": "entity: car rental company; 6 queries",
                        "ts": 1759759331000
                      }
                    ],
                    "rows": [
                      {
                        "fields": {
                          "company": "Bologna Rent",
                          "phone": "+39 051 000000",
                          "website": "https://example.it"
                        },
                        "_source_url": "https://example.it/contatti",
                        "_fetched_at": "2026-10-06T14:05:10.000Z",
                        "confidence": 0.93,
                        "billed_fields": [
                          "phone"
                        ],
                        "fee_usd": 0.05
                      }
                    ],
                    "row_count": 42,
                    "billable_rows": 40,
                    "nextCursor": 42,
                    "createdAt": 1759759331000,
                    "finishedAt": 1759759780000
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "cancelDataset",
        "tags": [
          "Datasets"
        ],
        "summary": "Cancel a dataset job",
        "description": "Stops a running job you own; the unspent budget is refunded at settlement. To delete the stored record of a finished run use `DELETE /scraper/datasets/{jobId}/record`.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Dataset cancelled",
                  "payload": {
                    "id": "ds_7a1c22",
                    "status": "cancelled"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/datasets/{jobId}/download": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "get": {
        "operationId": "downloadDataset",
        "tags": [
          "Datasets"
        ],
        "summary": "Download a dataset file",
        "description": "The run's rows as CSV or JSON, partial runs included (rows collected before an interruption are delivered too). Always built from rows that passed the list-hygiene filter. 404 while the run is still going or when it produced no rows. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "json"
              ],
              "default": "csv"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File attachment `dataset-{jobId}.csv|json`.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "example": "company,phone,website,_source_url\nBologna Rent,+39 051 000000,https://example.it,https://example.it/contatti\n"
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "columns": {
                      "type": "array"
                    },
                    "rows": {
                      "type": "array"
                    },
                    "rowCount": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "columns": [
                    {
                      "name": "company",
                      "type": "string"
                    }
                  ],
                  "rows": [
                    {
                      "company": "Bologna Rent",
                      "_source_url": "https://example.it/contatti"
                    }
                  ],
                  "rowCount": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Unknown job, not yours, or file not ready (run not finished or no rows).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "File not ready — the run has not finished or produced no rows"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/download' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/download',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\nr.raise_for_status()\nopen(\"response.out\", \"wb\").write(r.content)",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/download\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst bytes = Buffer.from(await res.arrayBuffer());\nrequire(\"node:fs\").writeFileSync(\"response.out\", bytes);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/download');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\nfile_put_contents('response.out', $raw);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/datasets/{jobId}/record": {
      "parameters": [
        {
          "$ref": "#/components/parameters/jobId"
        }
      ],
      "patch": {
        "operationId": "renameDataset",
        "tags": [
          "Datasets"
        ],
        "summary": "Rename a dataset run",
        "description": "Sets the run's label (max 120 characters); an empty string or null clears it and the prompt becomes the label again. The prompt itself is never rewritten. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 120
                  }
                }
              },
              "example": {
                "name": "Bologna car rentals — October"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Renamed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Dataset renamed",
                  "payload": {
                    "jobId": "ds_7a1c22",
                    "name": "Bologna car rentals — October",
                    "prompt": "Car rental companies in Bologna with phone and website"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\":\"Bologna car rentals — October\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.patch(\n    'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"name\": \"Bologna car rentals — October\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record\", {\n  method: \"PATCH\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"name\": \"Bologna car rentals — October\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'PATCH',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'Bologna car rentals — October'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "deleteDatasetRecord",
        "tags": [
          "Datasets"
        ],
        "summary": "Delete a dataset run's stored record",
        "description": "Permanently removes the record and its stored rows. A run still in flight must be cancelled first (400). Irreversible. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Dataset deleted",
                  "payload": {
                    "jobId": "ds_7a1c22"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "The run is still running — cancel it first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Cancel the run before deleting it."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/datasets/job_8f2c1a/record');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/parser/generate": {
      "post": {
        "operationId": "generateParser",
        "tags": [
          "Parser presets"
        ],
        "summary": "Generate CSS selectors with an LLM, once",
        "description": "Looks at a page once with a model and returns CSS selectors (`parser`) that extract the fields you asked for — ready to pass as `extract` on every later scrape of that layout, where no model is involved and the plain scrape price applies. Every selector is run against the page before it is returned: `report`, `missed` and `coverage` tell you which fields are reliable. Give `url` (fetched through the pool, `render: true` for SPA pages) or `html` you already have (max 3 MB, no proxy bandwidth). Charged once as a setup step, and only when the parser extracts something (`coverage` > 0).",
        "x-price-key": "parser_generate",
        "x-pricing-note": "parser_generate, only when coverage > 0.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Required unless `html` is given."
                  },
                  "html": {
                    "type": "string"
                  },
                  "fields": {
                    "type": "object",
                    "maxProperties": 25,
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 300
                    },
                    "description": "field name → what it is. Required unless `prompt` is given."
                  },
                  "prompt": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Free-text alternative to `fields` (the model names them)."
                  },
                  "render": {
                    "type": "boolean",
                    "default": false
                  },
                  "country": {
                    "$ref": "#/components/schemas/GeoValue"
                  }
                }
              },
              "example": {
                "url": "https://example.com/products/42",
                "fields": {
                  "title": "product name",
                  "price": "current price with currency",
                  "sku": "SKU code"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Parser generated (message says when no usable selector could be produced; then not charged).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/GenerateParserResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Parser generated",
                  "payload": {
                    "parser": {
                      "title": "h1.product-title",
                      "price": {
                        "selector": "span.price",
                        "attr": null
                      },
                      "sku": "dd.sku"
                    },
                    "report": [
                      {
                        "field": "title",
                        "selector": "h1.product-title",
                        "sample": "Trail Runner 2",
                        "missed": false
                      },
                      {
                        "field": "price",
                        "selector": "span.price",
                        "sample": "€ 129,00",
                        "missed": false
                      },
                      {
                        "field": "sku",
                        "selector": "dd.sku",
                        "sample": "TR2-42",
                        "missed": false
                      }
                    ],
                    "missed": [],
                    "coverage": 1,
                    "repaired": false,
                    "usage": {
                      "cost_usd": 0.02,
                      "free_usd": 0.02,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "description": "Data API off for your key, or the generator's model is not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/parser/generate' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com/products/42\",\"fields\":{\"title\":\"product name\",\"price\":\"current price with currency\",\"sku\":\"SKU code\"}}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/parser/generate',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"url\": \"https://example.com/products/42\",\n        \"fields\": {\n            \"title\": \"product name\",\n            \"price\": \"current price with currency\",\n            \"sku\": \"SKU code\"\n        }\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/generate\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"url\": \"https://example.com/products/42\",\n    \"fields\": {\n      \"title\": \"product name\",\n      \"price\": \"current price with currency\",\n      \"sku\": \"SKU code\"\n    }\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/generate');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'url' => 'https://example.com/products/42',\n    'fields' => [\n      'title' => 'product name',\n      'price' => 'current price with currency',\n      'sku' => 'SKU code'\n    ]\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/parser/presets": {
      "get": {
        "operationId": "listParserPresets",
        "tags": [
          "Parser presets"
        ],
        "summary": "List your presets",
        "description": "Every stored parser of your account with its stats and version history. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Presets.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "presets": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/ParserPreset"
                              }
                            }
                          },
                          "additionalProperties": true
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Presets",
                  "payload": {
                    "presets": [
                      {
                        "id": "pst_7Qk3",
                        "name": "example-product",
                        "sourceUrl": "https://example.com/products/42",
                        "fields": {
                          "title": "product name",
                          "price": "current price"
                        },
                        "render": false,
                        "parser": {
                          "title": "h1.product-title",
                          "price": "span.price"
                        },
                        "version": 1,
                        "autoHeal": true,
                        "createdAt": 1759759331000,
                        "updatedAt": 1759759331000,
                        "lastHealAt": null,
                        "stats": {
                          "runs": 12,
                          "lastRunAt": 1759830000000,
                          "fields": {
                            "title": {
                              "hits": 12,
                              "misses": 0
                            },
                            "price": {
                              "hits": 11,
                              "misses": 1
                            }
                          },
                          "recent": [
                            1,
                            1,
                            0.5,
                            1
                          ]
                        },
                        "history": [
                          {
                            "version": 1,
                            "parser": {
                              "title": "h1.product-title",
                              "price": "span.price"
                            },
                            "at": 1759759331000,
                            "reason": "created",
                            "coverage": 1
                          }
                        ]
                      }
                    ]
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/parser/presets' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "post": {
        "operationId": "createParserPreset",
        "tags": [
          "Parser presets"
        ],
        "summary": "Save a parser as a preset",
        "description": "Stores a parser (usually the one /scraper/parser/generate just returned) under a name. Scrape with `presetId` instead of an inline `extract` schema and every run is scored per field; when the recent success rate decays and `autoHeal` is on, the preset regenerates itself from `sourceUrl` and bumps its version. Ownership is server-side: a client-supplied tenant is ignored. Free to store.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "parser"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "parser": {
                    "$ref": "#/components/schemas/ExtractSchema",
                    "description": "Non-empty, at most 25 fields."
                  },
                  "sourceUrl": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Page the parser was learned from — self-healing refetches it."
                  },
                  "fields": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "field → description, so a heal can regenerate the same shape."
                  },
                  "render": {
                    "type": "boolean",
                    "default": false
                  },
                  "autoHeal": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "name": "example-product",
                "parser": {
                  "title": "h1.product-title",
                  "price": "span.price"
                },
                "sourceUrl": "https://example.com/products/42",
                "fields": {
                  "title": "product name",
                  "price": "current price"
                },
                "autoHeal": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/ParserPreset"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Preset created",
                  "payload": {
                    "id": "pst_7Qk3",
                    "name": "example-product",
                    "sourceUrl": "https://example.com/products/42",
                    "fields": {
                      "title": "product name",
                      "price": "current price"
                    },
                    "render": false,
                    "parser": {
                      "title": "h1.product-title",
                      "price": "span.price"
                    },
                    "version": 1,
                    "autoHeal": true,
                    "createdAt": 1759759331000,
                    "updatedAt": 1759759331000,
                    "lastHealAt": null,
                    "stats": {
                      "runs": 0,
                      "lastRunAt": null,
                      "fields": {},
                      "recent": []
                    },
                    "history": [
                      {
                        "version": 1,
                        "parser": {
                          "title": "h1.product-title",
                          "price": "span.price"
                        },
                        "at": 1759759331000,
                        "reason": "created"
                      }
                    ]
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/parser/presets' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\":\"example-product\",\"parser\":{\"title\":\"h1.product-title\",\"price\":\"span.price\"},\"sourceUrl\":\"https://example.com/products/42\",\"fields\":{\"title\":\"product name\",\"price\":\"current price\"},\"autoHeal\":true}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"name\": \"example-product\",\n        \"parser\": {\n            \"title\": \"h1.product-title\",\n            \"price\": \"span.price\"\n        },\n        \"sourceUrl\": \"https://example.com/products/42\",\n        \"fields\": {\n            \"title\": \"product name\",\n            \"price\": \"current price\"\n        },\n        \"autoHeal\": true\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"name\": \"example-product\",\n    \"parser\": {\n      \"title\": \"h1.product-title\",\n      \"price\": \"span.price\"\n    },\n    \"sourceUrl\": \"https://example.com/products/42\",\n    \"fields\": {\n      \"title\": \"product name\",\n      \"price\": \"current price\"\n    },\n    \"autoHeal\": true\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'name' => 'example-product',\n    'parser' => [\n      'title' => 'h1.product-title',\n      'price' => 'span.price'\n    ],\n    'sourceUrl' => 'https://example.com/products/42',\n    'fields' => [\n      'title' => 'product name',\n      'price' => 'current price'\n    ],\n    'autoHeal' => true\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/parser/presets/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/presetId"
        }
      ],
      "get": {
        "operationId": "getParserPreset",
        "tags": [
          "Parser presets"
        ],
        "summary": "Read a preset",
        "description": "Parser, stats and version history. A preset belonging to someone else answers 404. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Preset.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/ParserPreset"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Preset",
                  "payload": {
                    "id": "pst_7Qk3",
                    "name": "example-product",
                    "parser": {
                      "title": "h1.product-title",
                      "price": "span.price"
                    },
                    "version": 1,
                    "autoHeal": true,
                    "createdAt": 1759759331000,
                    "updatedAt": 1759759331000,
                    "lastHealAt": null,
                    "stats": {
                      "runs": 12,
                      "lastRunAt": 1759830000000,
                      "fields": {},
                      "recent": []
                    },
                    "history": []
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "put": {
        "operationId": "updateParserPreset",
        "tags": [
          "Parser presets"
        ],
        "summary": "Update a preset",
        "description": "Rename, replace the parser (bumps the version), toggle `autoHeal`, update `fields`/`sourceUrl`. Only the keys you send change. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "parser": {
                    "$ref": "#/components/schemas/ExtractSchema",
                    "description": "Non-empty, at most 25 fields."
                  },
                  "autoHeal": {
                    "type": "boolean"
                  },
                  "fields": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "sourceUrl": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "autoHeal": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/ParserPreset"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Preset updated",
                  "payload": {
                    "id": "pst_7Qk3",
                    "name": "example-product",
                    "parser": {
                      "title": "h1.product-title",
                      "price": "span.price"
                    },
                    "version": 1,
                    "autoHeal": false,
                    "createdAt": 1759759331000,
                    "updatedAt": 1759840000000,
                    "lastHealAt": null,
                    "stats": {
                      "runs": 12,
                      "lastRunAt": 1759830000000,
                      "fields": {},
                      "recent": []
                    },
                    "history": []
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT 'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"autoHeal\":false}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.put(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"autoHeal\": false\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3\", {\n  method: \"PUT\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"autoHeal\": false\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'PUT',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'autoHeal' => false\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "deleteParserPreset",
        "tags": [
          "Parser presets"
        ],
        "summary": "Delete a preset",
        "description": "Removes the preset and its version history. Scrapes that still send its `presetId` answer 404 afterwards. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Preset deleted",
                  "payload": {
                    "ok": true
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/parser/presets/{id}/heal": {
      "parameters": [
        {
          "$ref": "#/components/parameters/presetId"
        }
      ],
      "post": {
        "operationId": "healParserPreset",
        "tags": [
          "Parser presets"
        ],
        "summary": "Regenerate a preset's parser now",
        "description": "The manual trigger of the repair that runs automatically when a preset decays: refetches `sourceUrl`, asks the model for fresh selectors and adopts them only if they extract more of the page than the current ones. `force: true` bypasses the cooldown between heals. Billed like a generation, and only when a new version was actually produced (`healed: true`).",
        "x-price-key": "parser_generate",
        "x-pricing-note": "parser_generate only when healed is true.",
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "force": {
                    "type": "boolean",
                    "default": false
                  }
                }
              },
              "example": {
                "force": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Heal attempted (message says whether a new version was adopted).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/HealResult"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Preset healed",
                  "payload": {
                    "healed": true,
                    "reason": "coverage improved",
                    "version": 2,
                    "coverageBefore": 0.5,
                    "coverageAfter": 1,
                    "parser": {
                      "title": "h1[itemprop=name]",
                      "price": "span.price-now"
                    },
                    "usage": {
                      "cost_usd": 0.02,
                      "free_usd": 0.02,
                      "paid_usd": 0
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "description": "Data API off for your key, or the generator's model is not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/heal' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"force\":false}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/heal',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"force\": false\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/heal\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"force\": false\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/heal');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'force' => false\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/parser/presets/{id}/stats": {
      "parameters": [
        {
          "$ref": "#/components/parameters/presetId"
        }
      ],
      "get": {
        "operationId": "getParserPresetStats",
        "tags": [
          "Parser presets"
        ],
        "summary": "How well a preset still works",
        "description": "Lifetime success rate per field, mean coverage over the recent window and whether the preset now counts as decayed (the signal that triggers self-healing). Free — it is the health check of a parser you already paid to build.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Stats.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/PresetStatsView"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Preset stats",
                  "payload": {
                    "id": "pst_7Qk3",
                    "name": "example-product",
                    "version": 2,
                    "runs": 12,
                    "lastRunAt": 1759830000000,
                    "successRateByField": {
                      "title": 1,
                      "price": 0.917
                    },
                    "recentCoverage": 0.96,
                    "decayed": false,
                    "autoHeal": true,
                    "lastHealAt": 1759840000000
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceDisabled"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/stats' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/stats',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/stats\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/parser/presets/pst_7Qk3/stats');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/usage": {
      "get": {
        "operationId": "getUsage",
        "tags": [
          "Account"
        ],
        "summary": "Per-day usage and cost",
        "description": "Request counts (total and per query type), proxy bandwidth, AI token cost and billed vs free-tier spend per UTC day for the calling key's account, read from the daily aggregation. Free; not subject to the Data API kill switch.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 90,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage report.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "days": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/UsageDay"
                              }
                            },
                            "totals": {
                              "type": "object",
                              "properties": {
                                "requests": {
                                  "type": "integer"
                                },
                                "by_type": {
                                  "type": "object"
                                },
                                "proxy_kb": {
                                  "type": "number"
                                },
                                "billed_usd": {
                                  "type": "number"
                                },
                                "free_usd": {
                                  "type": "number"
                                }
                              }
                            },
                            "period_days": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Scraper usage",
                  "payload": {
                    "days": [
                      {
                        "date": "2026-10-06",
                        "requests": 143,
                        "by_type": {
                          "extract": 120,
                          "google": 20,
                          "map": 3
                        },
                        "proxy_kb": 61230,
                        "ai_cost_usd": 0,
                        "billed_usd": 0,
                        "free_usd": 0.0375
                      }
                    ],
                    "totals": {
                      "requests": 143,
                      "by_type": {
                        "extract": 120,
                        "google": 20,
                        "map": 3
                      },
                      "proxy_kb": 61230,
                      "billed_usd": 0,
                      "free_usd": 0.0375
                    },
                    "period_days": 30
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/usage' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/usage',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/usage\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/usage');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/scraper/billing": {
      "get": {
        "operationId": "getBilling",
        "tags": [
          "Account"
        ],
        "summary": "Billing status and your price list",
        "description": "Current price list with your tier's discount applied (keyed like pricing.json), monthly free allowance and what is left of it, wallet balance, active tier, billing mode and the per-minute limits each mode carries. Lets a client or an agent budget its calls without a dashboard round-trip. Free; not subject to the Data API kill switch.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "responses": {
          "200": {
            "description": "Billing status.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/BillingStatus"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Billing status",
                  "payload": {
                    "billing_enabled": true,
                    "billed": true,
                    "balance": 12.5,
                    "tier": {
                      "key": "payg",
                      "name": "Pay as you go",
                      "discount_pct": 0,
                      "rate_limit_per_min": 20
                    },
                    "billing_mode": {
                      "preference": "free_first",
                      "effective": "free_first",
                      "available": true,
                      "free_first_rate_limit_per_min": 20,
                      "balance_rate_limit_per_min": 300,
                      "effective_rate_limit_per_min": 20
                    },
                    "free_monthly_usd": 2,
                    "free_remaining_usd": 1.62,
                    "ai_token_markup": 2,
                    "prices_usd": {
                      "extract": 0.0002,
                      "extract_render": 0.001,
                      "serp": 0.0005,
                      "serp_render": 0.002,
                      "map": 0.0005,
                      "seo_audit": 0.0012,
                      "crawl_page": 0.0003,
                      "batch_url": 0.0002,
                      "collector_result": 0.002
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/scraper/billing' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/scraper/billing',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/scraper/billing\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/scraper/billing');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/public/proxies": {
      "get": {
        "operationId": "listProxies",
        "tags": [
          "Proxies"
        ],
        "summary": "List your proxy plans",
        "description": "Every proxy service on the account (residential basic/premium/private, ISP, premium ISP, datacenter, datacenter traffic, IPv6, mobile, mobile v2) with credentials, bandwidth left, expiry and the `orderId` the generate and whitelist endpoints take. Free; no Data API billing.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "planType",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "residentialbasic",
                "residentialpremium",
                "resiprivate",
                "isp",
                "isppremium",
                "datacenter",
                "datacentertraffic",
                "ipv6",
                "mobile",
                "mobile_v2"
              ]
            }
          },
          {
            "name": "active",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "Filter by expiry; omit for all."
          }
        ],
        "responses": {
          "200": {
            "description": "Plans.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "proxies": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/ProxyPlan"
                              }
                            },
                            "pagination": {
                              "type": "object",
                              "properties": {
                                "total": {
                                  "type": "integer"
                                },
                                "limit": {
                                  "type": "integer"
                                },
                                "offset": {
                                  "type": "integer"
                                },
                                "hasMore": {
                                  "type": "boolean"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Success",
                  "payload": {
                    "proxies": [
                      {
                        "id": "prx_1",
                        "orderId": "ord_8c21",
                        "planName": "Residential Premium 5 GB",
                        "planType": "residentialpremium",
                        "planTypeName": "Residential Premium",
                        "username": "user_8c21",
                        "password": "p4ssw0rd",
                        "proxyId": "sub_19a",
                        "bandwidth": 5,
                        "bandwidthGB": 5,
                        "bandwidthLeft": 3.2,
                        "bandwidthLeftGB": 3.2,
                        "bandwidthUsed": 1.8,
                        "bandwidthUsedGB": 1.8,
                        "bandwidthUsagePercent": 36,
                        "isUnlimited": false,
                        "expiry": "2026-11-06T00:00:00.000Z",
                        "expiresAt": "2026-11-06T00:00:00.000Z",
                        "isActive": true,
                        "isExpired": false,
                        "daysRemaining": 30,
                        "hoursRemaining": 720,
                        "ips": 0,
                        "whitelistSlots": 0,
                        "whitelistedIPs": [],
                        "region": "Global",
                        "speed": null,
                        "highConcurrency": false,
                        "highPriority": false,
                        "createdAt": "2026-10-06T10:00:00.000Z"
                      }
                    ],
                    "pagination": {
                      "total": 1,
                      "limit": 50,
                      "offset": 0,
                      "hasMore": false
                    }
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/public/proxies' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/public/proxies',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/public/proxies/generate": {
      "post": {
        "operationId": "generateProxies",
        "tags": [
          "Proxies"
        ],
        "summary": "Generate proxy strings for a plan",
        "description": "Ready-to-use endpoint strings (credentials included) for one order, in HTTP or SOCKS5 and several formats, with the targeting the plan supports: country/state/city for residential and mobile, ISP code for Residential Premium and Mobile V2, ASN for Residential Basic and traffic-based Datacenter, static gateways for Datacenter. `rotation: sticky` keeps one IP for `sessionTime` minutes; `static` (IPv6 only) is a fixed session with no TTL. Mobile V2 can alternatively return the IP-auth proxy list for a whitelisted `ip`. Premium ISP orders still being provisioned answer 202 with `pending: true`. Which parameters apply depends on the plan type — unsupported ones are ignored, not rejected. Free; no Data API billing (the plan's own bandwidth is consumed when you use the proxies).",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orderId"
                ],
                "properties": {
                  "orderId": {
                    "type": "string",
                    "description": "From GET /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",
                    "description": "`ip:port:user:pass` and the `…@ip:port` spellings are accepted as aliases."
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "default": 10
                  },
                  "country": {
                    "type": "string",
                    "description": "Lowercase country code (e.g. `us`); `all` = none."
                  },
                  "state": {
                    "type": "string",
                    "description": "Region slug (Residential Premium / Mobile V2: from the location tree). Alias `region`."
                  },
                  "city": {
                    "type": "string",
                    "description": "City slug."
                  },
                  "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 session minutes (Residential Basic / Datacenter traffic: min 3 enforced by the gateway)."
                  },
                  "isp": {
                    "type": "string",
                    "description": "ISP code (Residential Premium / Mobile V2) or carrier ASN (Mobile)."
                  },
                  "asn": {
                    "type": "string",
                    "description": "ASN, e.g. `AS12345` (Residential Basic / Datacenter traffic)."
                  },
                  "strict": {
                    "type": "boolean",
                    "default": false,
                    "description": "Residential/Datacenter Basic: `true` allows location fallback."
                  },
                  "filter": {
                    "type": "string",
                    "enum": [
                      "speed",
                      "speed-quality",
                      "quality"
                    ],
                    "description": "Residential Premium / Mobile V2 pool filter (default: max pool)."
                  },
                  "isExtension": {
                    "type": "boolean",
                    "default": false,
                    "description": "Rewrite hostnames with a unique prefix so a browser extension cannot cache the proxy (needs the wildcard DNS of the gateway)."
                  },
                  "ip": {
                    "type": "string",
                    "description": "Mobile V2: a whitelisted IP — returns the IP-auth proxy list instead of user:pass strings."
                  },
                  "gateway": {
                    "type": "string",
                    "enum": [
                      "ww",
                      "us",
                      "eu",
                      "as"
                    ],
                    "default": "ww",
                    "description": "Mobile V2 region gateway."
                  }
                }
              },
              "example": {
                "orderId": "ord_8c21",
                "protocol": "http",
                "format": "user:pass@host:port",
                "quantity": 5,
                "country": "us",
                "rotation": "sticky",
                "sessionTime": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Proxy strings.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/GeneratedProxies"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Success",
                  "payload": {
                    "orderId": "ord_8c21",
                    "quantity": 5,
                    "protocol": "http",
                    "format": "user:pass@host:port",
                    "rotation": "sticky",
                    "sessionTime": 10,
                    "geoTargeting": {
                      "country": "us",
                      "state": null,
                      "city": null
                    },
                    "proxies": [
                      "user_8c21-country-us-session-a1b2c3-time-10:p4ssw0rd@residential-ww.quantumproxies.io:9999",
                      "user_8c21-country-us-session-d4e5f6-time-10:p4ssw0rd@residential-ww.quantumproxies.io:9999"
                    ],
                    "bandwidth": 5,
                    "bandwidthLeft": 3.2,
                    "whitelist": []
                  },
                  "pagination": {}
                }
              }
            }
          },
          "202": {
            "description": "Premium ISP order still being provisioned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "Your ISP proxies are being provisioned. Check back shortly.",
                  "payload": {
                    "orderId": "ord_8c21",
                    "pending": true,
                    "proxies": []
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "Missing orderId, expired plan, inactive sub-user, or a plan type that cannot generate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Proxy has expired"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Order (or its proxy) not found on this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Order or proxy not found"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          },
          "502": {
            "description": "The plan's network did not answer; retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Unable to generate proxies. Please try again."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/public/proxies/generate' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"orderId\":\"ord_8c21\",\"protocol\":\"http\",\"format\":\"user:pass@host:port\",\"quantity\":5,\"country\":\"us\",\"rotation\":\"sticky\",\"sessionTime\":10}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/public/proxies/generate',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"orderId\": \"ord_8c21\",\n        \"protocol\": \"http\",\n        \"format\": \"user:pass@host:port\",\n        \"quantity\": 5,\n        \"country\": \"us\",\n        \"rotation\": \"sticky\",\n        \"sessionTime\": 10\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies/generate\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"orderId\": \"ord_8c21\",\n    \"protocol\": \"http\",\n    \"format\": \"user:pass@host:port\",\n    \"quantity\": 5,\n    \"country\": \"us\",\n    \"rotation\": \"sticky\",\n    \"sessionTime\": 10\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies/generate');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'orderId' => 'ord_8c21',\n    'protocol' => 'http',\n    'format' => 'user:pass@host:port',\n    'quantity' => 5,\n    'country' => 'us',\n    'rotation' => 'sticky',\n    'sessionTime' => 10\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/public/proxies/ip-info": {
      "get": {
        "operationId": "getIpInfo",
        "tags": [
          "Proxies"
        ],
        "summary": "Geolocate an IP",
        "description": "Country, region, city, coordinates, timezone, ISP and ASN of an IP address — useful to verify where a sticky session actually exits. Served by a third-party geolocation source with its own fair-use limit (about 45 lookups/minute shared). Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "ip",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "203.0.113.7"
          }
        ],
        "responses": {
          "200": {
            "description": "IP information.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/IpInfo"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Success",
                  "payload": {
                    "ip": "203.0.113.7",
                    "country": "United States",
                    "countryCode": "US",
                    "flag": "🇺🇸",
                    "region": "California",
                    "regionCode": "CA",
                    "city": "Los Angeles",
                    "zip": "90001",
                    "lat": 34.05,
                    "lon": -118.24,
                    "timezone": "America/Los_Angeles",
                    "isp": "Example Telecom",
                    "org": "Example Telecom LLC",
                    "as": "AS64496 Example Telecom"
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "Missing `ip`, or the lookup source refused the address (private range, malformed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "IP address is required. Use ?ip=x.x.x.x"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/public/proxies/ip-info?ip=203.0.113.7' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/public/proxies/ip-info?ip=203.0.113.7',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies/ip-info?ip=203.0.113.7\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies/ip-info?ip=203.0.113.7');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/public/proxies/whitelist-ip": {
      "get": {
        "operationId": "listWhitelistIps",
        "tags": [
          "Proxies"
        ],
        "summary": "List whitelisted IPs of an order",
        "description": "The IPs allowed to use an IP-auth plan without credentials. Mobile V2 plans also return the detailed upstream entries (ports, geo, sticky) under `entries`. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Whitelist.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "orderId": {
                              "type": "string"
                            },
                            "whitelist_ip": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "entries": {
                              "description": "Upstream entries (Residential Basic, Mobile V2) — shape depends on the plan's network."
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "Success",
                  "payload": {
                    "orderId": "ord_8c21",
                    "whitelist_ip": [
                      "203.0.113.7"
                    ]
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Order not found on this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip?orderId=ORDERID' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip?orderId=ORDERID',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies/whitelist-ip?orderId=ORDERID\", {\n  method: \"GET\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\"\n  }\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies/whitelist-ip?orderId=ORDERID');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY'],\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "post": {
        "operationId": "addWhitelistIp",
        "tags": [
          "Proxies"
        ],
        "summary": "Whitelist an IP",
        "description": "Allows an IPv4 address to use the plan by IP authentication. Supported on Residential Basic, Datacenter (both kinds), ISP, IPv6 and Mobile V2; Residential Premium/Private authenticate by user:pass and answer 200 with `whitelisted: false`. Mobile V2 accepts extra port/targeting options and `action: update` to edit an existing entry. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orderId",
                  "ip"
                ],
                "properties": {
                  "orderId": {
                    "type": "string"
                  },
                  "ip": {
                    "type": "string",
                    "pattern": "^(\\d{1,3}\\.){3}\\d{1,3}$",
                    "description": "IPv4 address."
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "add",
                      "update"
                    ],
                    "default": "add",
                    "description": "Mobile V2 only: `update` edits an existing entry's settings."
                  },
                  "ports_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000,
                    "description": "Mobile V2: ports to allocate."
                  },
                  "protocol": {
                    "type": "string",
                    "enum": [
                      "HTTP",
                      "SOCKS5"
                    ],
                    "description": "Mobile V2."
                  },
                  "country": {
                    "type": "string",
                    "description": "Mobile V2 geo targeting for the allocated ports."
                  },
                  "region": {
                    "type": "string",
                    "description": "Mobile V2."
                  },
                  "city": {
                    "type": "string",
                    "description": "Mobile V2."
                  },
                  "isp": {
                    "type": "string",
                    "description": "Mobile V2."
                  },
                  "sticky": {
                    "type": "boolean",
                    "description": "Mobile V2: keep the same IP per port."
                  },
                  "ttl": {
                    "type": "integer",
                    "description": "Mobile V2: sticky session TTL in seconds."
                  }
                }
              },
              "example": {
                "orderId": "ord_8c21",
                "ip": "203.0.113.7"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Whitelisted (or not applicable to this plan type).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "type": "object",
                          "properties": {
                            "ip": {
                              "type": "string"
                            },
                            "whitelisted": {
                              "type": "boolean"
                            },
                            "alreadyWhitelisted": {
                              "type": "boolean"
                            },
                            "whitelist_ip": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "IP whitelisted successfully",
                  "payload": {
                    "ip": "203.0.113.7",
                    "whitelisted": true,
                    "whitelist_ip": [
                      "203.0.113.7"
                    ]
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "description": "Missing fields, malformed IP, or the plan's network refused the entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "type": "error",
                  "message": "Invalid IP address format"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Order not found on this account (or its residential sub-user is missing).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"orderId\":\"ord_8c21\",\"ip\":\"203.0.113.7\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.post(\n    'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"orderId\": \"ord_8c21\",\n        \"ip\": \"203.0.113.7\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies/whitelist-ip\", {\n  method: \"POST\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"orderId\": \"ord_8c21\",\n    \"ip\": \"203.0.113.7\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies/whitelist-ip');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'POST',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'orderId' => 'ord_8c21',\n    'ip' => '203.0.113.7'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      },
      "delete": {
        "operationId": "removeWhitelistIp",
        "tags": [
          "Proxies"
        ],
        "summary": "Remove a whitelisted IP",
        "description": "Removes the IP from the plan's IP-auth list (Mobile V2 also accepts the entry `id`). Plans that authenticate by user:pass answer 200 with `removed: false`. Free.",
        "x-price-key": null,
        "x-rate-limit": "per-tier",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "orderId",
                  "ip"
                ],
                "properties": {
                  "orderId": {
                    "type": "string"
                  },
                  "ip": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string",
                    "description": "Mobile V2 entry id (alternative handle)."
                  }
                }
              },
              "example": {
                "orderId": "ord_8c21",
                "ip": "203.0.113.7"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Removed (or not applicable).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                },
                "example": {
                  "type": "response",
                  "message": "IP removed from whitelist",
                  "payload": {
                    "ip": "203.0.113.7",
                    "removed": true,
                    "whitelist_ip": []
                  },
                  "pagination": {}
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Order not found on this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip' \\\n  -H 'Authorization: Bearer qp_live_YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"orderId\":\"ord_8c21\",\"ip\":\"203.0.113.7\"}'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.delete(\n    'https://api.quantumproxies.io/v1/public/proxies/whitelist-ip',\n    headers={\"Authorization\": \"Bearer qp_live_YOUR_API_KEY\"},\n    json={\n        \"orderId\": \"ord_8c21\",\n        \"ip\": \"203.0.113.7\"\n    },\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/public/proxies/whitelist-ip\", {\n  method: \"DELETE\",\n  headers: {\n    Authorization: \"Bearer qp_live_YOUR_API_KEY\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify({\n    \"orderId\": \"ord_8c21\",\n    \"ip\": \"203.0.113.7\"\n  })\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/public/proxies/whitelist-ip');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'DELETE',\n  CURLOPT_RETURNTRANSFER => true,\n  CURLOPT_HTTPHEADER => ['Authorization: Bearer qp_live_YOUR_API_KEY', 'Content-Type: application/json'],\n  CURLOPT_POSTFIELDS => json_encode([\n    'orderId' => 'ord_8c21',\n    'ip' => '203.0.113.7'\n  ]),\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    },
    "/mcp/trial-config": {
      "get": {
        "operationId": "getMcpTrialConfig",
        "tags": [
          "Account"
        ],
        "summary": "No-key MCP trial settings",
        "description": "What the keyless trial of the hosted MCP endpoint allows right now for a brand: whether it is on, calls per client address per UTC day, calls across all addresses per day, and which tools it may run. Read by the hosted MCP servers once a minute; nothing secret in it, so it needs no API key and is cacheable for 60 s. The brand comes from `?brand=` or, failing that, from the request host.",
        "x-price-key": null,
        "x-rate-limit": "none",
        "security": [],
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "QP",
                "QD"
              ]
            },
            "description": "QP = QuantumProxies, QD = QuanticData. Defaults to the brand of the host you call."
          }
        ],
        "responses": {
          "200": {
            "description": "Trial settings.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "`public, max-age=60`."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "payload": {
                          "$ref": "#/components/schemas/TrialConfig"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "type": "response",
                  "message": "ok",
                  "payload": {
                    "brand": "QD",
                    "enabled": true,
                    "perIpPerDay": 5,
                    "perDay": 300,
                    "tools": [
                      "scrape",
                      "search",
                      "search_and_read",
                      "map",
                      "seo_audit",
                      "list_collectors",
                      "collector_run_status",
                      "proxy_locations"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://api.quantumproxies.io/v1/mcp/trial-config'",
            "x-id": "curl"
          },
          {
            "lang": "python",
            "label": "Python (requests)",
            "source": "import requests\n\nr = requests.get(\n    'https://api.quantumproxies.io/v1/mcp/trial-config',\n    timeout=120,\n)\ndata = r.json()\nif data[\"type\"] != \"response\":\n    raise SystemExit(data[\"message\"])\nprint(data[\"payload\"])",
            "x-id": "python"
          },
          {
            "lang": "javascript",
            "label": "Node (fetch)",
            "source": "const res = await fetch(\"https://api.quantumproxies.io/v1/mcp/trial-config\", {\n  method: \"GET\"\n});\nconst data = await res.json();\nif (data.type !== \"response\") throw new Error(data.message);\nconsole.log(data.payload);",
            "x-id": "node"
          },
          {
            "lang": "php",
            "label": "PHP (curl)",
            "source": "<?php\n$ch = curl_init('https://api.quantumproxies.io/v1/mcp/trial-config');\ncurl_setopt_array($ch, [\n  CURLOPT_CUSTOMREQUEST => 'GET',\n  CURLOPT_RETURNTRANSFER => true,\n]);\n$raw = curl_exec($ch);\ncurl_close($ch);\n$data = json_decode($raw, true);\nif ($data['type'] !== 'response') { throw new RuntimeException($data['message']); }\nprint_r($data['payload']);",
            "x-id": "php"
          }
        ]
      }
    }
  }
}