{"openapi":"3.1.0","info":{"title":"FineData API","description":"Web scraping API with antibot bypass, JavaScript rendering, CAPTCHA solving, and residential proxies.\n\n## Authentication\n\nAll requests require an API key passed in the `Authorization` header:\n\n```\nAuthorization: Bearer fd_your_api_key_here\n```\n\nGet your API key at [finedata.ai/dashboard](https://finedata.ai/dashboard) or via `POST /api/v1/api-keys`.\n\n## Quick Start\n\n```bash\ncurl -X POST \"https://api.finedata.ai/api/v1/scrape\" \\\n  -H \"Authorization: Bearer fd_your_api_key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\": \"https://example.com\"}'\n```\n\n## Token Pricing\n\nEvery request costs tokens. Base request = 1 token. Premium features add extra:\n\n| Feature | Cost |\n|---------|------|\n| Base request | 1 token |\n| TLS antibot (default) | +2 tokens |\n| JS rendering | +5 tokens |\n| Stealth antibot | +7 tokens |\n| Stealth headful | +25 tokens |\n| Residential proxy | +3 tokens |\n| Mobile proxy | +4 tokens |\n| BYOP (your proxies) | +1 token |\n| CAPTCHA solving | +10 tokens |\n| Auto-retry per attempt | +1 token |\n\n## Features\n\n- **Antibot Bypass** -- Cloudflare, DataDome, PerimeterX, and more\n- **JavaScript Rendering** -- Headless Chromium with Playwright\n- **CAPTCHA Solving** -- reCAPTCHA v2/v3, hCaptcha, Cloudflare Turnstile\n- **Residential Proxies** -- 87K+ IPs across 195 countries\n- **BYOP** -- Use your own HTTP/SOCKS5 proxies via saved profiles (`proxy_profile_id`)\n- **Sticky Sessions** -- Same IP for multi-page flows (auth, pagination)\n- **Async + Batch** -- Submit jobs, poll or receive webhooks\n- **MCP Support** -- Connect AI agents via Model Context Protocol\n","version":"1.0.0"},"paths":{"/api/v1/scrape":{"post":{"tags":["Web Scraping"],"summary":"Scrape URL","description":"Scrape a web page and return its HTML content.\n\nSend a URL and get back the rendered HTML, response headers, and metadata.\nSupports antibot bypass, JavaScript rendering, CAPTCHA solving, and residential proxies.\n\n**Minimal request:** `{\"url\": \"https://example.com\"}`","operationId":"scrape_endpoint_api_v1_scrape_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScrapeRequest"}}}},"responses":{"200":{"description":"JSON response (default) or raw content when raw_output=true","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicScrapeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/scrape":{"post":{"tags":["Async Scraping"],"summary":"Submit Async Job","description":"Submit a scrape job for background processing.\n\nReturns immediately with a `job_id`. Poll `GET /api/v1/async/jobs/{job_id}` for the result,\nor set `callback_url` to receive a webhook when the job finishes.","operationId":"create_async_job_api_v1_async_scrape_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncScrapeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/jobs/{job_id}":{"get":{"tags":["Async Scraping"],"summary":"Get Job Status","description":"Get the current status and result of an async job.\n\nStatuses: `pending` (queued), `processing` (running), `completed` (result available),\n`failed` (error available), `cancelled`.","operationId":"get_job_status_api_v1_async_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Async Scraping"],"summary":"Cancel Job","description":"Cancel a pending job. Only jobs with status `pending` can be cancelled.\nJobs already `processing` will complete normally.","operationId":"cancel_job_api_v1_async_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/jobs":{"get":{"tags":["Async Scraping"],"summary":"List Jobs","description":"List your async jobs, newest first. Supports pagination and status filtering.","operationId":"list_jobs_api_v1_async_jobs_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max jobs to return","default":50,"title":"Limit"},"description":"Max jobs to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status: pending, processing, completed, failed, cancelled","title":"Status"},"description":"Filter by status: pending, processing, completed, failed, cancelled"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/stats":{"get":{"tags":["Async Scraping"],"summary":"Get Job Stats","description":"Get aggregate job counts grouped by status (pending, processing, completed, failed, cancelled).","operationId":"get_job_stats_api_v1_async_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/batch":{"post":{"tags":["Async Scraping"],"summary":"Submit Batch","description":"Submit up to 100 URLs for parallel async scraping. Returns a `batch_id` to track progress.","operationId":"create_batch_job_api_v1_async_batch_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchScrapeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/async/batch/{batch_id}":{"get":{"tags":["Async Scraping"],"summary":"Get Batch Status","description":"Get batch progress. Pass `include_results=true` to get individual job results.\n\nStatuses: `pending`, `processing`, `completed`, `partial` (some failed), `failed` (all failed).","operationId":"get_batch_status_api_v1_async_batch__batch_id__get","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"include_results","in":"query","required":false,"schema":{"type":"boolean","description":"Include individual job results","default":false,"title":"Include Results"},"description":"Include individual job results"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchJobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys":{"post":{"tags":["API Keys"],"summary":"Create API Key","description":"Create a new API key. The raw key is returned only once -- save it securely.","operationId":"create_api_key_api_v1_api_keys_post","parameters":[{"name":"name","in":"query","required":false,"schema":{"type":"string","default":"New Key","title":"Name"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["API Keys"],"summary":"List API Keys","description":"List all API keys for the current user (key values are masked).","operationId":"list_api_keys_api_v1_api_keys_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/api-keys/{key_id}":{"delete":{"tags":["API Keys"],"summary":"Revoke API Key","description":"Permanently revoke an API key. This action cannot be undone.","operationId":"revoke_api_key_api_v1_api_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","title":"Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me":{"get":{"tags":["User"],"summary":"Get My Profile","description":"Return the authenticated user's ID, email, name, auth type, and plan.","operationId":"get_current_user_info_api_v1_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/usage":{"get":{"tags":["User"],"summary":"Get Usage & Balance","description":"Return current billing period token usage and balance for the authenticated user.","operationId":"get_usage_api_v1_usage_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/plans":{"get":{"tags":["Plans"],"summary":"List Plans","description":"List available subscription plans with pricing, token limits, and the user's current plan.","operationId":"get_plans_api_v1_plans_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proxy-profiles":{"post":{"tags":["Proxy Profiles (BYOP)"],"summary":"Create Profile","description":"Create an encrypted BYOP profile. Requires team_s+ plan. Up to 10 profiles and 100 proxies per profile.","operationId":"create_profile_api_v1_proxy_profiles_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Proxy Profiles (BYOP)"],"summary":"List Profiles","description":"List BYOP profiles for the authenticated user. Credentials are never returned.","operationId":"list_profiles_api_v1_proxy_profiles_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proxy-profiles/{profile_id}":{"get":{"tags":["Proxy Profiles (BYOP)"],"summary":"Get Profile","description":"Get profile metadata by id (no decrypted proxy URLs).","operationId":"get_profile_api_v1_proxy_profiles__profile_id__get","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"integer","title":"Profile Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Proxy Profiles (BYOP)"],"summary":"Update Profile","description":"Update name, proxy list, rotation mode, or auto_skip_failed.","operationId":"update_profile_api_v1_proxy_profiles__profile_id__put","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"integer","title":"Profile Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Proxy Profiles (BYOP)"],"summary":"Delete Profile","description":"Permanently delete a BYOP profile.","operationId":"delete_profile_api_v1_proxy_profiles__profile_id__delete","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"integer","title":"Profile Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/proxy-profiles/{profile_id}/test":{"post":{"tags":["Proxy Profiles (BYOP)"],"summary":"Test Profile","description":"Health-check each proxy in the profile via https://httpbin.org/ip. Returns masked URLs and per-proxy latency.","operationId":"test_profile_api_v1_proxy_profiles__profile_id__test_post","parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"integer","title":"Profile Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProxyTestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/serp":{"post":{"tags":["Google SERP"],"summary":"Google search (SERP)","description":"Run a Google search and return structured JSON results.\n\nSame auth and billing gates as ``POST /api/v1/scrape``. Charged only when a\npage is actually parsed; a Google block or a run with no results is free.","operationId":"serp_endpoint_api_v1_serp_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SerpRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/user/stats":{"get":{"tags":["User Statistics"],"summary":"Get User Stats","operationId":"get_user_stats_api_v1_user_stats_get","parameters":[{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date (YYYY-MM-DD). Defaults to 30 days ago.","title":"Date From"},"description":"Start date (YYYY-MM-DD). Defaults to 30 days ago."},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date (YYYY-MM-DD). Defaults to today.","title":"Date To"},"description":"End date (YYYY-MM-DD). Defaults to today."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["OAuth"],"summary":"Authorization Server Metadata","operationId":"authorization_server_metadata__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/jwks.json":{"get":{"tags":["OAuth"],"summary":"Jwks","operationId":"jwks__well_known_jwks_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/oauth/register":{"post":{"tags":["OAuth"],"summary":"Register Client","operationId":"register_client_oauth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRegistrationRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/authorize":{"get":{"tags":["OAuth"],"summary":"Authorize","operationId":"authorize_oauth_authorize_get","parameters":[{"name":"response_type","in":"query","required":true,"schema":{"type":"string","title":"Response Type"}},{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"scrape:write jobs:read usage:read","title":"Scope"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string","default":"S256","title":"Code Challenge Method"}},{"name":"resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/consent/approve":{"post":{"tags":["OAuth"],"summary":"Consent Approve","description":"Logged-in user approves MCP client access; returns redirect URL with code.","operationId":"consent_approve_oauth_consent_approve_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentApproveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/token":{"post":{"tags":["OAuth"],"summary":"Token","operationId":"token_oauth_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_oauth_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/revoke":{"post":{"tags":["OAuth"],"summary":"Revoke Token","description":"RFC 7009 revocation for refresh tokens.\n\nThe metadata already advertised revocation auth methods while no endpoint\nexisted, so a client that wanted to hand access back had nowhere to go.\nAlways answers 200: per RFC 7009 an unknown token is not an error, and\nsaying which tokens exist would turn this into an oracle.","operationId":"revoke_token_oauth_revoke_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_revoke_token_oauth_revoke_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AsyncJobListResponse":{"properties":{"jobs":{"items":{},"type":"array","title":"Jobs"},"total":{"type":"integer","title":"Total","description":"Total number of jobs"},"limit":{"type":"integer","title":"Limit","description":"Page size"},"offset":{"type":"integer","title":"Offset","description":"Current offset"}},"type":"object","required":["jobs","total","limit","offset"],"title":"AsyncJobListResponse","description":"Paginated list of async jobs."},"AsyncJobResponse":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Unique job identifier (UUID)"},"status":{"type":"string","title":"Status","description":"Initial job status (always 'pending')"},"url":{"type":"string","title":"Url","description":"Target URL submitted"},"created_at":{"type":"string","title":"Created At","description":"ISO 8601 creation timestamp"},"estimated_completion":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Estimated Completion","description":"Estimated completion time (ISO 8601)"}},"type":"object","required":["job_id","status","url","created_at"],"title":"AsyncJobResponse","description":"Returned when an async job is created.","example":{"created_at":"2026-02-07T12:00:00Z","estimated_completion":"2026-02-07T12:00:30Z","job_id":"550e8400-e29b-41d4-a716-446655440000","status":"pending","url":"https://example.com"}},"AsyncJobStatsResponse":{"properties":{"total":{"type":"integer","title":"Total","description":"Total jobs"},"pending":{"type":"integer","title":"Pending","description":"Jobs waiting in queue"},"processing":{"type":"integer","title":"Processing","description":"Jobs currently running"},"completed":{"type":"integer","title":"Completed","description":"Successfully completed jobs"},"failed":{"type":"integer","title":"Failed","description":"Failed jobs"},"cancelled":{"type":"integer","title":"Cancelled","description":"Cancelled jobs"}},"type":"object","required":["total","pending","processing","completed","failed","cancelled"],"title":"AsyncJobStatsResponse","description":"Aggregate job counts by status."},"AsyncJobStatusResponse":{"properties":{"job_id":{"type":"string","title":"Job Id","description":"Job identifier"},"status":{"type":"string","title":"Status","description":"Current status: pending, processing, completed, failed, cancelled"},"url":{"type":"string","title":"Url","description":"Target URL"},"method":{"type":"string","title":"Method","description":"HTTP method used","default":"GET"},"created_at":{"type":"string","title":"Created At","description":"Creation timestamp"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At","description":"Processing start timestamp"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At","description":"Completion timestamp"},"use_js_render":{"type":"boolean","title":"Use Js Render","description":"JS rendering was enabled","default":false},"use_residential":{"type":"boolean","title":"Use Residential","description":"Residential proxy was used","default":false},"use_isp":{"type":"boolean","title":"Use Isp","description":"ISP proxy was used","default":false},"use_mobile":{"type":"boolean","title":"Use Mobile","description":"Mobile proxy was used","default":false},"proxy_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proxy Country","description":"Requested proxy country (ISO-2), if any"},"stealth_antibot":{"type":"boolean","title":"Stealth Antibot","description":"Stealth antibot was used","default":false},"stealth_antibot_headful":{"type":"boolean","title":"Stealth Antibot Headful","description":"Headful stealth was used","default":false},"stealth_new":{"type":"boolean","title":"Stealth New","description":"New stealth engine was used","default":false},"stealth_premium":{"type":"boolean","title":"Stealth Premium","description":"Premium stealth engine was used","default":false},"stealth_premium_headful":{"type":"boolean","title":"Stealth Premium Headful","description":"Premium stealth headful was used","default":false},"result":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Result","description":"Scrape result (only when status=completed)"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message (only when status=failed)"},"attempts":{"type":"integer","title":"Attempts","description":"Number of attempts made","default":0},"tokens_used":{"type":"integer","title":"Tokens Used","description":"Total tokens consumed","default":0}},"type":"object","required":["job_id","status","url","created_at"],"title":"AsyncJobStatusResponse","description":"Full job status, including result when completed."},"AsyncScrapeRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Target URL to scrape"},"method":{"type":"string","title":"Method","description":"HTTP method (GET, POST, PUT, DELETE)","default":"GET"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Custom HTTP headers"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body","description":"Request body (for POST/PUT)"},"tls_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tls Profile","description":"TLS fingerprint profile: chrome145, chrome136, firefox147, safari26_0, smart, vip","default":"chrome136"},"max_retries":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Max Retries","description":"Max retry attempts","default":5},"timeout":{"anyOf":[{"type":"integer","maximum":300.0,"minimum":5.0},{"type":"null"}],"title":"Timeout","description":"Timeout in seconds (max 300 for captcha)","default":120},"use_antibot":{"type":"boolean","title":"Use Antibot","description":"Browser-like TLS fingerprint (+2 tokens)","default":true},"use_js_render":{"type":"boolean","title":"Use Js Render","description":"Render JavaScript with headless browser (+5 tokens)","default":false},"use_residential":{"type":"boolean","title":"Use Residential","description":"Residential proxy (+3 tokens)","default":false},"use_isp":{"type":"boolean","title":"Use Isp","description":"ISP proxy (+2 tokens)","default":false},"use_mobile":{"type":"boolean","title":"Use Mobile","description":"Mobile carrier proxy (+4 tokens)","default":false},"proxy_sticky":{"type":"boolean","title":"Proxy Sticky","description":"Keep the same proxy exit IP across requests in this job. Works with residential and BYOP sticky profiles.","default":false},"proxy_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proxy Country","description":"Request a proxy exit IP from a specific country (ISO-2 code, e.g. 'US', 'DE'). Applies to datacenter, residential, ISP and mobile proxies. Mutually exclusive with proxy_profile_id (BYOP)."},"proxy_profile_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Proxy Profile Id","description":"Use your own proxy list via a saved BYOP profile id. Mutually exclusive with use_residential/use_isp/use_mobile. Charges flat +1 token. Requires team_s plan or admin override."},"stealth_antibot":{"type":"boolean","title":"Stealth Antibot","description":"Stronger browser emulation for pages a plain request cannot load (+7 tokens)","default":false},"stealth_antibot_headful":{"type":"boolean","title":"Stealth Antibot Headful","description":"Full real browser with a visible display (+25 tokens)","default":false},"stealth_new":{"type":"boolean","title":"Stealth New","description":"Experimental next-gen engine (+15 tokens)","default":false},"stealth_premium":{"type":"boolean","title":"Stealth Premium","description":"Premium stealth engine (+20 tokens)","default":false},"stealth_premium_headful":{"type":"boolean","title":"Stealth Premium Headful","description":"Premium stealth headful mode (+30 tokens)","default":false},"js_wait_for":{"type":"string","title":"Js Wait For","description":"Page load strategy: networkidle, load, domcontentloaded, or selector:.css","default":"networkidle"},"js_scroll":{"type":"boolean","title":"Js Scroll","description":"Scroll to load lazy content","default":false},"js_actions":{"anyOf":[{"items":{"$ref":"#/components/schemas/JsAction"},"type":"array","maxItems":10},{"type":"null"}],"title":"Js Actions","description":"Browser actions before extraction: click, wait, type, scroll, hover, evaluate (+2 tokens each, max 10)"},"solve_captcha":{"type":"boolean","title":"Solve Captcha","description":"Auto-solve captchas: reCAPTCHA, hCaptcha, Turnstile (+10 tokens)","default":false},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Sticky session ID for same proxy IP across requests"},"session_ttl":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":60.0},{"type":"null"}],"title":"Session Ttl","description":"Session lifetime in seconds (default 1800)","default":1800},"formats":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Formats","description":"Output formats to include in response. Options: 'markdown', 'rawHtml', 'text', 'links', 'screenshot'. If not specified, only 'body' (raw HTML) is returned for backward compatibility. Example: ['markdown', 'links']"},"only_main_content":{"type":"boolean","title":"Only Main Content","description":"Extract only the main content of the page (removes navigation, footer, sidebar, ads). Applies to 'markdown' and 'text' formats. Uses Mozilla Readability algorithm","default":false},"extract_rules":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extract Rules","description":"CSS/XPath selectors for structured data extraction. Simple: {'title': 'h1', 'price': '.price'}. Advanced: {'links': {'selector': 'a.product', 'type': 'list', 'output': '@href'}}. Supported types: text (default), html, list. Output: text content or @attr"},"extract_schema":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extract Schema","description":"JSON Schema for AI-powered structured data extraction. The AI model analyzes page content and returns data matching your schema. Example: {'type': 'object', 'properties': {'products': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'price': {'type': 'number'}}}}}} (+5 tokens)"},"extract_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract Prompt","description":"Natural language instruction for AI-powered data extraction. Alternative to extract_schema. Example: 'Extract all product names, prices, and ratings from this page' (+5 tokens)"},"ai_content_mode":{"anyOf":[{"type":"string","enum":["full","main"]},{"type":"null"}],"title":"Ai Content Mode","description":"Content mode for AI extraction (extract_schema/extract_prompt). 'full' — AI sees full page content including sidebars, structured data blocks (best for product pages, real estate listings, marketplaces). 'main' — AI sees only main content extracted via Readability algorithm (best for articles, blog posts — fewer tokens, less noise). Default: 'full'","default":"full"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url","description":"Webhook URL to receive the result when job completes"},"callback_headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Callback Headers","description":"Custom headers sent with the webhook POST"}},"type":"object","required":["url"],"title":"AsyncScrapeRequest","description":"Async scrape request. Same options as sync scrape, plus webhook callback.","examples":[{"callback_url":"https://your-server.com/webhook","url":"https://example.com","use_js_render":true},{"solve_captcha":true,"stealth_antibot":true,"timeout":300,"url":"https://heavy-site.com"}]},"BatchJobResponse":{"properties":{"batch_id":{"type":"string","title":"Batch Id","description":"Unique batch identifier"},"job_ids":{"items":{},"type":"array","title":"Job Ids","description":"List of individual job IDs"},"total_jobs":{"type":"integer","title":"Total Jobs","description":"Number of jobs in the batch"},"status":{"type":"string","title":"Status","description":"Batch status (initially 'pending')"},"created_at":{"type":"string","title":"Created At","description":"Creation timestamp"}},"type":"object","required":["batch_id","job_ids","total_jobs","status","created_at"],"title":"BatchJobResponse","description":"Returned when a batch is created."},"BatchJobStatusResponse":{"properties":{"batch_id":{"type":"string","title":"Batch Id","description":"Batch identifier"},"status":{"type":"string","title":"Status","description":"Overall status: pending, processing, completed, partial, failed"},"total_jobs":{"type":"integer","title":"Total Jobs","description":"Total jobs in batch"},"completed_jobs":{"type":"integer","title":"Completed Jobs","description":"Successfully completed jobs"},"failed_jobs":{"type":"integer","title":"Failed Jobs","description":"Failed jobs"},"created_at":{"type":"string","title":"Created At","description":"Creation timestamp"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At","description":"Completion timestamp (all jobs done)"},"results":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Results","description":"Individual job results (when include_results=true)"}},"type":"object","required":["batch_id","status","total_jobs","completed_jobs","failed_jobs","created_at"],"title":"BatchJobStatusResponse","description":"Batch progress and results."},"BatchScrapeRequest":{"properties":{"requests":{"items":{},"type":"array","maxItems":100,"minItems":1,"title":"Requests","description":"Array of scrape requests. Each item supports the same fields as AsyncScrapeRequest (without callback_url)"},"callback_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callback Url","description":"Webhook URL called when all jobs in the batch complete"}},"type":"object","required":["requests"],"title":"BatchScrapeRequest","description":"Submit multiple URLs for async scraping in a single request.","example":{"callback_url":"https://your-server.com/batch-webhook","requests":[{"url":"https://example.com/page1"},{"url":"https://example.com/page2","use_js_render":true},{"body":"{}","method":"POST","url":"https://api.example.com/data"}]}},"Body_revoke_token_oauth_revoke_post":{"properties":{"token":{"type":"string","title":"Token"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"}},"type":"object","required":["token"],"title":"Body_revoke_token_oauth_revoke_post"},"Body_token_oauth_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"redirect_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Redirect Uri"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"},"code_verifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Verifier"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"},"resource":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}},"type":"object","required":["grant_type"],"title":"Body_token_oauth_token_post"},"ClientRegistrationRequest":{"properties":{"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"redirect_uris":{"items":{"type":"string"},"type":"array","title":"Redirect Uris"},"grant_types":{"items":{"type":"string"},"type":"array","title":"Grant Types"},"token_endpoint_auth_method":{"type":"string","title":"Token Endpoint Auth Method","default":"none"},"scope":{"type":"string","title":"Scope","default":"scrape:write jobs:read usage:read"}},"type":"object","title":"ClientRegistrationRequest"},"ConsentApproveRequest":{"properties":{"client_id":{"type":"string","title":"Client Id"},"redirect_uri":{"type":"string","title":"Redirect Uri"},"scope":{"type":"string","title":"Scope","default":"scrape:write jobs:read usage:read"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"code_challenge":{"type":"string","title":"Code Challenge"},"code_challenge_method":{"type":"string","title":"Code Challenge Method","default":"S256"}},"type":"object","required":["client_id","redirect_uri","code_challenge"],"title":"ConsentApproveRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JsAction":{"properties":{"action":{"type":"string","enum":["click","wait","wait_for","scroll","type","hover","screenshot","evaluate"],"title":"Action","description":"Action type: click, wait, wait_for, scroll, type, hover, screenshot, evaluate"},"selector":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Selector","description":"CSS selector for the target element"},"ms":{"anyOf":[{"type":"integer","maximum":30000.0,"minimum":100.0},{"type":"null"}],"title":"Ms","description":"Wait time in milliseconds (for 'wait' action). Accepts both 'ms' and 'value' keys"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Text to type (for 'type' action)"},"timeout":{"anyOf":[{"type":"integer","maximum":30000.0,"minimum":1000.0},{"type":"null"}],"title":"Timeout","description":"Timeout for wait_for in ms","default":10000},"y":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Y","description":"Y position for scroll (if no selector)"},"script":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}],"title":"Script","description":"JavaScript code to execute on the page (for 'evaluate' action). Runs in the page context with a 15s timeout. Max 10,000 characters"}},"type":"object","required":["action"],"title":"JsAction","description":"JavaScript action to perform on page"},"ProxyProfileCreateRequest":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name"},"proxies":{"items":{"type":"string"},"type":"array","maxItems":100,"minItems":1,"title":"Proxies"},"rotation_mode":{"type":"string","enum":["round_robin","sticky"],"title":"Rotation Mode","default":"round_robin"},"auto_skip_failed":{"type":"boolean","title":"Auto Skip Failed","default":true}},"type":"object","required":["name","proxies"],"title":"ProxyProfileCreateRequest","example":{"auto_skip_failed":true,"name":"My residential pool","proxies":["http://user:pass@proxy1.example.com:8080","socks5://user:pass@proxy2.example.com:1080"],"rotation_mode":"round_robin"}},"ProxyProfileListResponse":{"properties":{"profiles":{"items":{"$ref":"#/components/schemas/ProxyProfileResponse"},"type":"array","title":"Profiles"},"total":{"type":"integer","title":"Total"},"max_profiles":{"type":"integer","title":"Max Profiles"}},"type":"object","required":["profiles","total","max_profiles"],"title":"ProxyProfileListResponse"},"ProxyProfileResponse":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"proxy_count":{"type":"integer","title":"Proxy Count"},"rotation_mode":{"type":"string","title":"Rotation Mode"},"auto_skip_failed":{"type":"boolean","title":"Auto Skip Failed"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","name","proxy_count","rotation_mode","auto_skip_failed"],"title":"ProxyProfileResponse"},"ProxyProfileUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Name"},"proxies":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"Proxies"},"rotation_mode":{"anyOf":[{"type":"string","enum":["round_robin","sticky"]},{"type":"null"}],"title":"Rotation Mode"},"auto_skip_failed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Skip Failed"}},"type":"object","title":"ProxyProfileUpdateRequest"},"ProxyTestResponse":{"properties":{"profile_id":{"type":"integer","title":"Profile Id"},"tested":{"type":"integer","title":"Tested"},"succeeded":{"type":"integer","title":"Succeeded"},"failed":{"type":"integer","title":"Failed"},"results":{"items":{"$ref":"#/components/schemas/ProxyTestResult"},"type":"array","title":"Results"}},"type":"object","required":["profile_id","tested","succeeded","failed","results"],"title":"ProxyTestResponse"},"ProxyTestResult":{"properties":{"index":{"type":"integer","title":"Index"},"proxy":{"type":"string","title":"Proxy"},"ok":{"type":"boolean","title":"Ok"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["index","proxy","ok"],"title":"ProxyTestResult"},"PublicScrapeRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Target URL to scrape"},"method":{"type":"string","title":"Method","description":"HTTP method (GET, POST, PUT, DELETE)","default":"GET"},"headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Headers","description":"Custom HTTP headers to send with the request"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body","description":"Request body (for POST/PUT requests)"},"timeout":{"anyOf":[{"type":"integer","maximum":300.0,"minimum":5.0},{"type":"null"}],"title":"Timeout","description":"Request timeout in seconds. Increase for captcha solving (max 300)","default":120},"max_retries":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Max Retries","description":"Max automatic retry attempts on failure","default":5},"auto_retry":{"type":"boolean","title":"Auto Retry","description":"Automatically retry on failure (+1 token per retry)","default":true},"use_antibot":{"type":"boolean","title":"Use Antibot","description":"Browser-like TLS fingerprint (+2 tokens). Enabled by default","default":true},"tls_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tls Profile","description":"TLS fingerprint profile: chrome136, chrome131, chrome124, firefox133, safari184, safari18_0, or 'vip' for premium rotation (vip:ios, vip:android, vip:windows, vip:mobile)","default":"chrome136"},"use_residential":{"type":"boolean","title":"Use Residential","description":"Route through residential proxy instead of datacenter (+3 tokens)","default":false},"use_isp":{"type":"boolean","title":"Use Isp","description":"Route through ISP proxy for clean IP reputation (+2 tokens)","default":false},"use_mobile":{"type":"boolean","title":"Use Mobile","description":"Route through mobile carrier proxy for maximum anonymity (+4 tokens)","default":false},"proxy_sticky":{"type":"boolean","title":"Proxy Sticky","description":"Keep the same proxy exit IP for the entire browser session. Required when a warmup request and the follow-up fetch must come from one IP, e.g. a site that ties a session cookie to the address that obtained it. Works with residential proxies and BYOP profiles (rotation_mode=sticky).","default":false},"proxy_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proxy Country","description":"Request a proxy exit IP from a specific country (ISO-2 code, e.g. 'US', 'DE'). Applies to datacenter, residential, ISP and mobile proxies. Returns 422 if the country isn't currently supported for the resolved proxy type. Mutually exclusive with proxy_profile_id (BYOP)."},"proxy_profile_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Proxy Profile Id","description":"Use your own proxy list via a saved BYOP profile id (Bring Your Own Proxy). Mutually exclusive with use_residential / use_isp / use_mobile. Charges flat +1 token instead of the vendor surcharge. Requires team_s plan or admin override."},"stealth_antibot":{"type":"boolean","title":"Stealth Antibot","description":"Stronger browser emulation for pages that a plain request cannot load (+7 tokens)","default":false},"stealth_antibot_headful":{"type":"boolean","title":"Stealth Antibot Headful","description":"Full real browser with a visible display, for pages the headless engine cannot load (+25 tokens)","default":false},"stealth_new":{"type":"boolean","title":"Stealth New","description":"Experimental next-generation stealth engine (+15 tokens)","default":false},"stealth_premium":{"type":"boolean","title":"Stealth Premium","description":"Premium stealth engine with full fingerprint emulation (+20 tokens)","default":false},"stealth_premium_headful":{"type":"boolean","title":"Stealth Premium Headful","description":"Premium stealth engine in headful mode with GPU rendering (+30 tokens)","default":false},"use_js_render":{"type":"boolean","title":"Use Js Render","description":"Render JavaScript with headless browser. Required for SPAs (+5 tokens)","default":false},"js_wait_for":{"type":"string","title":"Js Wait For","description":"Page load strategy: 'networkidle', 'load', 'domcontentloaded', or 'selector:.css-selector'","default":"networkidle"},"js_scroll":{"type":"boolean","title":"Js Scroll","description":"Scroll to bottom to trigger lazy-loaded content","default":false},"js_actions":{"anyOf":[{"items":{"$ref":"#/components/schemas/JsAction"},"type":"array","maxItems":10},{"type":"null"}],"title":"Js Actions","description":"Sequence of browser actions before extracting HTML: click, wait, type, scroll, hover, evaluate (+2 tokens each, max 10)"},"solve_captcha":{"type":"boolean","title":"Solve Captcha","description":"Auto-detect and solve captchas: reCAPTCHA, hCaptcha, Turnstile (+10 tokens)","default":false},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Sticky session ID. All requests with the same ID share the same proxy IP. Max 64 chars"},"session_ttl":{"anyOf":[{"type":"integer","maximum":86400.0,"minimum":60.0},{"type":"null"}],"title":"Session Ttl","description":"Session lifetime in seconds (default: 1800 = 30 min, max: 86400 = 24h)","default":1800},"formats":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Formats","description":"Output formats to include in response. Options: 'markdown', 'rawHtml', 'text', 'links', 'screenshot', 'csv', 'xlsx'. csv/xlsx export AI extraction results as tabular data (requires extract_prompt or extract_schema). If not specified, only 'body' (raw HTML) is returned for backward compatibility. Example: ['markdown', 'links']"},"only_main_content":{"type":"boolean","title":"Only Main Content","description":"Extract only the main content of the page (removes navigation, footer, sidebar, ads). Applies to 'markdown' and 'text' formats. Uses Mozilla Readability algorithm","default":false},"raw_output":{"type":"boolean","title":"Raw Output","description":"Return clean content directly instead of JSON wrapper. Requires exactly one format in 'formats' (e.g. formats=['markdown']). Response Content-Type matches the format: text/markdown, text/plain, text/html, image/png, text/csv, application/xlsx. Metadata is returned in response headers: X-Tokens-Used, X-Request-Id, X-Status-Code. Without 'formats', returns raw HTML as text/html.","default":false},"extract_rules":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extract Rules","description":"CSS/XPath selectors for structured data extraction. Simple: {'title': 'h1', 'price': '.price'}. Advanced: {'links': {'selector': 'a.product', 'type': 'list', 'output': '@href'}}. Supported types: text (default), html, list. Output: text content or @attr"},"extract_schema":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extract Schema","description":"JSON Schema for AI-powered structured data extraction. The AI model analyzes page content and returns data matching your schema. Example: {'type': 'object', 'properties': {'products': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'price': {'type': 'number'}}}}}} (+5 tokens)"},"extract_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extract Prompt","description":"Natural language instruction for AI-powered data extraction. Alternative to extract_schema. Example: 'Extract all product names, prices, and ratings from this page' (+5 tokens)"},"ai_content_mode":{"anyOf":[{"type":"string","enum":["full","main"]},{"type":"null"}],"title":"Ai Content Mode","description":"Content mode for AI extraction (extract_schema/extract_prompt). 'full' — AI sees full page content including sidebars, structured data blocks (best for product pages, real estate listings, marketplaces). 'main' — AI sees only main content extracted via Readability algorithm (best for articles, blog posts — fewer tokens, less noise). Default: 'full'","default":"full"}},"type":"object","required":["url"],"title":"PublicScrapeRequest","description":"Scrape request parameters.","examples":[{"url":"https://example.com"},{"js_wait_for":"networkidle","url":"https://spa-site.com","use_js_render":true},{"stealth_antibot":true,"url":"https://protected-site.com","use_residential":true},{"session_id":"my-session-123","session_ttl":300,"url":"https://example.com/page1"}]},"PublicScrapeResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether the request completed successfully"},"status_code":{"type":"integer","title":"Status Code","description":"HTTP status code of the target page"},"headers":{"type":"object","title":"Headers","description":"Response headers from the target page"},"body":{"type":"string","title":"Body","description":"Raw HTML or text content of the page (kept for backward compatibility)"},"data":{"anyOf":[{"$ref":"#/components/schemas/ScrapeData"},{"type":"null"}],"description":"Structured output based on requested 'formats'. Contains markdown, text, links, etc."},"meta":{"type":"object","title":"Meta","description":"Request metadata: url, resolved_url, elapsed_ms, proxy_country"},"tokens_used":{"type":"integer","title":"Tokens Used","description":"Total tokens consumed for this request","default":1},"captcha_detected":{"type":"boolean","title":"Captcha Detected","description":"Whether a captcha was detected on the page","default":false},"captcha_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captcha Type","description":"Captcha type if detected: recaptcha_v2, recaptcha_v3, hcaptcha, turnstile"},"captcha_solved":{"type":"boolean","title":"Captcha Solved","description":"Whether the captcha was solved successfully","default":false}},"type":"object","required":["success","status_code","headers","body"],"title":"PublicScrapeResponse","description":"Scrape result.","example":{"body":"<!DOCTYPE html><html>...</html>","captcha_detected":false,"captcha_solved":false,"data":{"markdown":"# Example Page\n\nThis is the page content...","metadata":{"description":"An example page","title":"Example"}},"headers":{"content-type":"text/html; charset=utf-8"},"meta":{"elapsed_ms":1250,"resolved_url":"https://example.com/","url":"https://example.com"},"status_code":200,"success":true,"tokens_used":3}},"ScrapeData":{"properties":{"markdown":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Markdown","description":"Page content converted to Markdown format. Clean, LLM-friendly output"},"raw_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Html","description":"Original HTML content of the page"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"Plain text content extracted from the page"},"links":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Links","description":"All links (URLs) found on the page"},"screenshot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot","description":"Base64-encoded PNG screenshot of the page (requires JS rendering)"},"extract":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Extract","description":"Structured data extracted via extract_rules, extract_schema, or extract_prompt"},"metadata":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Metadata","description":"Page metadata: title, description, language, og:image, favicon, etc."},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type","description":"Original Content-Type of the response (useful for binary data detection)"},"csv":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Csv","description":"AI extraction results as CSV string (when 'csv' format requested)"},"xlsx":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Xlsx","description":"AI extraction results as base64-encoded XLSX (when 'xlsx' format requested)"}},"type":"object","title":"ScrapeData","description":"Structured scrape output. Fields are populated based on the requested 'formats'."},"SerpRequest":{"properties":{"q":{"type":"string","maxLength":2048,"minLength":1,"title":"Q","description":"Search query (1-2048 chars)"},"gl":{"type":"string","title":"Gl","description":"Google country: ISO 3166-1 alpha-2 (e.g. 'us')","default":"us"},"hl":{"type":"string","title":"Hl","description":"Google interface language: ISO 639-1, optional region (e.g. 'en' or 'en-GB')","default":"en"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location","description":"Accepted but unused in P1 (only gl/hl apply)"},"start":{"type":"integer","maximum":90.0,"minimum":0.0,"title":"Start","description":"Result offset; 0-90 in steps of 10 (10 results per page)","default":0},"device":{"type":"string","title":"Device","description":"Only 'desktop' is supported in P1","default":"desktop"},"include_html":{"type":"boolean","title":"Include Html","description":"Also return the raw Google HTML","default":false}},"type":"object","required":["q"],"title":"SerpRequest","description":"Google search request. The Google URL is built here, never sent by the client."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key obtained from the dashboard. Pass as `Authorization: Bearer fd_...`"}}},"tags":[{"name":"Web Scraping","description":"Core endpoint. Scrape any URL with antibot bypass, JS rendering, and proxy rotation."},{"name":"Async Scraping","description":"Submit long-running scrape jobs and retrieve results later. Supports webhooks and batch processing."},{"name":"API Keys","description":"Create and manage API keys for programmatic access."},{"name":"User","description":"Current user profile and account information."},{"name":"Plans","description":"Available subscription plans and pricing."},{"name":"Proxy Profiles (BYOP)","description":"Bring Your Own Proxy — save encrypted proxy lists and reference them by `proxy_profile_id` in scrape requests.\n\n**Requirements:** `team_s` plan or higher (or admin `allow_byop` override).\n\n**Pricing:** +1 token per request (stacks on top of antibot/render fees; replaces vendor proxy surcharges +2/+3/+4).\n\n**Limits:** up to 10 profiles per user, 100 proxies per profile. Credentials are Fernet-encrypted at rest; list endpoints never return decrypted URLs.\n\n**Rotation:** `round_robin` (default) or `sticky` (same exit IP per `session_id`). Failed proxies can be auto-skipped for 5 minutes when `auto_skip_failed` is enabled.\n\nManage profiles in the dashboard at `/proxy-profiles` or via the endpoints below."},{"name":"MCP Integration","description":"Connect AI agents (Cursor, Claude Desktop, Windsurf) to FineData using the Model Context Protocol.\n\n## Cursor IDE\n\nAdd to `~/.cursor/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"finedata\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@finedata/mcp-server\"],\n      \"env\": { \"FINEDATA_API_KEY\": \"fd_your_key\" }\n    }\n  }\n}\n```\n\n## Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"finedata\": {\n      \"command\": \"uvx\",\n      \"args\": [\"finedata-mcp\"],\n      \"env\": { \"FINEDATA_API_KEY\": \"fd_your_key\" }\n    }\n  }\n}\n```\n\n## Available MCP Tools\n\n- **scrape_url** -- Sync scraping with antibot, JS render, captcha\n- **scrape_async** -- Async scraping, returns job_id\n- **get_job_status** -- Check async job status\n- **batch_scrape** -- Batch scrape up to 100 URLs\n- **get_usage** -- Current token usage\n\n## Links\n\n- [PyPI: finedata-mcp](https://pypi.org/project/finedata-mcp/)\n- [NPM: @finedata/mcp-server](https://www.npmjs.com/package/@finedata/mcp-server)\n- [GitHub: quality-network/finedata-mcp](https://github.com/quality-network/finedata-mcp)\n"}],"security":[{"BearerAuth":[]}]}