API Tutorials

Как решить reCAPTCHA v2 Enterprise с помощью Node.js

На стороне клиента обычная reCAPTCHA v2 и её Enterprise-версия выглядят одинаково: тот же флажок «Я не робот», тот же виджет. Разница — в бэкенде: Google Enterprise проверяет токен строже и учитывает дополнительный контекст запроса. Для интеграции с CaptchaAI это означает ровно одно изменение — параметр enterprise=1 в запросе к in.php. Всё остальное в вашем Node.js-коде остаётся прежним.

Ниже — рабочая схема целиком:

  • как отличить Enterprise-виджет от обычного;
  • как отправить задачу и опросить результат;
  • что делать с полученным токеном и с ошибками.

Обычная v2 и Enterprise: что реально меняется

Граница между версиями проходит не по вёрстке, а по проверке токена на бэкенде.

Что сравниваем reCAPTCHA v2 reCAPTCHA v2 Enterprise
Виджет на странице флажок «Я не робот» тот же флажок
Путь anchor-запроса /recaptcha/api2/anchor /recaptcha/enterprise/anchor
Скрипт api.js enterprise.js
Параметр action (sa=) обычно отсутствует часто задан
Флаг в запросе к in.php не нужен enterprise=1
Привязка к User-Agent мягкая жёсткая

Вывод: код переиспользуется целиком, внимания требуют два места — тип виджета и User-Agent.


Что понадобится перед стартом

Требование Подробности
API-ключ CaptchaAI captchaai.com
Node.js 14+ Встроенный fetch или пакет node-fetch.
sitekey Параметр k= из anchor-URL Enterprise.
URL страницы Полный адрес страницы, где показывается проверка.
action (необязательно) Параметр sa= из того же anchor-URL.

Порядок подготовки:

  1. Скопируйте API-ключ из панели управления.
  2. Проверьте версию Node.js: node -v — 14 или выше.
  3. Снимите k= и sa= из anchor-URL целевой страницы.
  4. Убедитесь, что план активен и потоков хватает.

Тарификация идёт по потокам, а не по числу решений: BASIC ($15/мес, 5 потоков) закрывает одиночный скрипт, ADVANCE ($90/мес, 50 потоков) — параллельную очередь. Поток — это одна задача «в полёте». Цены в USD.


Шаг 1: определите, что перед вами именно Enterprise

Откройте DevTools, вкладку «Сеть», и найдите запрос anchor:

https://www.google.com/recaptcha/enterprise/anchor?ar=1&k=6LdxxXXxAAAAAAcX...&sa=LOGIN&...

На что смотреть:

  • Скрипт на странице подключается как /recaptcha/enterprise.js, а путь запроса содержит /enterprise/anchor.
  • Значение параметра k= — это sitekey.
  • Значение sa= (если параметр присутствует) — это action.
  • Обычная v2 запрашивает /recaptcha/api2/anchor — для неё enterprise=1 передавать не нужно, иначе целевая форма токен не примет.

Шаг 2: отправьте задачу в CaptchaAI

const API_KEY = "YOUR_API_KEY";

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

  if (action) {
    params.set("action", action);
  }

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

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

  console.log(`Task submitted. ID: ${data.request}`);
  return data.request;
}
  • Метод остаётся userrecaptcha: отдельного метода под Enterprise нет, весь переключатель — один флаг.
  • Параметр json: "1" избавляет от разбора текстового формата OK|<id>.
  • status: 1 — задача принята, в request лежит ID.
  • status: 0 — в request код ошибки; повторять запрос без правки параметров бессмысленно.

Шаг 3: опрашивайте результат без спешки

Тайминг опроса:

  • первая проверка — не раньше чем через 20 секунд после отправки;
  • дальше — каждые 5 секунд, до 30 попыток.
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function pollResult(taskId) {
  await delay(20000);

  for (let attempt = 0; attempt < 30; attempt++) {
    const params = new URLSearchParams({
      key: API_KEY,
      action: "get",
      id: taskId,
      json: "1",
    });

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

    if (data.status === 1) {
      console.log(`Solved. Token: ${data.request.substring(0, 60)}...`);
      return {
        token: data.request,
        userAgent: data.user_agent || "",
      };
    }

    if (data.request !== "CAPCHA_NOT_READY") {
      throw new Error(`Solve failed: ${data.request}`);
    }

    console.log(`Attempt ${attempt + 1}: not ready, waiting 5s...`);
    await delay(5000);
  }

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

CAPCHA_NOT_READY означает «ещё в работе» и ошибкой не является. Поле user_agent для Enterprise критично — к нему вернёмся в разборе ошибок.

Ветвление в цикле:

  1. status: 1 — забирайте токен из request и выходите.
  2. request: CAPCHA_NOT_READY — ждите 5 секунд и опрашивайте снова.
  3. Любое другое значение — исключение, попытки не тратьте.

Шаг 4: подставьте токен в запрос

Два правила подстановки:

  • решённое значение уходит в поле g-recaptcha-response;
  • если в ответе был user_agent, тот же User-Agent ставьте в заголовки запроса.
async function submitForm(token, userAgent) {
  const headers = { "Content-Type": "application/x-www-form-urlencoded" };

  if (userAgent) {
    headers["User-Agent"] = userAgent;
  }

  const response = await fetch("https://example.com/api/login", {
    method: "POST",
    headers,
    body: new URLSearchParams({
      username: "user",
      password: "pass",
      "g-recaptcha-response": token,
    }),
  });

  console.log(`Response status: ${response.status}`);
  return response;
}

Токен одноразовый и живёт около двух минут — запрашивайте решение непосредственно перед отправкой формы.


Полный скрипт целиком

const API_KEY = "YOUR_API_KEY";
const SITE_KEY = "6LdxxXXxAAAAAAcXxxXxxX91xxxxxxxx8xxOx7A";
const PAGE_URL = "https://staging.example.com/qa-login";
const ACTION = "LOGIN"; // optional — omit if not in anchor URL

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

async function solveRecaptchaV2Enterprise() {
  // Submit task
  const submitParams = new URLSearchParams({
    key: API_KEY,
    method: "userrecaptcha",
    googlekey: SITE_KEY,
    pageurl: PAGE_URL,
    enterprise: "1",
    action: ACTION,
    json: "1",
  });

  const submitRes = await fetch(
    `https://ocr.captchaai.com/in.php?${submitParams}`
  );
  const submitData = await submitRes.json();

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

  const taskId = submitData.request;
  console.log(`Task ID: ${taskId}`);

  // Poll for result
  await delay(20000);

  for (let i = 0; i < 30; i++) {
    const pollParams = new URLSearchParams({
      key: API_KEY,
      action: "get",
      id: taskId,
      json: "1",
    });

    const pollRes = await fetch(
      `https://ocr.captchaai.com/res.php?${pollParams}`
    );
    const pollData = await pollRes.json();

    if (pollData.status === 1) {
      return {
        token: pollData.request,
        userAgent: pollData.user_agent || "",
      };
    }

    if (pollData.request !== "CAPCHA_NOT_READY") {
      throw new Error(`Solve error: ${pollData.request}`);
    }

    await delay(5000);
  }

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

(async () => {
  const { token, userAgent } = await solveRecaptchaV2Enterprise();
  console.log(`Token: ${token.substring(0, 60)}...`);
  if (userAgent) console.log(`User-Agent: ${userAgent}`);
})();

Ожидаемый вывод в консоли

Task ID: 73849562810
Token: 03AGdBq24PBCqLmOx2V4pGHJjkR2xZ1r...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...

Разбор ошибок

Самая частая жалоба — «токен получен, но форма его не принимает». Почти всегда это несовпадение User-Agent: Enterprise-токен привязан к окружению, в котором был получен.

Ошибка Причина Что делать
ERROR_WRONG_USER_KEY Неверный формат ключа. Проверьте, что ключ из панели управления скопирован целиком — это 32 символа.
ERROR_KEY_DOES_NOT_EXIST Ключ не найден. Сверьте значение с аккаунтом на captchaai.com.
ERROR_ZERO_BALANCE Баланс исчерпан. Пополните баланс или проверьте срок действия плана.
ERROR_BAD_TOKEN_OR_PAGEURL Неверный sitekey или URL страницы. Возьмите значение k= заново из anchor-URL Enterprise.
ERROR_CAPTCHA_UNSOLVABLE Задачу решить не удалось. Убедитесь, что виджет действительно Enterprise v2, и повторите попытку.
Сайт отклоняет токен Несовпадение User-Agent. Подставьте user_agent из ответа res.php в заголовки запроса.

Сценарий: Enterprise-логин на staging перед релизом

Типичная задача для команды в Алматы или Минске: перед выкаткой нужно прогнать сотню регрессионных сценариев авторизации, а на форме входа стоит reCAPTCHA v2 Enterprise, и отключить её на staging нельзя. Скрипт выше встраивается в фикстуру подготовки сессии: один вызов на прогон.

Арифметика: сто прогонов по ~25 секунд при 5 потоках — это 8–9 минут ожидания на пачку, на 50 потоках — меньше минуты, и узким местом становится запуск браузеров. На нестабильном канале увеличивайте число попыток опроса, а не интервал.

Оговорка для тех, кто собирает данные с форм: обрабатывайте только то, что вы вправе обрабатывать — в РФ ориентир 152-ФЗ «О персональных данных», для трансграничных проектов подход в духе GDPR. Это не юридическая консультация.


Частые вопросы

Чем enterprise=1 отличается от отдельного метода API?

Ничем, кроме флага: метод остаётся userrecaptcha. Переход с обычной v2 на Enterprise стоит одной строки кода.

Нужно ли передавать action, если на странице его нет?

Нет. Если в anchor-URL отсутствует параметр sa=, поле action просто не отправляйте. Пустое или выдуманное значение ухудшит проверку токена на стороне сайта.

Работает ли этот подход с Puppeteer и Playwright?

Да. Со страницы снимается sitekey, задача уходит в API, токен записывается в скрытое поле через document.getElementById('g-recaptcha-response').innerHTML.

Сколько потоков брать под ночной CI-прогон?

Считайте по параллельности, а не по общему числу задач:

  • один скрипт или разовый прогон — BASIC ($15/мес, 5 потоков);
  • пятнадцать параллельных джобов — STANDARD ($30/мес, 15 потоков);
  • полсотни — ADVANCE ($90/мес, 50 потоков).

Количество решений внутри плана не ограничено.

Какие ещё типы проверок закрываются тем же кодом?

Схема «отправил → опросил → подставил» одинакова для всех поддерживаемых типов: Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, reCAPTCHA v3, текстовые и графические проверки. Меняются только method и набор параметров. Учтите, что hCaptcha и FunCaptcha CaptchaAI не решает, а поддержка GeeTest v4 пока только заявлена как скорая.


Что делать дальше

Скопируйте полный скрипт, подставьте YOUR_API_KEY и sitekey со staging-страницы — первый Enterprise-токен придёт за пару минут. Дальше оберните вызов в фикстуру тестов и подберите план по реальной параллельности.


Смежные материалы

Материал О чём
Решение reCAPTCHA v2 Enterprise через API тот же сценарий без привязки к языку
Решение reCAPTCHA v2 Enterprise на Python порт скрипта на Python
Частые ошибки reCAPTCHA v2 Enterprise и их исправление разбор кодов ошибок подробнее
Как распознать reCAPTCHA Enterprise на сайте методика определения типа виджета
Комментарии для этой статьи отключены.