{"openapi":"3.1.0","info":{"title":"ScrapingPros API","description":"ScrapingPros API for web scraping.","version":"0.1.0"},"paths":{"/v1/health":{"get":{"tags":["health"],"summary":"Health Check","description":"Comprehensive health check — no authentication required.","operationId":"health_check_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/plans":{"get":{"tags":["plans"],"summary":"List Plans","description":"List all available plans with pricing, credits, features, and limits.\n\nPublic endpoint — no authentication required. Use this to display pricing\ninformation and help users choose the right plan.\n\nThe credit system: 1 simple request = 1 credit, 1 browser request = 5 credits.\nAnti-bot protection (Camoufox) and proxy rotation are included at no extra cost.\nCredits are NOT consumed for requests that fail due to our infrastructure errors\n(timeouts, proxy failures, connection errors).","operationId":"list_plans_v1_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/sync/scrape":{"post":{"tags":["Synchronous Endpoints"],"summary":"Scrape","description":"Scrape a URL and return its content as HTML or clean markdown.\n\nThis is the core endpoint. Supports simple HTTP requests (fast, ~1-3s) and\nfull browser rendering with Camoufox anti-detection (for JavaScript-heavy sites).\n\n**Key features:**\n- `format=\"markdown\"` → clean text output (strips scripts/styles/nav, ideal for AI/LLM)\n- `browser=true` → headless browser for SPAs, dynamic content, anti-bot protected sites\n- `use_proxy=\"any\"` → automatic proxy rotation across 950+ proxies\n- `use_proxy=\"US\"` → country-specific proxy (requires prior approval)\n- `retry_on_block=true` → auto-retry on CAPTCHA/403, up to 3 retries with different IP/fingerprint\n- `extract={\"title\": \"css:h1\"}` → structured data extraction with CSS/XPath selectors\n- `actions=[...]` → browser automation (click, type, scroll, evaluate JavaScript)\n- `screenshot=true` → full-page screenshot as base64 PNG\n- `network_capture={\"resource_types\": [\"xhr\"]}` → capture network requests\n\n**Response includes:** html (or markdown), statusCode, extracted_data, screenshot,\ntimings (always present, even on errors), potentiallyBlockedByCaptcha detection.\n\n**Credits:** 1 credit per simple request, 5 credits per browser request. No charge on infra errors.\n\n**Demo token:** Use `demo_6x595maoA6GdOdVb` to try without signup (5,000 credits/month).","operationId":"scrape_v1_sync_scrape_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScrapeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScrapeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/sync/download":{"post":{"tags":["Synchronous Endpoints"],"summary":"Download","description":"Download a file (PDF, image, document) from a URL via headless browser.\n\nReturns the file content as base64-encoded string with detected MIME type.\nSupports proxy rotation. Use this for files that require browser rendering\nor authentication headers to download.\n\n**Credits:** 1 credit per download (same as simple request).","operationId":"download_v1_sync_download_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/sync/metrics":{"get":{"tags":["Synchronous Endpoints"],"summary":"Metrics","description":"Get global API metrics (admin only). Regular clients: use /client-metrics instead.\n\nReturns aggregated scraping statistics: request counts by type, success rates,\ntop domains, proxy usage, and response codes.\n\n**Params:** `date` (YYYY-MM-DD or range YYYY-MM-DD:YYYY-MM-DD), `metric` (url, proxy, api_codes, page_codes, exe_time, scrape_type).","operationId":"metrics_v1_sync_metrics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"date","in":"query","required":false,"schema":{"type":"string","default":"","title":"Date"}},{"name":"metric","in":"query","required":false,"schema":{"type":"string","default":"","title":"Metric"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sync/client-metrics":{"get":{"tags":["Synchronous Endpoints"],"summary":"Client Metrics","description":"Your usage metrics — requests, success rates, and per-domain breakdown.\n\nShows only your own data. Includes total requests, success/failed counts,\nbrowser vs simple breakdown, and top domains scraped.\n\n**Params:** `date` (YYYY-MM-DD, range, or YYYY-MM for full month), `hourly=true` for per-hour breakdown, `detail=urls` for per-domain stats.","operationId":"client_metrics_v1_sync_client_metrics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"date","in":"query","required":false,"schema":{"type":"string","default":"","title":"Date"}},{"name":"client","in":"query","required":false,"schema":{"type":"string","default":"","title":"Client"}},{"name":"hourly","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Hourly"}},{"name":"detail","in":"query","required":false,"schema":{"type":"string","default":"","title":"Detail"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientMetricsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sync/billing":{"get":{"tags":["Synchronous Endpoints"],"summary":"Billing","description":"Your monthly billing summary — precise request counts and credit consumption.\n\nReturns simple/browser success/failed counts, total requests, and credit breakdown\n(1 simple = 1 credit, 1 browser = 5 credits). Use `detail=urls` for per-domain costs.\n\n**Params:** `month` (YYYY-MM, default: current month), `detail=urls` for domain breakdown.\n\n**Credit system:** Each response includes a `credits` object per client showing\nsimple credits, browser credits, and total credits consumed.","operationId":"billing_v1_sync_billing_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":false,"schema":{"type":"string","default":"","title":"Month"}},{"name":"client","in":"query","required":false,"schema":{"type":"string","default":"","title":"Client"}},{"name":"detail","in":"query","required":false,"schema":{"type":"string","default":"","title":"Detail"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/collections":{"get":{"tags":["Asynchronous Endpoints"],"summary":"Get Collections","description":"Returns the collections created.\n\nReturns:\n    A JSON response containing the collections.","operationId":"get_collections_v1_async_collections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CollectionPublic"},"type":"array","title":"Response Get Collections V1 Async Collections Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Asynchronous Endpoints"],"summary":"Create Collection","description":"Create a batch of URLs for async processing.\n\nA collection groups multiple scrape requests that execute in parallel.\nEach request supports the same options as `/sync/scrape` (browser, proxy, extract, etc.).\nMax 1,000 URLs per collection. URLs validated for SSRF protection.\n\n**Webhook support:** Add `callback_url` to receive a signed POST notification when a run\ncompletes. The webhook payload includes event, run_id, status, counters, and job_ids.\nDelivery is verified via HMAC-SHA256 signature (`X-SP-Signature` header).\n\n**Workflow:** Create collection → `POST /collections/{id}/run` → poll `GET /runs/{run_id}`\n(or wait for webhook) → fetch results with `GET /runs/{run_id}/jobs/{job_id}/result`.","operationId":"create_collection_v1_async_collections_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCollectionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCollectionResponse"}}}},"400":{"description":"Request validation error."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/async/collections/{collection_id}":{"get":{"tags":["Asynchronous Endpoints"],"summary":"Get Collection","description":"Returns the collection with the given ID.\n\nArgs:\n    collection_id: The ID of the collection to retrieve.\n\nReturns:\n    A JSON response containing the collection.","operationId":"get_collection_v1_async_collections__collection_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionPublic"}}}},"404":{"description":"404: Collection not found."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Asynchronous Endpoints"],"summary":"Update Collection","description":"Updates the collection with the given ID.\n\nChanges cannot be undone. Everything from the collection can be changed. If\na list of requests is sent, the current one is replaced.\n\nArgs:\n    collection_id: The ID of the collection to update.\n    A JSON with the collection name and optionally a list of requests.\n\nReturns:\n    A JSON response containing the updated collection.","operationId":"update_collection_v1_async_collections__collection_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCollectionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewCollectionResponse"}}}},"400":{"description":"Request validation error."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Asynchronous Endpoints"],"summary":"Delete Collection","description":"Delete a collection and its associated jobs.\n\nThis removes the collection from the index and cleans up all job data.\nRuns that were already executed are not affected (their data persists\nin MySQL metrics).","operationId":"delete_collection_v1_async_collections__collection_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/collections/{collection_id}/run":{"post":{"tags":["Asynchronous Endpoints"],"summary":"Generate Run For Collection","description":"Execute a collection — starts async processing of all URLs.\n\nReturns immediately with a `run_id`. Poll `GET /runs/{run_id}` for status,\nor use `callback_url` (set on the collection) to receive a webhook when complete.\nResponse includes `job_ids` to fetch individual results with `GET /jobs/{job_id}/result`.\nA collection can be run multiple times (re-scrape the same URLs).\n\n**Webhook fields in response:** `callback_url` (the webhook URL) and `callback_status`\n(pending → sent / failed / retrying).\n\nArgs:\n    collection_id: The ID of the collection to run.\n\nReturns:\n    A JSON response containing the ID of the new run.","operationId":"generate_run_for_collection_v1_async_collections__collection_id__run_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunPublic"}}}},"404":{"description":"404: Collection not exists or Collection does not requests associated."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/collections/{collection_id}/runs/{run_id}":{"get":{"tags":["Asynchronous Endpoints"],"summary":"Get Run Result","description":"Get run status, progress counters, job IDs, and webhook delivery status.\n\nReturns `total_requests`, `success_requests`, `failed_requests`, `timeout_requests`,\n`job_ids` (to fetch individual results), and webhook fields (`callback_url`, `callback_status`).\n\n**Timings note:** `callback_status` tracks webhook delivery: pending → sent / failed / retrying.","operationId":"get_run_result_v1_async_collections__collection_id__runs__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunPublic"}}}},"404":{"description":"404: Run not found. | 404: Run not found for the given collection."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/collections/{collection_id}/runs/{run_id}/jobs":{"get":{"tags":["Asynchronous Endpoints"],"summary":"Get Job Executions","description":"Returns the job executions for a given run within a collection.\n\nArgs:\n    collection_id: The ID of the collection.\n    run_id: The ID of the run.\n\nReturns:\n    A JSON response containing the list of job executions.","operationId":"get_job_executions_v1_async_collections__collection_id__runs__run_id__jobs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobExecutionListPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/collections/{collection_id}/runs/{run_id}/jobs/{job_id}/result":{"get":{"tags":["Asynchronous Endpoints"],"summary":"Get Job Result","description":"Returns the full scrape result (HTML/markdown, extracted data, screenshot, etc.)\nfor a specific job in a completed run.\n\nResults are available for 24 hours after job completion. After that,\nthey expire from Redis and this endpoint returns 404.\n\nArgs:\n    collection_id: The ID of the collection.\n    run_id: The ID of the run.\n    job_id: The ID of the specific job.\n\nReturns:\n    The full scrape result including html, markdown, statusCode, extracted_data, etc.","operationId":"get_job_result_v1_async_collections__collection_id__runs__run_id__jobs__job_id__result_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"collection_id","in":"path","required":true,"schema":{"type":"string","title":"Collection Id"}},{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/async/viability-test":{"post":{"tags":["Viability Test"],"summary":"Create Viability Test","description":"Submit a list of URLs for viability analysis.\n\nReturns a run_id immediately. Poll GET /v1/async/viability-test/{run_id} for results.\nEach URL is analyzed for: CAPTCHA protection, browser necessity, content type,\nrate limiting, login walls, and API/XHR endpoints.","operationId":"create_viability_test_v1_async_viability_test_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViabilityTestRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViabilityRunPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/async/viability-test/{run_id}":{"get":{"tags":["Viability Test"],"summary":"Get Viability Test","description":"Poll the status and results of a viability test run.\n\nReturns status 'in_progress' while processing, 'completed' when done (results included).","operationId":"get_viability_test_v1_async_viability_test__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViabilityRunPublic"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/proxy/countries":{"get":{"tags":["proxy"],"summary":"List Countries","description":"List all 200+ countries available for geo-targeted proxy scraping.\n\nReturns ISO country codes (US, GB, AR, etc.). Use these codes with\n`use_proxy=\"US\"` in the scrape endpoint for country-specific IP addresses.\nCountry proxy access requires prior approval via `/request-country`.","operationId":"list_countries_v1_proxy_countries_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyCountriesResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/proxy/request-country":{"post":{"tags":["proxy"],"summary":"Request Country","description":"Request access to a country's proxy pool.\n\nSubmit a request to use proxies from a specific country. An admin reviews\nand approves. Once approved, use `use_proxy=\"US\"` (or your country code) in scrape requests.\nReturns `status: \"pending\"` (awaiting approval) or `\"already_approved\"`.","operationId":"request_country_v1_proxy_request_country_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyRequestCountryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/proxy/status":{"get":{"tags":["proxy"],"summary":"Proxy Status","description":"Check your country proxy approvals — which countries are approved, pending, or denied.\n\nReturns lists of `approved_countries` (ready to use) and `pending_countries` (awaiting admin review).","operationId":"proxy_status_v1_proxy_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"BillingClientData":{"properties":{"simple_success":{"type":"integer","title":"Simple Success","default":0},"simple_failed":{"type":"integer","title":"Simple Failed","default":0},"simple_total":{"type":"integer","title":"Simple Total","default":0},"browser_success":{"type":"integer","title":"Browser Success","default":0},"browser_failed":{"type":"integer","title":"Browser Failed","default":0},"browser_total":{"type":"integer","title":"Browser Total","default":0},"total_requests":{"type":"integer","title":"Total Requests","default":0},"total_success":{"type":"integer","title":"Total Success","default":0},"total_failed":{"type":"integer","title":"Total Failed","default":0},"credits":{"$ref":"#/components/schemas/BillingCredits","description":"Credit consumption breakdown"},"by_url":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/BillingUrlBreakdown"},"type":"object"},{"type":"null"}],"title":"By Url","description":"Per-domain breakdown (only when detail=urls)"}},"type":"object","required":["credits"],"title":"BillingClientData","description":"Billing data for a single client."},"BillingCredits":{"properties":{"simple":{"type":"integer","title":"Simple","description":"Credits consumed by simple requests (1 credit each)"},"browser":{"type":"integer","title":"Browser","description":"Credits consumed by browser requests (5 credits each)"},"total":{"type":"integer","title":"Total","description":"Total credits consumed"}},"type":"object","required":["simple","browser","total"],"title":"BillingCredits","description":"Credit consumption for a client."},"BillingResponse":{"properties":{"month":{"type":"string","title":"Month","description":"Billing period (YYYY-MM)"},"clients":{"additionalProperties":{"$ref":"#/components/schemas/BillingClientData"},"type":"object","title":"Clients","description":"Billing data by client_id"},"credit_system":{"$ref":"#/components/schemas/CreditSystemInfo","description":"Credit multipliers"}},"type":"object","required":["month","clients","credit_system"],"title":"BillingResponse","description":"Response model for GET /v1/sync/billing."},"BillingUrlBreakdown":{"properties":{"simple_success":{"type":"integer","title":"Simple Success","default":0},"simple_failed":{"type":"integer","title":"Simple Failed","default":0},"browser_success":{"type":"integer","title":"Browser Success","default":0},"browser_failed":{"type":"integer","title":"Browser Failed","default":0},"total":{"type":"integer","title":"Total","default":0}},"type":"object","title":"BillingUrlBreakdown","description":"Per-domain billing breakdown."},"ClickAction":{"properties":{"selector":{"type":"string","title":"Selector"},"type":{"type":"string","const":"click","title":"Type"},"wait_for_navigation":{"type":"boolean","title":"Wait For Navigation","default":false},"optional":{"type":"boolean","title":"Optional","default":false}},"type":"object","required":["selector","type"],"title":"ClickAction"},"ClientMetricsResponse":{"properties":{"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date","description":"Date or date range queried"},"scrape_type":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Scrape Type","description":"Breakdown by scrape type (browser/simple) with counts and rates"},"url":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Url","description":"Per-domain breakdown (when detail=urls)"},"hourly":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Hourly","description":"Per-hour breakdown (when hourly=true)"}},"type":"object","title":"ClientMetricsResponse","description":"Response model for GET /v1/sync/client-metrics.\n\nThe shape depends on parameters (date, hourly, detail), so we use\na flexible model that documents the top-level keys while allowing\nthe inner structure to vary."},"CollectAction":{"properties":{"type":{"type":"string","const":"collect","title":"Type"},"extract":{"additionalProperties":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"}]},"type":"object","title":"Extract","description":"Selectors to extract. Same format as the top-level extract parameter.","example":{"link_urls":{"attribute":"href","multiple":true,"selector":"css:a.product-link"},"prices":{"multiple":true,"selector":"css:.price"},"product_names":{"multiple":true,"selector":"css:.product-title"}}}},"type":"object","required":["type","extract"],"title":"CollectAction","description":"Action that extracts data from the current page and accumulates it\nin memory across while loop iterations.\n\nExample:\n{\n    \"type\": \"collect\",\n    \"extract\": {\n        \"product_names\": {\n            \"selector\": \"css:.product-title\",\n            \"multiple\": true\n        },\n        \"prices\": {\n            \"selector\": \"css:.price\",\n            \"multiple\": true\n        }\n    }\n}"},"CollectionPublic":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"CollectionPublic","description":"Response model for Get Collection/s"},"CountryRequest":{"properties":{"country_code":{"type":"string","title":"Country Code"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["country_code"],"title":"CountryRequest"},"CreditSystemInfo":{"properties":{"simple_request":{"type":"integer","title":"Simple Request","description":"Credits per simple HTTP request"},"browser_request":{"type":"integer","title":"Browser Request","description":"Credits per browser request"}},"type":"object","required":["simple_request","browser_request"],"title":"CreditSystemInfo","description":"Credit system description."},"DownloadRequest":{"properties":{"url":{"type":"string","title":"Url"},"use_proxy":{"anyOf":[{"$ref":"#/components/schemas/ProxyConfig"},{"type":"string"},{"type":"null"}],"title":"Use Proxy"}},"type":"object","required":["url"],"title":"DownloadRequest","description":"Request model for the file download endpoint."},"DownloadResponse":{"properties":{"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"contentType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contenttype"},"statusCode":{"type":"integer","title":"Statuscode"},"message":{"type":"string","title":"Message"},"executionTime":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Executiontime"}},"type":"object","required":["statusCode","message"],"title":"DownloadResponse","description":"Response model for the file download endpoint."},"EvaluateAction":{"properties":{"type":{"type":"string","const":"evaluate","title":"Type"},"script":{"type":"string","title":"Script","description":"JavaScript code to execute in the page context. Can be a simple expression or an async function.","example":"document.title"},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout","description":"Maximum time in ms to wait for JS execution (default 30s)","default":30000}},"type":"object","required":["type","script"],"title":"EvaluateAction","description":"Action that executes JavaScript in the browser page context.\n\nBasic example:\n{\n    \"type\": \"evaluate\",\n    \"script\": \"document.title\"\n}\n\n**AJAX forms** — when a page uses a JS-driven booking/search form that POSTs\nto an internal endpoint (e.g. /avl, /search/availability), the form submission\ncannot be triggered with a simple click because the handler lives in a closed\nJS scope (not accessible via window). Instead, use fetch() inside evaluate so\nthe request runs with the page's session cookies and is captured by the network\nlistener:\n\n{\n    \"type\": \"evaluate\",\n    \"script\": \"(async () => { const form = document.querySelector('#myForm'); const data = new URLSearchParams(new FormData(form)); const r = await fetch('/avl', {method: 'POST', headers: {'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded'}, body: data.toString()}); return r.status; })()\"\n}\n\nTypical action sequence for an AJAX booking form:\n  1. wait-for-selector  → ensure the form is ready\n  2. input / select     → populate visible fields\n  3. evaluate           → set hidden fields (e.g. checkin/checkout) directly via DOM\n  4. evaluate           → fire the fetch() call above\n  5. wait-for-timeout   → allow the response to be captured before analysis"},"FailedJobPublic":{"properties":{"job_id":{"type":"string","title":"Job Id"},"url":{"type":"string","title":"Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"status":{"type":"string","title":"Status"}},"type":"object","required":["job_id","url","status"],"title":"FailedJobPublic"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InputAction":{"properties":{"selector":{"type":"string","title":"Selector"},"type":{"type":"string","const":"input","title":"Type"},"text":{"type":"string","title":"Text"}},"type":"object","required":["selector","type","text"],"title":"InputAction"},"JobExecutionListPublic":{"properties":{"items":{"items":{"$ref":"#/components/schemas/JobExecutionPublic"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"JobExecutionListPublic"},"JobExecutionPublic":{"properties":{"job_public_id":{"type":"string","format":"uuid","title":"Job Public Id"},"run_public_id":{"type":"string","format":"uuid","title":"Run Public Id"},"collection_id":{"type":"string","format":"uuid","title":"Collection Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"execution_time_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Execution Time Sec"}},"type":"object","required":["job_public_id","run_public_id","collection_id","status"],"title":"JobExecutionPublic"},"JobStatus":{"type":"string","enum":["processing","completed","failed","timeout"],"title":"JobStatus"},"KeyPressAction":{"properties":{"type":{"type":"string","const":"key-press","title":"Type"},"key":{"type":"string","title":"Key"}},"type":"object","required":["type","key"],"title":"KeyPressAction"},"MethodGET":{"properties":{"method":{"type":"string","const":"get","title":"Method","default":"get"}},"type":"object","title":"MethodGET"},"MethodPOST":{"properties":{"method":{"type":"string","const":"post","title":"Method","default":"post"},"payload":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Payload"},"content_type":{"type":"string","enum":["json","form"],"title":"Content Type","default":"json"}},"type":"object","title":"MethodPOST"},"ModeTestResult":{"properties":{"success":{"type":"boolean","title":"Success","description":"True if the mode returned real content without CAPTCHA/block"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code","description":"HTTP status from the target page"},"blocked":{"type":"boolean","title":"Blocked","description":"True if CAPTCHA or block detected","default":false},"captcha_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captcha Type","description":"Specific CAPTCHA provider if detected"},"time_ms":{"type":"integer","title":"Time Ms","description":"Total time for this mode in milliseconds","default":0},"credits":{"type":"integer","title":"Credits","description":"Credits consumed by this mode","default":0},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message if the mode failed to execute"}},"type":"object","required":["success"],"title":"ModeTestResult","description":"Result of testing a single scraping mode."},"NetworkCaptureConfig":{"properties":{"resource_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Resource Types","description":"Filter captured requests by resource type. Valid values: document, eventsource, fetch, font, image, manifest, media, other, script, stylesheet, texttrack, websocket, xhr. null = capture all types."},"listen_after_load_ms":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":0.0},{"type":"null"}],"title":"Listen After Load Ms","description":"Extra milliseconds to keep listening for network activity after the page finishes loading (max 10 000 ms)."}},"type":"object","title":"NetworkCaptureConfig","description":"Configuration for capturing network requests made during a browser scrape."},"NewCollectionRequest":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the collection","default":"New Collection"},"requests":{"anyOf":[{"items":{"$ref":"#/components/schemas/ScrapeRequest"},"type":"array"},{"type":"null"}],"title":"Requests","description":"List of requests to be run in the collection"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url","description":"Webhook URL to POST when a run of this collection completes. Can be overridden per-run."}},"type":"object","title":"NewCollectionRequest","description":"Request model for the create collection endpoint."},"NewCollectionResponse":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"message":{"type":"string","title":"Message"},"duplicates_skipped":{"type":"integer","title":"Duplicates Skipped","default":0}},"type":"object","required":["message"],"title":"NewCollectionResponse","description":"Response model for the scrape endpoint."},"ProxyConfig":{"properties":{"proxy":{"type":"string","title":"Proxy","default":"any"},"max_retries":{"type":"integer","title":"Max Retries","default":3},"delay_seconds":{"type":"integer","title":"Delay Seconds","default":1},"backoff_factor":{"type":"integer","title":"Backoff Factor","default":2}},"type":"object","title":"ProxyConfig","example":{"backoff_factor":2,"delay_seconds":1,"max_retries":3,"proxy":"US"}},"ProxyCountriesResponse":{"properties":{"countries":{"items":{"type":"string"},"type":"array","title":"Countries"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["countries"],"title":"ProxyCountriesResponse"},"ProxyRequestCountryResponse":{"properties":{"status":{"type":"string","title":"Status"},"country_code":{"type":"string","title":"Country Code"},"message":{"type":"string","title":"Message"}},"type":"object","required":["status","country_code","message"],"title":"ProxyRequestCountryResponse"},"ProxyStatusResponse":{"properties":{"client_id":{"type":"string","title":"Client Id"},"approved_countries":{"items":{"type":"string"},"type":"array","title":"Approved Countries"},"pending_countries":{"items":{"type":"string"},"type":"array","title":"Pending Countries"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["client_id","approved_countries","pending_countries"],"title":"ProxyStatusResponse"},"RunPublic":{"properties":{"run_id":{"type":"string","format":"uuid","title":"Run Id"},"status":{"type":"string","title":"Status","default":"in_progress"},"total_requests":{"type":"integer","minimum":0.0,"title":"Total Requests","default":0},"success_requests":{"type":"integer","minimum":0.0,"title":"Success Requests","default":0},"failed_requests":{"type":"integer","minimum":0.0,"title":"Failed Requests","default":0},"timeout_requests":{"type":"integer","minimum":0.0,"title":"Timeout Requests","default":0},"collection_id":{"type":"string","format":"uuid","title":"Collection Id"},"failed_jobs":{"items":{"$ref":"#/components/schemas/FailedJobPublic"},"type":"array","title":"Failed Jobs"},"job_ids":{"items":{"type":"string"},"type":"array","title":"Job Ids","description":"Job IDs in this run (available for 24h in Redis)"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url","description":"Webhook URL for run completion notification"},"callback_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Status","description":"Webhook delivery status: pending, sent, failed, retrying"}},"type":"object","required":["run_id","collection_id"],"title":"RunPublic"},"ScrapeGuidance":{"properties":{"success":{"type":"boolean","title":"Success","description":"True only if real content was returned without CAPTCHA/blocks"},"error_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Type","description":"Classified error: captcha, timeout, proxy_error, ssl_error, dns_error, empty_content, rate_limited, site_error, country_not_approved, unknown"},"error_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Provider","description":"CAPTCHA/block provider if detected: cloudflare, amazon, datadome, perimeterx, akamai, recaptcha, hcaptcha"},"credits_charged":{"type":"integer","title":"Credits Charged","description":"Credits charged for this request. 0 if refunded.","default":0},"credits_refunded":{"type":"boolean","title":"Credits Refunded","description":"True if credits were refunded (infrastructure error)","default":false},"next_steps":{"items":{"type":"string"},"type":"array","title":"Next Steps","description":"Ordered actions to try next. Empty on success."},"suggested_request":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Suggested Request","description":"Ready-to-use request body for next attempt. null if no retry recommended."},"stop_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stop Reason","description":"If present, do NOT retry. Explains why retrying won't help."}},"type":"object","required":["success"],"title":"ScrapeGuidance","description":"AI-friendly guidance for understanding and acting on scrape results.\n\nAlways present in responses. When success=true, next_steps is empty.\nWhen success=false, next_steps explains what to try next.\nWhen stop_reason is set, do NOT retry — the issue is permanent."},"ScrapeRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Target URL to scrape. Must be http:// or https://.","examples":["https://example.com"]},"browser":{"type":"boolean","title":"Browser","description":"Enable headless browser rendering. Required for JavaScript-heavy sites, SPAs, and anti-bot protected pages.","default":false},"browser_type":{"type":"string","enum":["light","heavy"],"title":"Browser Type","description":"'heavy' (Camoufox, Firefox-based anti-detection) or 'light' (Playwright Chromium, faster but less stealth).","default":"heavy"},"format":{"type":"string","enum":["html","markdown"],"title":"Format","description":"Response format. 'html' returns raw HTML. 'markdown' returns clean text stripped of scripts/styles/nav — ideal for AI/LLM consumption.","default":"html"},"use_proxy":{"anyOf":[{"$ref":"#/components/schemas/ProxyConfig"},{"type":"string"},{"type":"null"}],"title":"Use Proxy","description":"Proxy config. 'any' for automatic rotation, 'US'/'GB'/etc for country-specific (requires approval), or object {proxy, max_retries, delay_seconds, backoff_factor}.","examples":["any","US"]},"screenshot":{"type":"boolean","title":"Screenshot","description":"Capture full-page screenshot as base64 PNG. Requires browser=true.","default":false},"actions":{"anyOf":[{"items":{"oneOf":[{"$ref":"#/components/schemas/While"},{"$ref":"#/components/schemas/ClickAction"},{"$ref":"#/components/schemas/CollectAction"},{"$ref":"#/components/schemas/InputAction"},{"$ref":"#/components/schemas/KeyPressAction"},{"$ref":"#/components/schemas/SelectAction"},{"$ref":"#/components/schemas/WaitForSelectorAction"},{"$ref":"#/components/schemas/WaitForTimeoutAction"},{"$ref":"#/components/schemas/EvaluateAction"}],"discriminator":{"propertyName":"type","mapping":{"click":"#/components/schemas/ClickAction","collect":"#/components/schemas/CollectAction","evaluate":"#/components/schemas/EvaluateAction","input":"#/components/schemas/InputAction","key-press":"#/components/schemas/KeyPressAction","select":"#/components/schemas/SelectAction","wait-for-selector":"#/components/schemas/WaitForSelectorAction","wait-for-timeout":"#/components/schemas/WaitForTimeoutAction","while":"#/components/schemas/While"}}},"type":"array"},{"type":"null"}],"title":"Actions","description":"Browser automation actions: click, input, select, key-press, wait-for-selector, wait-for-timeout, evaluate (JS), while loops, collect. Requires browser=true."},"language":{"type":"string","title":"Language","description":"Accept-Language header and browser locale. Example: 'en-US', 'es-AR'.","default":""},"http_method":{"anyOf":[{"$ref":"#/components/schemas/MethodGET"},{"$ref":"#/components/schemas/MethodPOST"},{"type":"null"}],"title":"Http Method","description":"For POST/PUT requests: {method: 'post', payload: {...}}. Cannot combine with browser=true."},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Custom HTTP headers sent with the request. Max 20 headers, 4KB each."},"window_size":{"type":"string","title":"Window Size","description":"Browser viewport: 'desktop' (random 1920x1080/1366x768/1280x720), 'mobile' (360x800/390x844/412x915), or 'any'.","default":""},"retry_on_block":{"type":"boolean","title":"Retry On Block","description":"If true, automatically retry with different IP/fingerprint when CAPTCHA or 403 detected. Max 3 retries. Only charges credits for the successful attempt.","default":false},"cookies":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Cookies","description":"Optional set cookies before scraping","example":{"name_1":"value_1","name_2":"value_2","name_3":"value_3","name_N":"value_N"}},"extract":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"}]},"type":"object"},{"type":"null"}],"title":"Extract","description":"Extract specific data using selectors. Supports simple format (string) or advanced format (object with selector, multiple, and attribute flags).","example":{"all_paragraphs":{"multiple":true,"selector":"css:p"},"first_link_href":{"attribute":"href","selector":"css:a"},"product_classes":{"attribute":"class","multiple":true,"selector":"css:h3.poly-component__title-wrapper"},"title":"css:h1"}},"network_capture":{"anyOf":[{"$ref":"#/components/schemas/NetworkCaptureConfig"},{"type":"null"}],"description":"Capture network requests made during the page load. Requires browser=true."},"count_for_tracking":{"type":"boolean","title":"Count For Tracking","default":false}},"type":"object","required":["url"],"title":"ScrapeRequest","description":"Request model for the scrape endpoint."},"ScrapeResponse":{"properties":{"html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html"},"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown"},"statusCode":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Statuscode"},"message":{"type":"string","title":"Message"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot"},"executionTime":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Executiontime"},"extracted_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extracted Data"},"evaluate_results":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Evaluate Results"},"network_requests":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Network Requests"},"potentiallyBlockedByCaptcha":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Potentiallyblockedbycaptcha"},"timings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Timings"},"guidance":{"anyOf":[{"$ref":"#/components/schemas/ScrapeGuidance"},{"type":"null"}],"description":"AI-friendly guidance: why the request failed, what to try next, when to stop retrying."}},"type":"object","required":["message"],"title":"ScrapeResponse","description":"Response model for the scrape endpoint."},"SelectAction":{"properties":{"selector":{"type":"string","title":"Selector"},"type":{"type":"string","const":"select","title":"Type"},"value":{"type":"string","title":"Value"}},"type":"object","required":["selector","type","value"],"title":"SelectAction"},"SelectorInvisibleCondition":{"properties":{"type":{"type":"string","const":"selector-invisible","title":"Type"},"selector":{"type":"string","title":"Selector"}},"type":"object","required":["type","selector"],"title":"SelectorInvisibleCondition"},"SelectorVisibleCondition":{"properties":{"type":{"type":"string","const":"selector-visible","title":"Type"},"selector":{"type":"string","title":"Selector"}},"type":"object","required":["type","selector"],"title":"SelectorVisibleCondition"},"UrlViabilityResult":{"properties":{"url":{"type":"string","title":"Url"},"depth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Depth","description":"Analysis depth used: quick, standard, or full"},"modes_tested":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/ModeTestResult"},"type":"object"},{"type":"null"}],"title":"Modes Tested","description":"Results per scraping mode tested: simple, simple_proxy, browser, browser_proxy"},"best_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Mode","description":"First mode that succeeded (simple, simple_proxy, browser, browser_proxy), or null if all failed"},"total_credits_used":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Credits Used","description":"Total credits consumed across all modes tested"},"captcha_detected":{"type":"boolean","title":"Captcha Detected"},"captcha_providers":{"items":{"type":"string"},"type":"array","title":"Captcha Providers"},"javascript_detected":{"type":"boolean","title":"Javascript Detected"},"javascript_required":{"type":"boolean","title":"Javascript Required"},"browser_confidence":{"type":"number","title":"Browser Confidence"},"content_type":{"type":"string","title":"Content Type"},"rate_limited":{"type":"boolean","title":"Rate Limited"},"soft_block":{"type":"boolean","title":"Soft Block"},"retry_after":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Retry After"},"login_wall":{"type":"boolean","title":"Login Wall"},"status_code":{"type":"integer","title":"Status Code"},"redirect_chain":{"items":{"type":"string"},"type":"array","title":"Redirect Chain"},"protection_signals":{"additionalProperties":{"type":"string"},"type":"object","title":"Protection Signals"},"api_detected":{"type":"boolean","title":"Api Detected"},"api_endpoints":{"items":{"type":"string"},"type":"array","title":"Api Endpoints"},"graphql_detected":{"type":"boolean","title":"Graphql Detected"},"api_auth_required":{"type":"boolean","title":"Api Auth Required"},"cloudflare_level":{"type":"string","title":"Cloudflare Level"},"can_use_simple_request":{"type":"boolean","title":"Can Use Simple Request"},"can_use_extract_html":{"type":"boolean","title":"Can Use Extract Html"},"can_use_browser":{"type":"boolean","title":"Can Use Browser"},"recommended_strategy":{"type":"string","title":"Recommended Strategy","description":"Strategy label: 'api', 'extract_html', 'browser', or specific blocker like 'captcha (datadome)', 'cloudflare_challenge', 'login_required', 'multiple_protections'"},"suggested_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Action","description":"Human-readable recommendation: what to do, which parameters to use, and what to expect."},"blocked_by":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Blocked By","description":"List of specific blockers detected (e.g. ['captcha (cloudflare)', 'cloudflare_challenge']). Null when not blocked."},"difficulty":{"anyOf":[{"type":"string","enum":["easy","medium","hard"]},{"type":"null"}],"title":"Difficulty","description":"Estimated scraping difficulty based on detected protections."},"suggested_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Suggested Params","description":"Ready-to-use parameters for /v1/sync/scrape based on the analysis (e.g. {url, browser: true, use_proxy: 'any', retry_on_block: true})."},"proxy_recommended":{"type":"boolean","title":"Proxy Recommended"},"proxy_type":{"type":"string","title":"Proxy Type"}},"type":"object","required":["url","captcha_detected","captcha_providers","javascript_detected","javascript_required","browser_confidence","content_type","rate_limited","soft_block","retry_after","login_wall","status_code","redirect_chain","protection_signals","api_detected","api_endpoints","graphql_detected","api_auth_required","cloudflare_level","can_use_simple_request","can_use_extract_html","can_use_browser","recommended_strategy","proxy_recommended","proxy_type"],"title":"UrlViabilityResult"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ViabilityRunPublic":{"properties":{"run_id":{"type":"string","title":"Run Id"},"status":{"type":"string","title":"Status"},"total_urls":{"type":"integer","title":"Total Urls"},"completed_urls":{"type":"integer","title":"Completed Urls","default":0},"results":{"anyOf":[{"items":{"$ref":"#/components/schemas/UrlViabilityResult"},"type":"array"},{"type":"null"}],"title":"Results"}},"type":"object","required":["run_id","status","total_urls"],"title":"ViabilityRunPublic"},"ViabilityTestRequest":{"properties":{"urls":{"items":{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},"type":"array","minItems":1,"title":"Urls"},"actions":{"anyOf":[{"items":{"oneOf":[{"$ref":"#/components/schemas/ClickAction"},{"$ref":"#/components/schemas/CollectAction"},{"$ref":"#/components/schemas/InputAction"},{"$ref":"#/components/schemas/KeyPressAction"},{"$ref":"#/components/schemas/SelectAction"},{"$ref":"#/components/schemas/WaitForSelectorAction"},{"$ref":"#/components/schemas/WaitForTimeoutAction"},{"$ref":"#/components/schemas/EvaluateAction"}],"discriminator":{"propertyName":"type","mapping":{"click":"#/components/schemas/ClickAction","collect":"#/components/schemas/CollectAction","evaluate":"#/components/schemas/EvaluateAction","input":"#/components/schemas/InputAction","key-press":"#/components/schemas/KeyPressAction","select":"#/components/schemas/SelectAction","wait-for-selector":"#/components/schemas/WaitForSelectorAction","wait-for-timeout":"#/components/schemas/WaitForTimeoutAction"}}},"type":"array"},{"type":"null"}],"title":"Actions"},"depth":{"type":"string","enum":["quick","standard","full"],"title":"Depth","description":"Analysis depth. 'quick': simple HTTP only (1 credit/url). 'standard': simple + proxy + browser (up to 7 credits/url). 'full': all modes including browser+proxy (up to 12 credits/url). Uses early exit: stops at the first mode that works.","default":"full"}},"type":"object","required":["urls"],"title":"ViabilityTestRequest"},"WaitForSelectorAction":{"properties":{"selector":{"type":"string","title":"Selector"},"type":{"type":"string","const":"wait-for-selector","title":"Type"},"time":{"type":"integer","title":"Time"}},"type":"object","required":["selector","type","time"],"title":"WaitForSelectorAction"},"WaitForTimeoutAction":{"properties":{"type":{"type":"string","const":"wait-for-timeout","title":"Type"},"time":{"type":"integer","title":"Time"}},"type":"object","required":["type","time"],"title":"WaitForTimeoutAction"},"While":{"properties":{"type":{"type":"string","const":"while","title":"Type"},"condition":{"oneOf":[{"$ref":"#/components/schemas/SelectorVisibleCondition"},{"$ref":"#/components/schemas/SelectorInvisibleCondition"}],"title":"Condition","discriminator":{"propertyName":"type","mapping":{"selector-invisible":"#/components/schemas/SelectorInvisibleCondition","selector-visible":"#/components/schemas/SelectorVisibleCondition"}}},"actions":{"items":{"oneOf":[{"$ref":"#/components/schemas/ClickAction"},{"$ref":"#/components/schemas/CollectAction"},{"$ref":"#/components/schemas/InputAction"},{"$ref":"#/components/schemas/KeyPressAction"},{"$ref":"#/components/schemas/SelectAction"},{"$ref":"#/components/schemas/WaitForSelectorAction"},{"$ref":"#/components/schemas/WaitForTimeoutAction"},{"$ref":"#/components/schemas/EvaluateAction"}],"discriminator":{"propertyName":"type","mapping":{"click":"#/components/schemas/ClickAction","collect":"#/components/schemas/CollectAction","evaluate":"#/components/schemas/EvaluateAction","input":"#/components/schemas/InputAction","key-press":"#/components/schemas/KeyPressAction","select":"#/components/schemas/SelectAction","wait-for-selector":"#/components/schemas/WaitForSelectorAction","wait-for-timeout":"#/components/schemas/WaitForTimeoutAction"}}},"type":"array","title":"Actions"},"max_iterations":{"type":"integer","minimum":1.0,"title":"Max Iterations","description":"Maximum number of loop iterations","default":20}},"type":"object","required":["type","condition","actions"],"title":"While","description":"Loop that performs multiple Actions on the page."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}