Use this page when your Playwright automation flow needs a stable captcha solving path with practical API integration guidance.
Death By Captcha (DBC) lets Playwright scripts resolve captcha challenges through the API instead of manual interaction: your script extracts the challenge parameters from the page, requests a solution from DBC, injects the result back into the page, and continues the flow. This page is the quickstart: installation, a runnable code sample, and supported task notes.
Node.js:
npm install playwright deathbycaptcha-lib
Python:
pip install deathbycaptcha-official
Use your DBC account credentials in the client. Create an account and check pricing and balance before running the flow.
const { chromium } = require('playwright');
const { HttpClient } = require('deathbycaptcha-lib');
const client = new HttpClient(process.env.DBC_USERNAME, process.env.DBC_PASSWORD);
const DEMO_URL = 'https://www.google.com/recaptcha/api2/demo';
async function solveRecaptchaV2(pageUrl, sitekey) {
const balance = await new Promise((resolve, reject) =>
client.get_balance((b) => (b ? resolve(b) : reject(new Error('Could not read balance')))));
if (balance <= 0) throw new Error('No balance - top up before solving.');
return new Promise((resolve, reject) =>
client.decode(
{ extra: { type: 4, token_params: JSON.stringify({ googlekey: sitekey, pageurl: pageUrl }) } },
(solution) => (solution && solution.text ? resolve(solution.text) : reject(new Error('No solution yet - retry')))
));
}
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto(DEMO_URL, { timeout: 60000 });
// 1. extract the challenge parameters
const sitekey = await page.getAttribute('#recaptcha-demo', 'data-sitekey');
// 2. request the solution token from DBC (type 4 = reCAPTCHA v2 token)
const token = await solveRecaptchaV2(DEMO_URL, sitekey);
// 3. inject the token and trigger the page callback
await page.evaluate((t) => {
const el = document.getElementById('g-recaptcha-response');
if (!el) return;
el.style.display = 'block';
el.value = t;
el.dispatchEvent(new Event('input', { bubbles: true }));
el.dispatchEvent(new Event('change', { bubbles: true }));
const cfg = window.___grecaptcha_cfg;
if (!cfg || !cfg.clients) return;
for (const k of Object.keys(cfg.clients)) {
const c = cfg.clients[k];
for (const key of Object.keys(c)) {
const item = c[key];
if (item && typeof item.callback === 'function') return item.callback(t);
if (item && item.W && typeof item.W.callback === 'function') return item.W.callback(t);
}
}
}, token);
// 4. submit and wait for success
await page.click('#recaptcha-demo-submit');
await page.waitForSelector('.recaptcha-success', { timeout: 15000 });
console.log('solved');
await browser.close();
})();
Full runnable version: examples/playwright in the official Node.js client repository
| Topic | Note |
|---|---|
| Captcha types (API) | reCAPTCHA v2 and v3, Cloudflare Turnstile, GeeTest, DataDome, and image/text captchas. |
| Balance | Solutions are paid from the account balance; check it before decoding. |
| Retries | No solution returned means transient: retry with backoff, as the official example does. |
| API vs extension | This flow uses the API inside your script; the browser extension is the no-code path for manual browsing. |
| Supported browsers | Chromium, Firefox and WebKit via Playwright (sample verified on Chromium). |
| Area | Why it matters | Recommended practice |
|---|---|---|
| Proxy consistency | Reduces verification mismatch risk in token flows. | Keep solve and submit path aligned in automation context. |
| Timeout discipline | Prevents queue stalls and flaky CI runs. | Use bounded retries with deterministic fallback handling. |
| Type-specific handling | Different challenge classes need different payload fields. | Start from API type pages and validate one type at a time. |
For Playwright captcha solver rollout, validate one captcha type first, then expand coverage with reliability and pricing checks for production scale.