Captcha solving service blog | SolveCaptcha How to bypass any rotate slider captcha with Python

How to bypass rotate slider captcha with Python

Rotate slider captcha asks the user to rotate an image or fragment until it reaches the correct orientation. It is commonly implemented as a circular image, puzzle fragment, or slider-controlled object that must be aligned with a reference image. For browser automation and data collection, manually solving every rotation challenge can interrupt the entire workflow. A more practical approach is to extract the rotatable image, send it to the [SolveCaptcha API](/captcha-solver-api), receive the required rotation angle, and reproduce the movement with Selenium, Playwright, Puppeteer, or another browser automation framework. This guide explains how to: - identify a rotate slider captcha; - extract the original captcha image; - submit it to SolveCaptcha; - poll the API for the result; - interpret positive and negative rotation values; - convert the returned angle into slider movement; - apply the result with Selenium; - handle retries, expired challenges, and API errors. Use this method only on websites you own or are authorized to test and automate. ## What is a rotate slider captcha? A rotate slider captcha is an image-based verification challenge where the user must rotate an object into the correct position. Common implementations include: - rotating an image until it becomes upright; - aligning an inner circular fragment with an outer image; - matching the orientation of two image layers; - rotating a puzzle fragment to fit a target area; - dragging a slider that controls an image’s rotation angle. The page may display a slider below the image. Moving the slider changes the CSS transform, canvas rendering, or server-generated rotation value. A simplified implementation may use: ```css transform: rotate(120deg); ``` More advanced widgets may also validate: - the final rotation angle; - movement duration; - intermediate slider positions; - mouse or touch events; - cookies and browser state; - challenge identifiers; - session-specific verification parameters. The browser automation framework handles the user interaction. SolveCaptcha determines how far the image must be rotated. ## Rotate captcha and rotate slider captcha differences The terms are often used interchangeably, but the browser interaction can differ. ### Rotate captcha The user clicks buttons to rotate an image in fixed increments. For example: ```text 40 degrees clockwise per click ``` A returned result of: ```text 120 ``` means the script should rotate the image three times: ```text 120 / 40 = 3 clicks ``` ### Rotate slider captcha The user drags a slider that changes the angle continuously or in small increments. For example: ```text Slider travel: 280 pixels Rotation range: 360 degrees Required angle: 180 degrees ``` The required slider movement is: ```text 280 × 180 / 360 = 140 pixels ``` The SolveCaptcha result provides the rotation angle. Your browser automation code must convert that angle into the interaction expected by the target widget. ## How SolveCaptcha rotate captcha solving works The standard workflow contains four stages: 1. Extract the image that must be rotated. 2. Submit the image to SolveCaptcha. 3. Poll the API until the answer is ready. 4. Rotate the image or move the slider according to the returned angle. The task is submitted to: ```text POST https://api.solvecaptcha.com/in.php ``` The result is retrieved from: ```text GET https://api.solvecaptcha.com/res.php ``` The required API method is: ```text rotatecaptcha ``` SolveCaptcha accepts the image as either: - a multipart file; - a base64-encoded image in the `body` parameter. For browser automation, base64 is usually more convenient because images extracted from a canvas, screenshot, or network response can be sent without first saving them permanently. ## SolveCaptcha request parameters A base64 request uses the following fields: ```text key=YOUR_API_KEY method=rotatecaptcha body=BASE64_IMAGE angle=40 json=1 ``` Parameters: | Parameter | Required | Description | |---|---:|---| | `key` | Yes | Your SolveCaptcha API key | | `method` | Yes | Must be `rotatecaptcha` | | `body` | Yes for base64 | Base64-encoded image that must be rotated | | `file` | Yes for multipart | Image file when using multipart upload | | `angle` | No | Rotation increment in degrees | | `json` | No | Set to `1` to receive JSON responses | The `angle` parameter defines the size of one rotation step. For example: ```text angle=40 ``` means the solver returns a result based on 40-degree increments. When the parameter is omitted, SolveCaptcha uses a default value of 40 degrees. Use the same rotation increment as the target widget whenever possible. If the page rotates the image by 15 degrees per button click, submit: ```text angle=15 ``` ## Create a rotate captcha task Example request: ```bash curl --request POST \ --url https://api.solvecaptcha.com/in.php \ --data-urlencode "key=YOUR_API_KEY" \ --data-urlencode "method=rotatecaptcha" \ --data-urlencode "body=BASE64_IMAGE" \ --data-urlencode "angle=40" \ --data-urlencode "json=1" ``` A successful response contains the captcha task ID: ```json { "status": 1, "request": "2122988149" } ``` Save the `request` value. It is required to retrieve the result. ## Get the rotation result Wait approximately five seconds before requesting the result: ```bash curl "https://api.solvecaptcha.com/res.php?key=YOUR_API_KEY&action=get&id=2122988149&json=1" ``` If the task is still being processed, the API returns: ```json { "status": 0, "request": "CAPCHA_NOT_READY" } ``` Wait another five seconds and repeat the request using the same task ID. When the task is complete, the response may look like: ```json { "status": 1, "request": "120" } ``` The returned value is the required rotation angle. For several submitted images, the response can contain multiple values: ```text 40|200|-120 ``` Each value corresponds to an image in the same order in which the images were submitted. ## Clockwise and counterclockwise rotation SolveCaptcha uses signed angle values: - a positive value means clockwise rotation; - a negative value means counterclockwise rotation. Examples: ```text 120 ``` Rotate the image 120 degrees clockwise. ```text -80 ``` Rotate the image 80 degrees counterclockwise. When the target widget supports rotation in only one direction, normalize negative values into the equivalent positive angle. Example: ```text -80 degrees = 280 degrees clockwise ``` Python conversion: ```python clockwise_angle = returned_angle % 360 ``` Examples: ```python 120 % 360 # 120 -80 % 360 # 280 -120 % 360 # 240 ``` Do not normalize the value when the interface supports both clockwise and counterclockwise controls and using the shorter direction is more appropriate. ## Complete Python client for SolveCaptcha Install Requests: ```bash python -m pip install requests ``` Set the API key. Linux or macOS: ```bash export SOLVECAPTCHA_API_KEY="YOUR_API_KEY" ``` Windows PowerShell: ```powershell $env:SOLVECAPTCHA_API_KEY="YOUR_API_KEY" ``` Create `solve_rotate_captcha.py`: ```python #!/usr/bin/env python3 import argparse import base64 import os import time from pathlib import Path from typing import Any import requests CREATE_TASK_URL = "https://api.solvecaptcha.com/in.php" GET_RESULT_URL = "https://api.solvecaptcha.com/res.php" class SolveCaptchaError(RuntimeError): """Raised when the SolveCaptcha API returns an error.""" def parse_json_response(response: requests.Response) -> dict[str, Any]: response.raise_for_status() try: data = response.json() except requests.JSONDecodeError as exc: raise SolveCaptchaError( f"SolveCaptcha returned invalid JSON: {response.text[:500]}" ) from exc if not isinstance(data, dict): raise SolveCaptchaError( f"Unexpected SolveCaptcha response: {data!r}" ) return data def parse_rotation_angles(answer: str) -> list[float]: normalized = answer.strip() if normalized.startswith("OK|"): normalized = normalized[3:] if not normalized: raise SolveCaptchaError("SolveCaptcha returned an empty answer") angles: list[float] = [] for raw_value in normalized.split("|"): value = raw_value.strip() if not value: continue try: angles.append(float(value)) except ValueError as exc: raise SolveCaptchaError( f"Unexpected rotation value: {value!r}" ) from exc if not angles: raise SolveCaptchaError( f"No rotation angles found in answer: {answer!r}" ) return angles class SolveCaptchaRotateClient: def __init__( self, api_key: str, poll_interval: float = 5.0, request_timeout: float = 30.0, ) -> None: if not api_key: raise ValueError("SolveCaptcha API key is required") self.api_key = api_key self.poll_interval = poll_interval self.request_timeout = request_timeout self.session = requests.Session() def create_task( self, image_bytes: bytes, angle_step: int = 40, ) -> str: if not image_bytes: raise ValueError("Captcha image is empty") if angle_step <= 0: raise ValueError( "Rotation angle step must be greater than zero" ) encoded_image = base64.b64encode(image_bytes).decode("ascii") payload = { "key": self.api_key, "method": "rotatecaptcha", "body": encoded_image, "angle": angle_step, "json": 1, } response = self.session.post( CREATE_TASK_URL, data=payload, timeout=self.request_timeout, ) data = parse_json_response(response) if data.get("status") != 1: error_code = str( data.get("request", "UNKNOWN_ERROR") ) raise SolveCaptchaError( f"Unable to create rotate captcha task: " f"{error_code}" ) task_id = str(data.get("request", "")).strip() if not task_id: raise SolveCaptchaError( "SolveCaptcha did not return a task ID" ) return task_id def get_result( self, task_id: str, ) -> list[float] | None: params = { "key": self.api_key, "action": "get", "id": task_id, "json": 1, } response = self.session.get( GET_RESULT_URL, params=params, timeout=self.request_timeout, ) data = parse_json_response(response) if data.get("status") == 1: return parse_rotation_angles( str(data.get("request", "")) ) error_code = str( data.get("request", "UNKNOWN_ERROR") ) if error_code == "CAPCHA_NOT_READY": return None raise SolveCaptchaError( f"Rotate captcha task {task_id} failed: " f"{error_code}" ) def solve( self, image_bytes: bytes, angle_step: int = 40, max_wait: float = 180.0, ) -> tuple[str, list[float]]: task_id = self.create_task( image_bytes=image_bytes, angle_step=angle_step, ) deadline = time.monotonic() + max_wait while time.monotonic() < deadline: time.sleep(self.poll_interval) result = self.get_result(task_id) if result is not None: return task_id, result raise TimeoutError( f"SolveCaptcha task {task_id} was not completed " f"within {max_wait:.0f} seconds" ) def report( self, task_id: str, accepted: bool, ) -> None: params = { "key": self.api_key, "action": ( "reportgood" if accepted else "reportbad" ), "id": task_id, "json": 1, } response = self.session.get( GET_RESULT_URL, params=params, timeout=self.request_timeout, ) parse_json_response(response) def main() -> None: parser = argparse.ArgumentParser( description=( "Solve a rotate captcha through SolveCaptcha." ) ) parser.add_argument( "image", type=Path, help="Path to the image that must be rotated", ) parser.add_argument( "--angle-step", type=int, default=40, help="Rotation increment used by the captcha", ) parser.add_argument( "--max-wait", type=float, default=180.0, help="Maximum result wait time in seconds", ) args = parser.parse_args() api_key = os.environ.get( "SOLVECAPTCHA_API_KEY", "", ).strip() if not api_key: raise SystemExit( "Set the SOLVECAPTCHA_API_KEY " "environment variable" ) if not args.image.is_file(): raise SystemExit( f"Image file does not exist: {args.image}" ) client = SolveCaptchaRotateClient( api_key=api_key ) task_id, angles = client.solve( image_bytes=args.image.read_bytes(), angle_step=args.angle_step, max_wait=args.max_wait, ) print(f"Task ID: {task_id}") for index, angle in enumerate(angles, start=1): direction = ( "clockwise" if angle >= 0 else "counterclockwise" ) print( f"Image {index}: " f"{abs(angle):g} degrees {direction}" ) if __name__ == "__main__": main() ``` Run the script: ```bash python solve_rotate_captcha.py rotate-captcha.png ``` Specify a different rotation increment: ```bash python solve_rotate_captcha.py rotate-captcha.png \ --angle-step 15 ``` Example output: ```text Task ID: 2122988149 Image 1: 120 degrees clockwise ``` ## How to extract a rotate captcha image The correct image must be submitted to SolveCaptcha. Avoid sending: - a full browser screenshot; - the slider track; - page text; - buttons; - borders around the captcha; - unrelated interface elements. Send only the image that must be rotated. The extraction method depends on how the widget renders the image. ## Extract an img element with Selenium If the captcha uses an `` element, Selenium can take a screenshot of that specific element: ```python from selenium.webdriver.common.by import By captcha_image = driver.find_element( By.CSS_SELECTOR, ".rotate-captcha img" ) image_bytes = captcha_image.screenshot_as_png ``` The returned PNG bytes can be passed directly to the Python client: ```python task_id, angles = client.solve( image_bytes=image_bytes, angle_step=40, ) ``` This approach captures only the rendered image and avoids including unrelated page elements. ## Extract a canvas image Some rotate captcha widgets use an HTML canvas. Try extracting the original canvas pixels: ```python import base64 data_url = driver.execute_script(""" const canvas = document.querySelector( '.rotate-captcha canvas' ); if (!canvas) { throw new Error('Captcha canvas not found'); } return canvas.toDataURL('image/png'); """) encoded = data_url.split(",", 1)[1] image_bytes = base64.b64decode(encoded) ``` Canvas extraction may fail when a cross-origin image has made the canvas unreadable. In that case, use an element screenshot: ```python canvas = driver.find_element( By.CSS_SELECTOR, ".rotate-captcha canvas" ) image_bytes = canvas.screenshot_as_png ``` ## Extract an image from a CSS background A captcha may use a CSS background instead of an `` element. Example: ```html
``` A simple option is to capture the element: ```python element = driver.find_element( By.CSS_SELECTOR, ".rotate-image" ) image_bytes = element.screenshot_as_png ``` When possible, inspect the Network panel and download the original image URL. Original image files usually produce more accurate results than resized browser screenshots. ## Preserve the original image dimensions The submitted image should not be: - stretched; - compressed excessively; - partially cropped; - rotated before submission; - covered by another element. If the image is rendered at a different size from the original file, you can still submit an element screenshot, but account for scaling when applying the result to the browser. For example: ```text Original image width: 323 px Rendered image width: 258.4 px Scale factor: 258.4 / 323 = 0.8 ``` The rotation angle itself does not change with image scaling, but slider dimensions and mouse offsets do. ## Apply the angle using rotation buttons Some widgets use clockwise and counterclockwise buttons. Suppose SolveCaptcha returns: ```text 120 ``` And each click rotates the image by: ```text 40 degrees ``` The required number of clicks is: ```text 120 / 40 = 3 ``` Selenium example: ```python from selenium.webdriver.common.by import By def apply_rotation_with_buttons( driver, angle: float, angle_step: int, ) -> None: clockwise_button = driver.find_element( By.CSS_SELECTOR, ".rotate-clockwise" ) counterclockwise_button = driver.find_element( By.CSS_SELECTOR, ".rotate-counterclockwise" ) click_count = round( abs(angle) / angle_step ) button = ( clockwise_button if angle >= 0 else counterclockwise_button ) for _ in range(click_count): button.click() ``` Call it with: ```python apply_rotation_with_buttons( driver=driver, angle=angles[0], angle_step=40, ) ``` Use the same `angle_step` value in both the SolveCaptcha request and browser interaction. ## Convert the angle into slider movement For a slider-controlled widget, convert degrees into pixels. The general formula is: ```text offset = usable slider width × returned angle ÷ total rotation range ``` For example: ```text Usable slider width: 280 px Rotation range: 360 degrees Returned angle: 180 degrees ``` Result: ```text 280 × 180 / 360 = 140 px ``` The usable slider width is usually: ```text track width - handle width ``` Python function: ```python def angle_to_slider_offset( angle: float, usable_width: float, rotation_range: float = 360.0, ) -> float: normalized_angle = angle % rotation_range return ( usable_width * normalized_angle / rotation_range ) ``` Example: ```python offset = angle_to_slider_offset( angle=180, usable_width=280, ) print(offset) # 140.0 ``` ## Move the rotate slider with Selenium The following example assumes: - the slider starts at zero degrees; - the complete slider range represents 360 degrees; - the handle initially starts at the left edge; - the widget accepts mouse drag events. ```python from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By def move_rotate_slider( driver, angle: float, ) -> None: track = driver.find_element( By.CSS_SELECTOR, ".rotate-slider-track" ) handle = driver.find_element( By.CSS_SELECTOR, ".rotate-slider-handle" ) track_width = track.rect["width"] handle_width = handle.rect["width"] usable_width = ( track_width - handle_width ) normalized_angle = angle % 360 offset = ( usable_width * normalized_angle / 360 ) actions = ActionChains(driver) actions.move_to_element(handle) actions.click_and_hold() actions.pause(0.1) actions.move_by_offset( offset * 0.35, 1, ) actions.pause(0.05) actions.move_by_offset( offset * 0.40, -1, ) actions.pause(0.05) actions.move_by_offset( offset * 0.25, 0, ) actions.pause(0.1) actions.release() actions.perform() ``` Use it after receiving the result: ```python task_id, angles = client.solve( image_bytes=image_bytes, angle_step=40, ) move_rotate_slider( driver=driver, angle=angles[0], ) ``` The selectors and angle-to-pixel mapping must be adapted to the target website. ## Widgets with a limited rotation range Not every slider represents a full 360-degree rotation. A widget may use: ```text Minimum angle: -180 degrees Maximum angle: 180 degrees ``` Or: ```text Minimum angle: 0 degrees Maximum angle: 270 degrees ``` Use the actual range when calculating the position. Example: ```python def map_angle_to_slider( angle: float, minimum_angle: float, maximum_angle: float, usable_width: float, ) -> float: angle_range = ( maximum_angle - minimum_angle ) if angle_range <= 0: raise ValueError( "Invalid rotation range" ) clamped_angle = max( minimum_angle, min(maximum_angle, angle), ) ratio = ( clamped_angle - minimum_angle ) / angle_range return usable_width * ratio ``` Example: ```python offset = map_angle_to_slider( angle=90, minimum_angle=-180, maximum_angle=180, usable_width=280, ) ``` Inspect the page’s JavaScript, slider attributes, or network requests to determine the actual angle range. ## How to find the slider-to-angle mapping Use browser developer tools to inspect the widget. Search the page scripts for: ```text rotate ``` ```text angle ``` ```text degree ``` ```text transform ``` ```text slider ``` ```text max ``` ```text step ``` You may find values such as: ```javascript const maxRotation = 360; const rotationStep = 2; ``` Or an input element: ```html ``` In this case, the mapping is direct: ```text slider value = angle ``` Another implementation may use: ```html ``` And convert the value internally: ```javascript angle = sliderValue * 3.6; ``` For a returned angle of 180 degrees: ```text slider value = 180 / 3.6 = 50 ``` Do not assume that slider pixels, input values, and rotation degrees are identical. ## Set a range input directly Some basic rotate captcha widgets use a native range input. Example: ```html ``` For testing an application you control, the value can be assigned and the expected events dispatched: ```python driver.execute_script(""" const slider = arguments[0]; const angle = arguments[1]; slider.value = angle; slider.dispatchEvent( new Event('input', { bubbles: true }) ); slider.dispatchEvent( new Event('change', { bubbles: true }) ); """, slider_element, normalized_angle) ``` Some third-party widgets ignore synthetic events or require real pointer movement. In that case, use Selenium `ActionChains`. ## Wait for verification correctly After applying the rotation, determine whether the challenge was accepted. Possible success indicators include: - the captcha dialog disappears; - a success icon appears; - the form submit button becomes enabled; - a hidden field receives a token; - an XHR verification request succeeds; - the page navigates; - the widget receives a success class. Example: ```python from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait wait = WebDriverWait(driver, 10) wait.until( EC.presence_of_element_located( ( By.CSS_SELECTOR, ".rotate-captcha-success", ) ) ) ``` Do not treat the absence of navigation as an automatic failure. Many captcha widgets verify the answer without reloading the page. ## Report correct and incorrect answers When the returned rotation is accepted, report it as correct: ```text action=reportgood ``` When the returned angle itself is incorrect, report it as incorrect: ```text action=reportbad ``` Example: ```python client.report( task_id=task_id, accepted=True, ) ``` Do not send `reportbad` when the failure was caused by: - an expired challenge; - an incorrect selector; - a wrong slider-width calculation; - using the wrong rotation range; - submitting a cropped image; - moving the wrong slider handle; - failing to dispatch the required events; - session or proxy problems. Only report an incorrect result when the returned angle was genuinely wrong. ## Handle CAPCHA_NOT_READY `CAPCHA_NOT_READY` means the task is still being processed. Correct behavior: 1. Keep the same task ID. 2. Wait five seconds. 3. Request the result again. 4. Stop after a defined timeout. Incorrect behavior: - creating a duplicate task; - polling continuously without a delay; - treating the response as a failed solution. ## Handle ERROR_CAPTCHA_UNSOLVABLE This error means SolveCaptcha could not determine a reliable orientation. Possible reasons include: - the image is too small; - the image is blurred; - the image contains the slider interface instead of the rotatable object; - the captcha changed while it was being captured; - the wrong image layer was submitted; - the image is already transformed; - the rotation increment does not match the challenge. Recommended action: 1. Reload the captcha. 2. Extract a fresh image. 3. Confirm the correct image dimensions. 4. Create a new task. 5. Limit the number of retries. Do not repeatedly submit the same unsolvable image. ## Other API errors ### ERROR_WRONG_USER_KEY The API key is invalid. Verify: ```text SOLVECAPTCHA_API_KEY ``` ### ERROR_ZERO_BALANCE The account balance is insufficient. Stop creating tasks until the balance is replenished. ### ERROR_NO_SLOT_AVAILABLE The task cannot currently be accepted. Use delayed retries or exponential backoff. ### Invalid JSON response Temporary server or proxy responses may contain HTML instead of JSON. Your API client should: - check the HTTP status; - handle JSON parsing errors; - log the response body; - retry temporary server errors; - limit the total number of retries. ## Keep the image and result synchronized A rotation result is valid only for the exact image submitted to SolveCaptcha. The challenge may refresh when: - the page reloads; - the captcha times out; - an incorrect answer is submitted; - the user clicks a reload button; - the browser session changes; - a verification request fails. Before applying the result, confirm that the captcha image is still the same. One method is to calculate an image hash: ```python import hashlib def image_hash(image_bytes: bytes) -> str: return hashlib.sha256( image_bytes ).hexdigest() ``` Store the hash when creating the task: ```python submitted_hash = image_hash( image_bytes ) ``` Before using the result, capture the current image again: ```python current_hash = image_hash( current_image_bytes ) if current_hash != submitted_hash: raise RuntimeError( "Rotate captcha changed before " "the answer was applied" ) ``` Discard answers for expired or replaced images. ## Multiple rotatable images SolveCaptcha can return several rotation values: ```text 40|200|-120 ``` The values correspond to the submitted images in order: ```text Image 1: 40 degrees clockwise Image 2: 200 degrees clockwise Image 3: 120 degrees counterclockwise ``` Preserve the original image order when creating the task and applying the results. Example mapping: ```python for element, angle in zip( image_elements, angles, strict=True, ): apply_angle( driver, element, angle, ) ``` Do not sort the images or angles after receiving the response. ## Common implementation mistakes ### Sending the complete captcha screenshot The solver needs the image that must be rotated, not the complete page or captcha interface. ### Using the wrong angle step The `angle` request parameter should match the widget’s rotation increment. ### Ignoring negative values Negative values indicate counterclockwise rotation. ### Assuming every slider represents 360 degrees Inspect the widget’s actual minimum and maximum values. ### Applying the answer after the captcha refreshes The result belongs only to the submitted image. ### Using the image width as the slider width The slider track and captcha image can have different dimensions. ### Reporting integration errors as bad answers Use `reportbad` only when the returned angle is wrong. ### Hardcoding selectors throughout the scraper Keep captcha selectors in one class or configuration object so that page changes can be handled quickly. ## Recommended architecture Keep the integration separated into clear components: ```text RotateCaptchaExtractor Extracts the image and challenge metadata SolveCaptchaRotateClient Creates tasks and retrieves angles RotateSliderController Converts angles into clicks or slider movement RotateCaptchaVerifier Checks whether the answer was accepted ``` This structure makes it easier to: - replace Selenium with Playwright or Puppeteer; - support several rotate captcha implementations; - update page selectors; - add logging and retries; - test API logic separately from browser logic. ## Frequently asked questions ### What does SolveCaptcha return for rotate captcha? It returns the angle required to rotate each submitted image. Example: ```text 120 ``` Or several angles: ```text 40|200|-120 ``` ### What does a negative angle mean? A negative value means the image should be rotated counterclockwise. ### Which API method should I use? Use: ```text method=rotatecaptcha ``` ### Which endpoints are required? Create the task: ```text https://api.solvecaptcha.com/in.php ``` Retrieve the result: ```text https://api.solvecaptcha.com/res.php ``` ### Can I submit a base64 image? Yes. Put the base64-encoded image in the `body` parameter. ### What is the default rotation step? The default `angle` value is 40 degrees. Set a different value when the widget uses another rotation increment. ### Can Selenium rotate the image directly? Selenium can modify CSS transforms, click rotation buttons, change a range input, or drag a slider. The correct method depends on how the website validates the interaction. ### How do I convert degrees into pixels? Use: ```text offset = usable slider width × angle ÷ rotation range ``` ### Why is the returned angle correct but verification fails? Possible causes include: - incorrect clockwise or counterclockwise handling; - wrong slider mapping; - incorrect rotation range; - stale challenge image; - missing mouse events; - session-specific verification; - a wrong image layer; - premature slider release. ## Conclusion Automatic rotate slider captcha solving requires two separate components: 1. SolveCaptcha determines the required rotation angle. 2. Selenium, Playwright, Puppeteer, or another browser framework applies that angle through the target widget. A reliable workflow should: 1. capture only the rotatable image; 2. preserve the original dimensions and orientation; 3. submit it with `method=rotatecaptcha`; 4. specify the widget’s rotation increment through `angle`; 5. poll `res.php` every five seconds; 6. interpret positive and negative values correctly; 7. convert the angle into clicks, slider values, or mouse movement; 8. verify the real success state; 9. report accepted and incorrect answers accurately; 10. discard results when the captcha image changes. Use the [SolveCaptcha rotate captcha API](/captcha-solver-api#solving_rotatecaptcha) to integrate automatic rotation recognition into authorized browser automation and data collection workflows.