Tutorials

Solving reCAPTCHA v2 with Node.js Fetch API and CaptchaAI

Node 18+ includes the native fetch API — no axios or node-fetch needed. This guide covers the full reCAPTCHA v2 solve flow with CaptchaAI using only built-in Node.js APIs.


Prerequisites

  • Node.js 18+ (for native fetch)
  • CaptchaAI API key

No external packages required.


Step 1: Submit the reCAPTCHA task

const API_KEY = "YOUR_API_KEY";

async function submitRecaptcha(sitekey, pageurl) {
  const params = new URLSearchParams({
    key: API_KEY,
    method: "userrecaptcha",
    googlekey: sitekey,
    pageurl: pageurl,
    json: "1",
  });

  const response = await fetch("https://ocr.captchaai.com/in.php", {
    method: "POST",
    body: params,
  });

  const data = await response.json();

  if (data.status !== 1) {
    throw new Error(`Submit error: ${data.request}`);
  }

  console.log(`Task submitted: ${data.request}`);
  return data.request;
}

Step 2: Poll for the result

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function pollResult(taskId) {
  const params = new URLSearchParams({
    key: API_KEY,
    action: "get",
    id: taskId,
    json: "1",
  });

  for (let i = 0; i < 30; i++) {
    await sleep(5000);

    const response = await fetch(
      `https://ocr.captchaai.com/res.php?${params}`
    );
    const data = await response.json();

    if (data.status === 1) {
      console.log("Solved!");
      return data.request;
    }

    if (data.request === "ERROR_CAPTCHA_UNSOLVABLE") {
      throw new Error("CAPTCHA unsolvable");
    }

    console.log(`Polling... (${i + 1}/30)`);
  }

  throw new Error("Solve timed out");
}

Step 3: Complete solve function

async function solveRecaptchaV2(sitekey, pageurl) {
  const taskId = await submitRecaptcha(sitekey, pageurl);
  const token = await pollResult(taskId);
  return token;
}

// Usage
const token = await solveRecaptchaV2(
  "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
  "https://example.com/login"
);
console.log(`Token: ${token.substring(0, 50)}...`);

Step 4: Submit the token to the target site

async function submitForm(url, formData) {
  const params = new URLSearchParams(formData);

  const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    },
    body: params,
    redirect: "follow",
  });

  return {
    status: response.status,
    url: response.url,
    body: await response.text(),
  };
}

// Full flow
async function loginWithRecaptcha(loginUrl, sitekey, credentials) {
  // Solve reCAPTCHA
  const token = await solveRecaptchaV2(sitekey, loginUrl);

  // Submit login form with token
  const result = await submitForm(loginUrl, {
    ...credentials,
    "g-recaptcha-response": token,
  });

  console.log(`Login result: ${result.status} → ${result.url}`);
  return result;
}

Extracting the sitekey from HTML

async function extractSitekey(url) {
  const response = await fetch(url, {
    headers: {
      "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    },
  });
  const html = await response.text();

  // Pattern 1: data-sitekey attribute
  const match = html.match(/data-sitekey=["']([A-Za-z0-9_-]{40})["']/);
  if (match) return match[1];

  // Pattern 2: render parameter in script src
  const renderMatch = html.match(/render=([A-Za-z0-9_-]{40})/);
  if (renderMatch) return renderMatch[1];

  // Pattern 3: grecaptcha.render call
  const renderCall = html.match(
    /grecaptcha\.render\s*\([^,]+,\s*\{[^}]*sitekey\s*:\s*["']([A-Za-z0-9_-]{40})["']/
  );
  if (renderCall) return renderCall[1];

  return null;
}

Production-ready solver class

class RecaptchaV2Solver {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async solve(sitekey, pageurl, options = {}) {
    const taskId = await this.#submit(sitekey, pageurl, options);
    return await this.#poll(taskId);
  }

  async #submit(sitekey, pageurl, options) {
    const body = new URLSearchParams({
      key: this.apiKey,
      method: "userrecaptcha",
      googlekey: sitekey,
      pageurl: pageurl,
      json: "1",
      ...(options.invisible && { invisible: "1" }),
      ...(options.data_s && { "data-s": options.data_s }),
    });

    const resp = await fetch("https://ocr.captchaai.com/in.php", {
      method: "POST",
      body,
    });
    const data = await resp.json();

    if (data.status !== 1) {
      throw new Error(`Submit: ${data.request}`);
    }
    return data.request;
  }

  async #poll(taskId) {
    const params = new URLSearchParams({
      key: this.apiKey,
      action: "get",
      id: taskId,
      json: "1",
    });

    for (let i = 0; i < 30; i++) {
      await new Promise((r) => setTimeout(r, 5000));

      const resp = await fetch(`https://ocr.captchaai.com/res.php?${params}`);
      const data = await resp.json();

      if (data.status === 1) return data.request;
      if (data.request === "ERROR_CAPTCHA_UNSOLVABLE") {
        throw new Error("CAPTCHA unsolvable");
      }
    }
    throw new Error("Timed out");
  }
}

// Usage
const solver = new RecaptchaV2Solver("YOUR_API_KEY");
const token = await solver.solve(
  "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
  "https://example.com/login"
);

Handling cookies and sessions

async function solveWithSession(loginUrl, sitekey, credentials) {
  // Node.js fetch doesn't handle cookies automatically.
  // Extract Set-Cookie headers manually.

  // Step 1: Get the login page (capture cookies)
  const pageResp = await fetch(loginUrl, { redirect: "manual" });
  const cookies = pageResp.headers.getSetCookie?.() || [];
  const cookieHeader = cookies.map((c) => c.split(";")[0]).join("; ");

  // Step 2: Solve CAPTCHA
  const solver = new RecaptchaV2Solver(API_KEY);
  const token = await solver.solve(sitekey, loginUrl);

  // Step 3: Submit with cookies
  const result = await fetch(loginUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Cookie: cookieHeader,
    },
    body: new URLSearchParams({
      ...credentials,
      "g-recaptcha-response": token,
    }),
    redirect: "manual",
  });

  return {
    status: result.status,
    location: result.headers.get("location"),
    cookies: result.headers.getSetCookie?.() || [],
  };
}

Troubleshooting

Symptom Cause Fix
fetch is not defined Node.js < 18 Upgrade Node or use node-fetch
ERROR_WRONG_GOOGLEKEY Invalid sitekey Re-extract from the page HTML
Token rejected by server Token expired (>2 min) Submit form faster after solving
Login returns same page Missing CSRF or cookies Extract hidden form fields and send cookies
TypeError: resp.json() Non-JSON response Check response status first

Frequently asked questions

Can I use axios instead of fetch?

Yes. Replace fetch() with axios.post() / axios.get(). The CaptchaAI API works the same regardless of HTTP client.

How long until the token expires?

reCAPTCHA v2 tokens expire after approximately 2 minutes. Solve and submit as quickly as possible.

Does this work with reCAPTCHA v2 Invisible?

Yes. Add invisible: "1" to the submit parameters. The API flow is identical.


Summary

Solve reCAPTCHA v2 with Node.js native fetch and CaptchaAI: extract the sitekey, submit to the API, poll for the token, and inject it into the form POST. No external packages needed on Node 18+.

Discussions (0)

No comments yet.

Related Posts

API Tutorials How to Solve reCAPTCHA v2 Enterprise with Node.js
Solve re CAPTCHA v 2 Enterprise using Node.js and Captcha AI API.

Solve re CAPTCHA v 2 Enterprise using Node.js and Captcha AI API. Complete guide with sitekey detection, task...

Automation reCAPTCHA v2 reCAPTCHA Enterprise
Jan 11, 2026
Explainers reCAPTCHA v2 Invisible: Trigger Detection and Solving
Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters, and handle auto-invoked CAPTCHAs.

Detect and solve re CAPTCHA v 2 Invisible challenges with Captcha AI — identify triggers, extract parameters,...

Automation Python reCAPTCHA v2
Apr 07, 2026
Comparisons WebDriver vs Chrome DevTools Protocol for CAPTCHA Automation
Compare Web Driver and Chrome Dev Tools Protocol (CDP) for CAPTCHA automation — detection, performance, capabilities, and when to use each with Captcha AI.

Compare Web Driver and Chrome Dev Tools Protocol (CDP) for CAPTCHA automation — detection, performance, capabi...

Automation Python reCAPTCHA v2
Mar 27, 2026
Reference CAPTCHA Token Injection Methods Reference
Complete reference for injecting solved CAPTCHA tokens into web pages.

Complete reference for injecting solved CAPTCHA tokens into web pages. Covers re CAPTCHA, Turnstile, and Cloud...

Automation Python reCAPTCHA v2
Apr 08, 2026
API Tutorials How to Solve reCAPTCHA v2 Enterprise with Python
Solve re CAPTCHA v 2 Enterprise using Python and Captcha AI API.

Solve re CAPTCHA v 2 Enterprise using Python and Captcha AI API. Complete guide with sitekey extraction, task...

Automation Python reCAPTCHA v2
Apr 08, 2026
Tutorials Pytest Fixtures for CaptchaAI API Testing
Build reusable pytest fixtures to test CAPTCHA-solving workflows with Captcha AI.

Build reusable pytest fixtures to test CAPTCHA-solving workflows with Captcha AI. Covers mocking, live integra...

Automation Python reCAPTCHA v2
Apr 08, 2026
Tutorials CAPTCHA Solving Fallback Chains
Implement fallback chains for CAPTCHA solving with Captcha AI.

Implement fallback chains for CAPTCHA solving with Captcha AI. Cascade through solver methods, proxy pools, an...

Automation Python reCAPTCHA v2
Apr 06, 2026
Use Cases Multi-Step Workflow Automation with CaptchaAI
Manage workflows across multiple accounts on CAPTCHA-protected platforms — , action, and data collection at scale.

Manage workflows across multiple accounts on CAPTCHA-protected platforms — , action, and data collection at sc...

Automation Python reCAPTCHA v2
Apr 06, 2026
API Tutorials Solving CAPTCHAs with Kotlin and CaptchaAI API
Complete guide to solving re CAPTCHA, Turnstile, and image CAPTCHAs in Kotlin using Captcha AI's HTTP API with Ok Http, Ktor client, and coroutines.

Complete guide to solving re CAPTCHA, Turnstile, and image CAPTCHAs in Kotlin using Captcha AI's HTTP API with...

Automation reCAPTCHA v2 Cloudflare Turnstile
Mar 06, 2026
Tutorials CAPTCHA Handling in Flask Applications with CaptchaAI
Integrate Captcha AI into Flask applications for automated CAPTCHA solving.

Integrate Captcha AI into Flask applications for automated CAPTCHA solving. Includes service class, API endpoi...

Automation Cloudflare Turnstile
Mar 17, 2026
Tutorials Streaming Batch Results: Processing CAPTCHA Solutions as They Arrive
Process CAPTCHA solutions the moment they arrive instead of waiting for tasks to complete — use async generators, event emitters, and callback patterns for stre...

Process CAPTCHA solutions the moment they arrive instead of waiting for all tasks to complete — use async gene...

Automation Python All CAPTCHA Types
Apr 07, 2026