
Ethan Collins
Pattern Recognition Specialist

When your AI-powered web automation hits a CAPTCHA wall, the entire pipeline stalls. Pages fail to load, forms can't be submitted, and data extraction grinds to a halt — all because of a challenge designed to block bots. TinyFish AgentQL is a powerful suite of tools for connecting AI to the web, featuring natural language queries, Playwright integrations, and structured data extraction at enterprise scale. But like any browser automation framework, it gets stuck on CAPTCHAs.
CapSolver changes this completely. By loading the CapSolver Chrome extension into AgentQL's Playwright-powered browser context, CAPTCHAs are resolved automatically and invisibly in the background. No manual solving. No complex API orchestration on your end. Your automation scripts keep running as if the CAPTCHA was never there.
The best part? Your AgentQL queries and scripts don't need a single line of CAPTCHA-related code. The extension handles detection, solving, and token injection entirely on its own while your agent focuses on what it does best — extracting data and automating workflows.
TinyFish AgentQL is an enterprise-grade toolkit for connecting AI agents and LLMs to live web environments. Developed by TinyFish, it provides an AI-powered query language that lets you locate page elements and extract structured data using natural language — no brittle CSS selectors or XPaths required.
AgentQL operates on any page — including authenticated content and dynamically generated pages — making it ideal for large-scale web automation, data collection, and AI agent workflows.
CapSolver is a leading AI-powered CAPTCHA solving service that automatically resolves diverse CAPTCHA challenges. With fast response times and broad compatibility, CapSolver integrates seamlessly into automated workflows.
Most CAPTCHA-solving integrations require you to write boilerplate code: create tasks, poll for results, inject tokens into hidden fields. That's the standard approach with raw Playwright or Puppeteer scripts.
AgentQL + CapSolver takes a fundamentally different approach:
| Traditional (Code-Based) | AgentQL + CapSolver Extension |
|---|---|
| Write a CapSolver service class | Load extension in Playwright context |
Call createTask() / getTaskResult() |
Extension handles everything automatically |
Inject tokens via page.evaluate() |
Token injection is invisible |
| Handle errors, retries, timeouts in code | Extension manages retries internally |
| Different code for each CAPTCHA type | Works for all types automatically |
The key insight: The CapSolver extension runs inside AgentQL's Playwright browser context. When AgentQL navigates to a page with a CAPTCHA, the extension detects it, solves it in the background, and injects the token — all before your script interacts with the form. Your automation code stays clean, focused, and CAPTCHA-free.
Before setting up the integration, make sure you have:
Important: Chrome extensions only work in Chromium with a persistent context in Playwright. This is a Playwright requirement, not an AgentQL limitation.
Python SDK:
pip install agentql
playwright install chromium
JavaScript SDK:
npm install agentql
npx playwright install chromium
Download the CapSolver Chrome extension and extract it to a dedicated directory:
CapSolver.Browser.Extension-chrome-v1.17.0.zipmkdir -p ~/capsolver-extension
unzip CapSolver.Browser.Extension-chrome-v*.zip -d ~/capsolver-extension/
ls ~/capsolver-extension/manifest.json
You should see manifest.json — this confirms the extension is in the right place.
Open the extension config file at ~/capsolver-extension/assets/config.js and replace the apiKey value with your own:
export const defaultConfig = {
apiKey: 'CAP-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', // ← your key here
useCapsolver: true,
// ... rest of the config
};
You can get your API key from your CapSolver dashboard.
The critical step is launching Playwright's Chromium with a persistent context that loads the CapSolver extension.
Python Example:
import agentql
from playwright.sync_api import sync_playwright
import time
import os
# Path to CapSolver extension
CAPSOLVER_EXTENSION_PATH = os.path.expanduser("~/capsolver-extension")
def main():
with sync_playwright() as p:
# Launch Chromium with persistent context and CapSolver extension
context = p.chromium.launch_persistent_context(
user_data_dir="./browser-data",
headless=False, # Extensions require headed mode
args=[
f"--disable-extensions-except={CAPSOLVER_EXTENSION_PATH}",
f"--load-extension={CAPSOLVER_EXTENSION_PATH}",
],
)
# Wrap the page with AgentQL for AI-powered queries
page = agentql.wrap(context.pages[0])
# Navigate to your target page
page.goto("https://example.com/protected-page")
# Wait for CapSolver to detect and solve any CAPTCHA
time.sleep(30)
# Find and click the submit button using AgentQL's natural language queries
response = page.query_elements("""
{
submit_button
}
""")
# Click the submit button — CAPTCHA is already solved!
response.submit_button.click()
# Extract data after submission
result = page.query_data("""
{
confirmation_message
}
""")
print(f"Result: {result['confirmation_message']}")
context.close()
if __name__ == "__main__":
main()
JavaScript Example:
const { chromium } = require('playwright');
const agentql = require('agentql');
const path = require('path');
const os = require('os');
const CAPSOLVER_EXTENSION_PATH = path.join(os.homedir(), 'capsolver-extension');
(async () => {
// Launch Chromium with persistent context and CapSolver extension
const context = await chromium.launchPersistentContext('./browser-data', {
headless: false, // Extensions require headed mode
args: [
`--disable-extensions-except=${CAPSOLVER_EXTENSION_PATH}`,
`--load-extension=${CAPSOLVER_EXTENSION_PATH}`,
],
});
// Get the first page and wrap with AgentQL
const page = agentql.wrap(context.pages()[0]);
// Navigate to target page
await page.goto('https://example.com/protected-page');
// Wait for CapSolver to handle any CAPTCHA
await page.waitForTimeout(30000);
// Use AgentQL queries to interact — CAPTCHA already solved
const response = await page.queryElements(`{
submit_button
}`);
await response.submit_button.click();
// Extract result data
const result = await page.queryData(`{
confirmation_message
}`);
console.log('Result:', result.confirmation_message);
await context.close();
})();
After launching the browser, you can verify the CapSolver extension is active by navigating to chrome://extensions in the browser window. You should see the CapSolver extension listed and enabled.
Alternatively, check the browser console for CapSolver log messages indicating the service worker is running.
Once setup is complete, using CapSolver with AgentQL is straightforward.
Don't write CAPTCHA-specific code. Just add a wait time before interacting with CAPTCHA-protected forms, and let the extension do its work.
page.goto("https://example.com/contact")
# Fill in the form using AgentQL queries
response = page.query_elements("""
{
contact_form {
name_field
email_field
message_field
submit_button
}
}
""")
response.contact_form.name_field.fill("John Doe")
response.contact_form.email_field.fill("john@example.com")
response.contact_form.message_field.fill("Hello, I have a question about your services.")
# Wait for CapSolver to resolve the CAPTCHA
time.sleep(30)
# Submit — the CAPTCHA token is already injected
response.contact_form.submit_button.click()
page.goto("https://example.com/login")
# Wait for CapSolver to resolve the Turnstile challenge
time.sleep(25)
# Find login form elements with AgentQL
response = page.query_elements("""
{
login_form {
email_input
password_input
login_button
}
}
""")
# Fill in the form — Turnstile is already handled
response.login_form.email_input.fill("me@example.com")
response.login_form.password_input.fill("mypassword123")
# Click login
response.login_form.login_button.click()
page.goto("https://example.com/data")
# Wait for any CAPTCHA challenge to clear
time.sleep(30)
# Extract structured data with AgentQL
data = page.query_data("""
{
products[] {
name
price
rating
availability
}
}
""")
for product in data['products']:
print(f"{product['name']}: ${product['price']} ({product['rating']} stars)")
| CAPTCHA Type | Typical Solve Time | Recommended Wait |
|---|---|---|
| reCAPTCHA v2 (checkbox) | 5-15 seconds | 30-60 seconds |
| reCAPTCHA v2 (invisible) | 5-15 seconds | 30 seconds |
| reCAPTCHA v3 | 3-10 seconds | 20-30 seconds |
| Cloudflare Turnstile | 3-10 seconds | 20-30 seconds |
Tip: When in doubt, use 30 seconds. It's better to wait a bit longer than to submit too early. The extra time doesn't affect the result.
Here's what happens when AgentQL runs with the CapSolver extension loaded:
Your AgentQL Script
───────────────────────────────────────────────────
page.goto("https://...") ──► Chromium loads the page
│
▼
┌─────────────────────────────┐
│ Page with CAPTCHA widget │
│ │
│ CapSolver Extension: │
│ 1. Content script detects │
│ CAPTCHA on the page │
│ 2. Service worker calls │
│ CapSolver API │
│ 3. Token received │
│ 4. Token injected into │
│ hidden form field │
└─────────────────────────────┘
│
▼
time.sleep(30) Extension resolves CAPTCHA...
│
▼
page.query_elements(...) AgentQL finds form elements
submit_button.click() Form submits WITH valid token
│
▼
"Verification successful!"
When Playwright launches Chromium with the --load-extension flag:
Here's a complete Python setup with all configuration options for the AgentQL + CapSolver integration:
import agentql
from playwright.sync_api import sync_playwright
import os
# Configuration
CAPSOLVER_EXTENSION_PATH = os.path.expanduser("~/capsolver-extension")
USER_DATA_DIR = "./browser-data"
with sync_playwright() as p:
context = p.chromium.launch_persistent_context(
user_data_dir=USER_DATA_DIR,
headless=False,
args=[
f"--disable-extensions-except={CAPSOLVER_EXTENSION_PATH}",
f"--load-extension={CAPSOLVER_EXTENSION_PATH}",
],
)
page = agentql.wrap(context.pages[0])
# ... your automation code here
context.close()
| Option | Description |
|---|---|
user_data_dir |
Directory to store browser profile data (cookies, sessions). Required for persistent context. |
headless |
Must be False — Chrome extensions do not work in headless mode. |
--disable-extensions-except |
Restricts which extensions can load (prevents conflicts). |
--load-extension |
Path to the unpacked CapSolver extension directory. |
CAPSOLVER_EXTENSION_PATH |
Full path to the extracted CapSolver extension containing manifest.json. |
The CapSolver API key is configured directly in the extension's assets/config.js file (see Step 3 above).
Symptom: CAPTCHAs aren't being solved automatically.
Cause: You may be using a regular browser context instead of a persistent context, or running in headless mode.
Solution: Extensions in Playwright require a persistent context and headed mode:
# ✅ Correct — persistent context, headed
context = p.chromium.launch_persistent_context(
user_data_dir="./browser-data",
headless=False,
args=[...extension args...]
)
# ❌ Wrong — regular context (extensions won't load)
browser = p.chromium.launch()
context = browser.new_context()
Possible causes:
Symptom: Script runs but no extension appears.
Cause: Chrome extensions do not work in headless mode.
Solution: Use headed mode with a virtual display on servers:
# Install Xvfb
sudo apt-get install xvfb
# Start a virtual display
Xvfb :99 -screen 0 1280x720x24 &
# Set DISPLAY
export DISPLAY=:99
Symptom: Extension flag is silently ignored.
Cause: Google Chrome 137+ removed support for --load-extension in branded builds.
Solution: Use Playwright's bundled Chromium (recommended) or Chrome for Testing:
# Install Playwright's Chromium (recommended)
npx playwright install chromium
# Or download Chrome for Testing
# Visit: https://googlechromelabs.github.io/chrome-for-testing/
Always use generous wait times. More wait time is always safer. The CAPTCHA typically resolves in 5-20 seconds, but network latency, complex challenges, or retries can add time. 30-60 seconds is the sweet spot.
Keep your automation scripts clean. Don't add CAPTCHA-specific logic to your AgentQL queries. The extension handles everything — your code should focus purely on data extraction and interaction.
Monitor your CapSolver balance. Each CAPTCHA resolution costs credits. Check your balance at capsolver.com/dashboard regularly to avoid interruptions.
Use persistent context consistently. Always launch with launch_persistent_context() when you need extensions. This also preserves cookies and session data across runs, which can reduce CAPTCHA frequency.
Use Xvfb on headless servers. Chrome extensions require a display context. Set up Xvfb for server environments where no physical display is available.
The TinyFish AgentQL + CapSolver integration brings invisible CAPTCHA solving to one of the most powerful web automation toolkits available. Instead of writing complex CAPTCHA-handling code, you simply:
The CapSolver Chrome extension handles the rest — detecting CAPTCHAs, solving them via the CapSolver API, and injecting tokens into the page. Your AgentQL scripts never need to know about CAPTCHAs at all.
This is what CAPTCHA solving looks like when you combine AI-powered web automation with AI-powered CAPTCHA solving: invisible, automatic, and code-free.
Ready to get started? Sign up for CapSolver and use the bonus code AGENTQL to get an extra 6% on your first top-up!

No. The CapSolver extension works entirely in the background within the Playwright browser context. Just add a time.sleep() or waitForTimeout() before submitting forms, and the extension handles detection, solving, and token injection automatically.
Playwright only supports Chrome extensions when using launch_persistent_context(). This is a Playwright architecture requirement. Regular browser contexts created via browser.new_context() cannot load extensions.
No. Chrome extensions require a headed browser. For server environments without a display, use Xvfb (X Virtual Framebuffer) to create a virtual display.
CapSolver supports reCAPTCHA v2 (checkbox and invisible), reCAPTCHA v3, Cloudflare Turnstile, AWS WAF CAPTCHA, and more. The extension automatically detects the CAPTCHA type and resolves it accordingly.
CapSolver offers competitive pricing based on CAPTCHA type and volume. Visit capsolver.com for current pricing.
AgentQL offers both free and paid tiers. The SDK and query language are available for development and testing. Visit tinyfish.ai for pricing details.
For most CAPTCHAs, 30-60 seconds is sufficient. The actual solve time is typically 5-20 seconds, but adding extra buffer ensures reliability. When in doubt, use 30 seconds.
Discover the best AI for solving image puzzles. Learn how CapSolver's Vision Engine and ImageToText APIs automate complex visual challenges with high accuracy.

Learn how search API tools, knowledge supply chains, SERP API workflows, and AI data pipelines shape modern web data infrastructure for AI.
