Skip to content

Node.js SDK

Verified v2.0.0· 2026-05-28

Официальная библиотека CaptchaSonic для Node.js и TypeScript — современная, на основе Promise, с несколькими транспортами (gRPC / ConnectRPC / HTTP).

CaptchaSonic Node.js SDK (captchasonic) — современная, основанная на Promise и ориентированная на TypeScript библиотека для решения CAPTCHA в больших объёмах. Каждый метод возвращает Promise, поставляется с полными определениями типов и работает через три взаимозаменяемых транспорта: нативный gRPC (самый быстрый, только Node.js), ConnectRPC (работает в Node.js и в браузерах) и обычный HTTP/JSON. Временные ошибки повторяются автоматически с экспоненциальной задержкой.

Работает в Node.js ≥ 18 и в современных браузерах, совместима с Express, Fastify, Next.js, React, Vue и Vite.


Установка

npm install captchasonic
# или
yarn add captchasonic
# или
pnpm add captchasonic

Требования

ТребованиеПримечания
Node.js≥ 18.0.0 (необходимо для транспорта grpc)
Формат модуляES Module — пакет содержит "type": "module"
БраузерЛюбой современный браузер с fetch; используйте транспорт connect или http

Пакет публикуется только как ESM. В ESM-проекте ("type": "module" в package.json или файл .mjs) импортируйте напрямую:

import { CaptchaSonic } from "captchasonic";

Из файла CommonJS загружайте его через динамический import():

// CommonJS (.cjs / "type": "commonjs")
const { CaptchaSonic } = await import("captchasonic");

TIP

Если вы используете TypeScript, установите "module": "NodeNext" (или "ESNext") и "moduleResolution": "NodeNext" в tsconfig.json, чтобы встроенные определения типов корректно разрешались.


Аутентификация

Создайте API-ключ в панели CaptchaSonic и передайте его первым аргументом конструктора:

import { CaptchaSonic } from "captchasonic";

const solver = new CaptchaSonic("YOUR_API_KEY");

Никогда не храните ключи в системе контроля версий. Считывайте ключ из окружения:

import { CaptchaSonic } from "captchasonic";

const solver = new CaptchaSonic(process.env.CAPTCHASONIC_API_KEY);

Быстрый старт

У каждого типа captcha есть отдельный помощник solve*, который отправляет задачу и возвращает результат. Для задач с изображениями отдельного шага опроса не требуется — SDK делает это за вас.

import { CaptchaSonic } from "captchasonic";

const solver = new CaptchaSonic(process.env.CAPTCHASONIC_API_KEY);

const result = await solver.solveRecaptchaV2({
  images: tiles,            // Uint8Array[] | Buffer[] | file-path[]
  question: "traffic lights",
});

// Выбор по сетке возвращается как индексы плиток
console.log(result.typedSolution?.grid?.objects); // напр. [2, 4, 7]

Возвращает: методы для изображений возвращают результат, ответ которого находится в typedSolution (здесь typedSolution.grid.objects — индексы выбранных плиток); методы на основе токена возвращают токен в карте solution.

TIP

Методы на основе токена (Turnstile, Cloudflare, токен reCAPTCHA v2/v3, токен popular-captcha) отправляют задачу автоматизации браузера и опрашивают результат внутри, пока токен не будет готов — по умолчанию до 120 секунд.


Поддерживаемые типы captcha

Все методы для изображений принимают единый типизированный объект параметров. Изображения могут быть Uint8Array, Node Buffer или строкой с путём к файлу (пути к файлам поддерживаются только в Node.js).

reCAPTCHA v2 (изображение)

await solver.solveRecaptchaV2({
  images: tiles,                 // обычно 9 плиток для сетки 3×3
  question: "traffic lights",    // обычный текст или код класса Google, напр. "/m/015qff"
});
// → result.typedSolution.grid.objects  (number[] — индексы выбранных плиток)

PopularCaptcha (изображение в стиле hCaptcha)

await solver.solvePopularCaptcha({
  images: tiles,                 // 1–64 плитки
  question: "Click each image with a cat",
  questionType: "objectClassify", // "objectClassify" | "grid" | "objectClick" | "objectDrag"
  examples,                      // необязательные эталонные изображения для objectClick
  websiteURL: "https://example.com",
});
// objectClassify/grid → typedSolution.grid.objects
// objectClick        → typedSolution.click
// objectDrag         → typedSolution.drag

GeeTest

// сетка из девяти (требуются question и images)
await solver.solveGeetest({ type: "nine", question: "Select all bicycles", images: tiles });

// click / icon (требуются question и images)
await solver.solveGeetest({ type: "click", question: "the bear", images: tiles });

// слайд-пазл (фрагмент + фон)
await solver.solveGeetest({ type: "slide", images: [piece], examples: [background] });

// пазлы с перестановкой
await solver.solveGeetest({ type: "match" });
await solver.solveGeetest({ type: "winlinze" });

Возвращает: типы grid/click попадают в typedSolution.grid.objects (или typedSolution.click); slide возвращает typedSolution.slide.x.

Допустимые псевдонимы type:

КаноническоеПсевдонимы
nine-grid"nine", "geetest_nine", "9"
click / icon"click", "geetest_click", "icon"
slide"slide", "geetest_slide"
match"match", "geetest_match"
winlinze"winlinze", "geetest_winlinze"

OCR / изображение-в-текст

await solver.solveOcr({ images: [img] });                                  // общий OCR
await solver.solveOcr({ images: [img], module: "mtcaptcha", maxLength: 4 });
await solver.solveOcr({ images: imgs, module: "bls", numeric: true, maxLength: 3 });
// → result.typedSolution.text.texts[0]
ПараметрТипПримечания
module"common" | "mtcaptcha" | "bls" | "morocco"По умолчанию "common"
numericbooleanТолько цифры (автоматически для "bls")
caseSensitivebooleanСохранять регистр букв
minLength / maxLengthnumberГраницы длины

TikTok

await solver.solveTikTok({ type: "click", question: "Select the shape", images });
await solver.solveTikTok({ type: "whirl", question: "Rotate to match", images, examples }); // examples обязательны
await solver.solveTikTok({ type: "slide", question: "Slide to fit", images, examples });    // examples обязательны

Возвращает: click попадает в typedSolution.click; whirl/slide возвращают typedSolution.slide.x.

type принимает "click"/"tiktok_click", "whirl"/"tiktok_whirl", "slide"/"tiktok_slide".

Binance

await solver.solveBinance({ type: "grid", question: "Select the bicycle", images });
await solver.solveBinance({ type: "slide", images: [puzzle], examples: [background] });

Возвращает: grid попадает в typedSolution.grid.objects; slide возвращает typedSolution.slide.x.

type принимает "grid"/"binance_grid" и "slide"/"binance_slide".

AWS WAF

solveAwsWaf принимает позиционные аргументы. question форматируется как "type:category:target".

await solver.solveAwsWaf(tiles, "grid:vehicles:cars");

Возвращает: индексы выбранных плиток в typedSolution.grid.objects.

Слайд-изображение (локально, без ИИ)

Определяет смещение слайда локально с помощью обнаружения контуров. Принимает одно объединённое изображение или [background, piece].

const r = await solver.solveSlideImage({ images: ["slide_bg.png", "piece.png"] });
console.log(r.typedSolution?.slide?.x); // смещение в пикселях, напр. 142

Возвращает: смещение слайда в пикселях в typedSolution.slide.x.

Методы на основе токена (автоматизация браузера)

Эти методы отправляют задачу и опрашивают результат внутри, пока не будет получен токен (до таймаута опроса, по умолчанию 120 с).

await solver.solveTurnstile({ websiteURL, websiteKey, proxy });          // proxy необязателен
await solver.solveRecaptchaV2Token({ websiteURL, websiteKey, proxy });   // proxy необязателен
await solver.solveRecaptchaV3Token({ websiteURL, websiteKey, proxy });   // proxy необязателен
await solver.solvePopularCaptchaToken({ websiteURL, websiteKey, proxy, metadata }); // proxy необязателен
await solver.solveCloudflare({ websiteURL, websiteKey, proxy });         // proxy ОБЯЗАТЕЛЕН

Возвращает: токен в карте solution ответа (например, result.solution.token или result.solution.gRecaptchaResponse, в зависимости от captcha).


Использование с TypeScript

SDK экспортирует типы для каждого объекта параметров и для ответов. Импортируйте их через import type.

import { CaptchaSonic } from "captchasonic";
import type { SolveGeetestOptions, GetTaskResultResponse } from "captchasonic";

const solver = new CaptchaSonic(process.env.CAPTCHASONIC_API_KEY!);

const opts: SolveGeetestOptions = {
  type: "nine",
  question: "Select all bicycles",
  images: tiles,
};

const result = await solver.solveGeetest(opts);
console.log(result.typedSolution?.grid?.objects);

Экспортируемые типы

import type {
  CaptchaSonicOptions,
  ImageInput,
  SolvePopularCaptchaOptions,
  SolveRecaptchaV2Options,
  SolveGeetestOptions,
  SolveOcrOptions,
  SolveTikTokOptions,
  SolveBinanceOptions,
  SolveTurnstileOptions,
  SolvePopularCaptchaTokenOptions,
  SolveRecaptchaV2TokenOptions,
  SolveRecaptchaV3TokenOptions,
  SolveCloudflareOptions,
  SolveSlideImageOptions,
  GeetestSubtype,
  TikTokSubtype,
  BinanceSubtype,
  Task,
  CreateTaskResponse,
  GetTaskResultResponse,
} from "captchasonic";

ImageInput — это Uint8Array | Buffer | string.


Поддержка прокси

Методы на основе токена / автоматизации браузера принимают необязательную строку proxy в формате http://user:pass@host:port:

await solver.solveTurnstile({
  websiteURL: "https://example.com",
  websiteKey: "0x4AAAAAAA...",
  proxy: "http://user:[email protected]:8080",
});

WARNING

solveCloudflare всегда требует прокси — поле proxy для этого метода обязательно. Остальные методы на основе токена работают без прокси, если proxy опущен.

Для корпоративного hCaptcha можно также передать metadata (rqdata, rqtoken, fingerprint) в solvePopularCaptchaToken.


Конфигурация

Передайте объект параметров вторым аргументом конструктора. Поддерживаются только перечисленные ниже параметры.

const solver = new CaptchaSonic("YOUR_API_KEY", {
  transport: "connect",   // "grpc" (по умолчанию) | "connect" | "http"
  timeout: 180_000,       // макс. время ожидания опроса в мс (псевдоним: timeoutMs); по умолчанию на вызов 30000
  pollingInterval: 5_000, // частота опроса в мс (по умолчанию 2000)
  baseUrl: "https://api.captchasonic.com", // переопределение endpoint (псевдоним: url)
});
ПараметрТипПо умолчаниюОписание
transport"grpc" | "connect" | "http""grpc"Сетевой протокол (см. таблицу ниже)
timeout / timeoutMsnumber30000 на вызовТаймаут запроса; timeout также ограничивает время ожидания опроса
pollingIntervalnumber2000Как часто опрашиваются задачи с токеном
url / baseUrlstringзависит от транспортаПереопределение endpoint API

Транспорты

ТранспортОкруженияПротокол
grpcТолько Node.jsБинарный gRPC поверх HTTP/2 — наименьшая задержка, отправляет изображения как сырые бинарные данные
connectNode.js и браузерыConnectRPC поверх fetch
httpNode.js и браузерыОбычный REST/JSON поверх fetch

TIP

В браузере используйте connect (рекомендуется) или http. Нативный gRPC требует Node.js. С connect/http изображения автоматически кодируются в base64 перед отправкой; с grpc они отправляются как сырые бинарные данные без накладных расходов.


Обработка ошибок

Все сбои на уровне API выбрасывают SonicError, расширяющий встроенный Error. Он содержит числовой errorId и устанавливает name в соответствующее имя ошибки.

import { CaptchaSonic, SonicError } from "captchasonic";

try {
  const result = await solver.solveGeetest({ type: "nine", question: "bicycles", images });
} catch (err) {
  if (err instanceof SonicError) {
    console.error(err.errorId); // 1–6
    console.error(err.name);    // напр. "InvalidApiKeyError"
    console.error(err.message);
  } else {
    throw err; // сеть / непредвиденная
  }
}
errorIdnameПричинаДействие
1InvalidApiKeyErrorAPI-ключ отсутствует или недействителенПроверьте ключ в панели управления
2InsufficientBalanceErrorНедостаточно кредитовПополните баланс
3DailyLimitExceededErrorПревышена дневная квотаДождитесь сброса или повысьте тариф
4MinuteLimitExceededErrorДостигнут лимит запросов в минутуСделайте паузу и повторите позже
5QuotaExceededErrorКвота тарифа исчерпанаОбновите тариф
6PlanExpiredErrorПодписка истеклаПродлите подписку

TIP

Временные ошибки gRPC повторяются автоматически с экспоненциальной задержкой (до 3 попыток), поэтому обычно достаточно обрабатывать только перечисленные выше случаи SonicError.


Вспомогательные методы аккаунта

const balance = await solver.getBalance(); // → number (USD)

const health = await solver.healthCheck(); // → { healthy: boolean, version: string }

Низкоуровневые методы для задач доступны, если нужен прямой контроль над отправкой и опросом:

const created = await solver.createTask(task);        // отправить Partial<Task>
const result  = await solver.getTaskResult(taskId);   // опросить результат

Устранение неполадок

require is not defined / Cannot use import statement outside a module — пакет только ESM. Используйте import в ESM-проекте или await import("captchasonic") из CommonJS. См. Установка.

Транспорт grpc не работает в браузере — нативный gRPC доступен только в Node.js. Переключитесь на transport: "connect" или transport: "http".

InvalidApiKeyError при каждом вызове — убедитесь, что ключ передан первым аргументом конструктора и не равен undefined (например, из-за отсутствующей переменной окружения).

Метод на основе токена истекает по таймауту — задачи с токеном опрашиваются до timeout мс (по умолчанию 120000). Увеличьте timeout и проверьте, что websiteURL / websiteKey совпадают с целевой страницей. Для Cloudflare требуется действительный proxy.

Изображения по пути к файлу не загружаются — пути к файлам читаются синхронно и доступны только в Node.js; в браузере передавайте Uint8Array.


Ресурсы