# Integrating CapSolver with Skyvern: A Developer-First Pattern

![](https://cdn.hashnode.com/uploads/covers/69d75cd8fa7251682e63633a/a0cfa7ea-a1fb-4a71-9701-7a0282a10335.png align="center")

Skyvern can interpret a page and act on natural-language instructions. CapSolver can return a documented CAPTCHA solution. A production integration should connect them without placing secrets or low-level verification state inside the AI agent.

This tutorial shows the pattern for owned or explicitly authorized environments.

## Architecture

Use a narrow pipeline:

```text
Navigate with Skyvern
→ classify the authorized challenge
→ call CapSolver from application code
→ return the result to the same browser page
→ continue with Skyvern
→ verify the intended operation
```

Skyvern’s public SDK exposes AI-assisted page operations such as `page.act()` and `page.validate()`. CapSolver’s SDK accepts task parameters and returns a solution. Your application remains responsible for authorization, session ownership, secrets, and success checks.

## Setup

Skyvern currently supports Python 3.11–3.13 in its pip quickstart:

```bash
python -m venv .venv
source .venv/bin/activate

pip install "skyvern[all]"
pip install --upgrade capsolver
python -m playwright install chromium
```

Load credentials outside the prompt:

```bash
export CAPSOLVER_API_KEY="set-this-in-your-secret-manager"
```

## Solve a documented reCAPTCHA v2 task

The official CapSolver documentation shows:

```python
import capsolver

solution = capsolver.solve({
    "type": "ReCaptchaV2TaskProxyLess",
    "websiteURL": "https://www.google.com/recaptcha/api2/demo",
    "websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
})

token = solution["gRecaptchaResponse"]
```

Use the actual authorized page URL and site key. Keep the API key in the host process; do not add it to Skyvern instructions or logs.

## Hand the result to the page

For a page that uses the standard hidden response field:

```python
async def inject_token(page, token: str) -> None:
    await page.evaluate(
        """
        (token) => {
            const textarea = document.getElementById('g-recaptcha-response');
            if (!textarea) {
                throw new Error('g-recaptcha-response field not found');
            }
            textarea.value = token;
            textarea.dispatchEvent(new Event('change', { bubbles: true }));
        }
        """,
        token,
    )
```

Treat this as one integration pattern, not a universal recipe. A system you own may use a callback or server request instead. Inspect its implementation and preserve the same browser session.

## Resume and validate

```python
await page.act("Submit the form")
ok = await page.validate(
    "The authorized test completed and the expected result is visible"
)
if not ok:
    raise RuntimeError("Expected result was not verified")
```

Never treat “CapSolver returned a value” as proof that the business operation completed.

## Add ImageToTextTask when the page uses an image code

For an authorized image CAPTCHA:

```python
image_src = await page.locator("#demoCaptcha_CaptchaImage").get_attribute("src")
if not image_src or "," not in image_src:
    raise RuntimeError("A valid Base64 CAPTCHA image was not found")

base64_image = image_src.split(",", 1)[1]
solution = capsolver.solve({
    "type": "ImageToTextTask",
    "websiteURL": TARGET_URL,
    "module": "common",
    "body": base64_image,
})
captcha_text = solution["text"]
```

Fill the returned text into the expected input, submit, and verify the page result. Consult the [current ImageToTextTask reference](https://docs.capsolver.com/en/guide/recognition/ImageToTextTask/) before using optional modules.

## Debugging checklist

*   Does `websiteURL` match the current page?
    
*   Does the site key belong to that page?
    
*   Did navigation invalidate the page state?
    
*   Did the result reach the expected field or callback?
    
*   Is the browser session unchanged?
    
*   Is the success assertion specific?
    
*   Is the retry budget bounded?
    

## Security checklist

*   Allowlist authorized domains.
    
*   Keep API keys in a secret store.
    
*   Redact tokens and cookies from traces.
    
*   Reject redirects to unapproved hosts.
    
*   Limit retries and total runtime.
    
*   Require a final application assertion.
    

## Closing thought

AI browser automation works best when the model handles semantic interaction and deterministic code handles security-sensitive state. Skyvern and CapSolver fit that division naturally when the integration keeps authorization, secrets, token handoff, and verification outside the prompt.

Links:

*   [Skyvern](https://github.com/Skyvern-AI/skyvern)
    
*   [CapSolver](https://www.capsolver.com/?utm_source=hashnode&utm_medium=article&utm_campaign=skyvern-capsolver)
    
*   [reCAPTCHA v2 guide](https://docs.capsolver.com/en/guide/captcha/ReCaptchaV2/)
