Browser API — это облачный браузер MegaIndex для автоматизации сайтов, которым нужен настоящий браузер: JavaScript-рендеринг, клики, формы, скролл, геозависимый контент и обработка CAPTCHA.

Ваш скрипт подключается к удалённому браузеру по CDP WebSocket URL и управляет им через Playwright, Puppeteer или другой клиент с поддержкой Chrome DevTools Protocol (CDP). Запускать и обслуживать Chrome на своём сервере не требуется.

Для работы Browser API используются два независимых ресурса:

  • browser traffic — трафик облачного браузера, который учитывается MegaIndex в GB;
  • custom proxy — внешний прокси пользователя. MegaIndex не продаёт, не тарифицирует и не учитывает трафик такого прокси.

Новый пользователь получает Default account, Default profile, 1 GB тестового browser traffic и ограниченный бесплатный IPv6 fallback для первоначальной проверки. В текущей реализации fallback также может применяться к другим профилям с proxyMode: "none". Для рабочих подключений используйте собственный прокси.

Что можно делать через Browser API

  • подключаться к удалённому Chrome через CDP;
  • использовать Playwright, Puppeteer и другие CDP-клиенты;
  • создавать browser accounts и отдельные browser profiles;
  • сохранять custom proxy на уровне аккаунта или профиля;
  • передавать custom proxy только для конкретного подключения;
  • автоматически или вручную решать CAPTCHA через CDP-интерфейс Captcha;
  • получать историю и статистику расхода browser traffic;
  • покупать дополнительный browser traffic за баланс MegaIndex.

Основные термины

Browser account — основная учётная запись облачного браузера. Она содержит browser login, browser password и общие настройки подключения.

Browser profile — отдельная браузерная среда внутри browser account. Для параллельных процессов используйте разные профили.

Default account — browser account с именем Default browser account, автоматически доступный новому пользователю.

Default profile — начальный профиль Default account.

Browser traffic — трафик, переданный облачным браузером. Он приобретается и учитывается отдельно от трафика пользовательского прокси.

Custom proxy — внешний HTTP, HTTPS, SOCKS4 или SOCKS5 прокси пользователя.

CDP URL / connectionUri — WebSocket URL с данными доступа для подключения к облачному браузеру.

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

1. Проверьте тестовые ресурсы

При первом подключении пользователю доступны:

  • Default account;
  • Default profile;
  • 1 GB тестового browser traffic;
  • ограниченный бесплатный IPv6 fallback.

Этого достаточно, чтобы проверить CDP-подключение без предварительной покупки browser traffic и настройки собственного прокси.

IPv6 fallback предназначен только для знакомства с сервисом. Некоторые сайты не поддерживают IPv6, блокируют такой трафик или показывают другой контент. Для рабочего сценария настройте custom proxy.

2. Получите готовый CDP URL

Используйте CDP URL Default profile из интерфейса либо запросите connectionUri через публичный API.

Не публикуйте connectionUri: он содержит данные доступа к браузеру.

3. Подключитесь через Playwright

Установите Playwright:

npm install playwright

Сохраните CDP URL в переменную окружения:

export MEGAINDEX_BROWSER_CDP_URL="PASTE_CDP_URL_HERE"

Создайте файл quick-start.js:

const { chromium } = require('playwright');

async function main() {
  const connectionUri = process.env.MEGAINDEX_BROWSER_CDP_URL;

  if (!connectionUri) {
    throw new Error('MEGAINDEX_BROWSER_CDP_URL is not set');
  }

  const browser = await chromium.connectOverCDP(connectionUri);
  const context = browser.contexts()[0];
  const page = await context.newPage();

  await page.goto('https://example.com', {
    waitUntil: 'networkidle',
    timeout: 60_000,
  });

  console.log(await page.title());
  await page.screenshot({ path: 'browser-api-test.png', fullPage: true });
  await browser.close();
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Запустите пример:

node quick-start.js

4. Подключитесь через Puppeteer

Установите Puppeteer Core:

npm install puppeteer-core
const puppeteer = require('puppeteer-core');

async function main() {
  const connectionUri = process.env.MEGAINDEX_BROWSER_CDP_URL;

  if (!connectionUri) {
    throw new Error('MEGAINDEX_BROWSER_CDP_URL is not set');
  }

  const browser = await puppeteer.connect({
    browserWSEndpoint: connectionUri,
  });

  const page = await browser.newPage();
  await page.goto('https://example.com', {
    waitUntil: 'networkidle2',
    timeout: 60_000,
  });

  console.log(await page.title());
  await browser.disconnect();
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

5. Перейдите на custom proxy

Для рабочего подключения добавьте собственный прокси на уровне browser account, browser profile или запроса connection.

MegaIndex не учитывает proxy traffic. Его стоимость, лимиты, география и доступность определяются провайдером вашего прокси.

Публичный HTTP API

Base URL

Текущий тестовый endpoint:

http://89.108.119.8/test-browser-api/browser.php

Далее в примерах используется переменная:

BASE_URL="http://89.108.119.8/test-browser-api/browser.php"

Авторизация

Для запросов используется API key пользователя MegaIndex. Получить или перевыпустить его можно на странице:

/profile/api-key

После перевыпуска старый ключ перестаёт работать.

Ключ поддерживается в четырёх форматах.

Query string:

curl "$BASE_URL?method=accounts&key=YOUR_API_KEY"

JSON body:

curl -X POST "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{"method":"connection","key":"YOUR_API_KEY","accountId":123}'

Заголовок X-API-Key:

curl "$BASE_URL?method=accounts" \
  -H "X-API-Key: YOUR_API_KEY"

Bearer token:

curl "$BASE_URL?method=accounts" \
  -H "Authorization: Bearer YOUR_API_KEY"

Bearer-аутентификация подтверждена фактическим запросом: корректный ключ в заголовке Authorization возвращает 200 OK и обычный ответ выбранного метода.

Не размещайте API key во frontend-коде, публичных репозиториях, скриншотах и логах.

Формат запросов

Операция передаётся в параметре method. Технически также поддерживаются endpoint и action, но для единообразия используйте method.

Для JSON-запросов передавайте:

Content-Type: application/json

Методы

method HTTP Назначение
prices GET Получить стоимость browser traffic с учётом объёма покупки.
accounts GET, POST, PUT, DELETE Управлять browser accounts.
profiles GET, POST, PUT, DELETE Управлять browser profiles.
connection GET, POST Получить WebSocket URI для CDP-подключения.
history GET Получить историю операций Browser API.
statistics GET Получить статистику использования browser traffic.
buy POST Купить browser traffic за баланс MegaIndex.

Алиасы stats, buy-traffic и traffic-buy поддерживаются для совместимости. В новой интеграции используйте основные названия методов.

Browser traffic и оплата

Что учитывает MegaIndex

MegaIndex учитывает только browser traffic — сетевой трафик облачного браузера. Он измеряется в GB и расходуется независимо от трафика custom proxy.

Custom proxy принадлежит пользователю. MegaIndex не показывает его остаток, не списывает за него деньги и не контролирует тариф прокси-провайдера.

Практически это означает, что во время рабочего подключения могут одновременно расходоваться:

  1. browser traffic в MegaIndex;
  2. proxy traffic у внешнего провайдера.

Получить цены

curl "$BASE_URL?method=prices&key=YOUR_API_KEY"

С явным указанием валюты:

curl "$BASE_URL?method=prices&currency=usd&key=YOUR_API_KEY"

Ответ содержит массив ценовых диапазонов:

[
  {
    "from": 1,
    "to": 9,
    "price": 5,
    "discount": 0,
    "oldPrice": 5,
    "currency": "usd"
  },
  {
    "from": 10,
    "to": 29,
    "price": 4,
    "discount": 20,
    "oldPrice": 5,
    "currency": "usd"
  },
  {
    "from": 10000,
    "to": 0,
    "price": 1.4,
    "discount": 72,
    "oldPrice": 5,
    "currency": "usd"
  }
]

Поля диапазона:

Поле Тип Описание
from integer Минимальный объём покупки в GB, включительно.
to integer Максимальный объём в GB, включительно. Значение 0 означает отсутствие верхней границы.
price number Цена одного GB после применения объёмной скидки.
oldPrice number Базовая цена одного GB без скидки.
discount number Скидка относительно базовой цены, в процентах. Может быть дробной.
currency string Валюта цены. В подтверждённом ответе используется usd.

При покупке API автоматически выбирает ценовой диапазон по значению flow. Например, при покупке от 10 до 29 GB применяется цена 4 USD за GB, а для покупки от 10000 GB — 1.4 USD за GB.

Купить browser traffic

curl -X POST "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "buy",
    "key": "YOUR_API_KEY",
    "flow": 10,
    "idempotencyKey": "browser-traffic-order-1001"
  }'

Параметры:

Поле Тип Обязательное Описание
flow integer да Покупаемое количество GB. Текущий допустимый диапазон: от 1 до 100000.
idempotencyKey string да Уникальный ключ операции, защищающий от повторного списания.

Для повторной отправки того же заказа используйте тот же idempotencyKey. Для новой покупки создайте новый ключ.

Пример ответа:

{
  "status": "OK",
  "flow": 10,
  "financeId": 23082035,
  "price": {
    "amount": 50,
    "pricePerGb": 5,
    "oldPrice": 5,
    "discount": 0,
    "currency": "usd"
  },
  "balance": {
    "before": 100,
    "after": 50,
    "currency": "usd"
  },
  "traffic": {
    "totalKb": 10485760,
    "usedKb": 0,
    "availableKb": 10485760,
    "totalGb": 10,
    "usedGb": 0,
    "availableGb": 10
  }
}

В успешном ответе:

  • flow — купленный объём в GB;
  • financeId — ID финансовой операции MegaIndex;
  • price.amount — полная стоимость покупки;
  • price.pricePerGb — применённая цена одного GB;
  • balance.before и balance.after — баланс до и после списания;
  • traffic — обновлённый общий, использованный и доступный browser traffic в KB и GB.

Подтверждённое соотношение: 1 GB = 1048576 KB.

Если запрос с тем же idempotencyKey уже был обработан, деньги повторно не списываются:

{
  "status": "OK",
  "duplicate": true,
  "flow": 10,
  "financeId": 23082035,
  "price": {
    "amount": 50,
    "pricePerGb": 5,
    "oldPrice": 5,
    "discount": 0,
    "currency": "usd"
  },
  "balance": {
    "current": 50,
    "currency": "usd"
  }
}

В повторном ответе:

  • duplicate: true подтверждает, что операция уже была обработана;
  • financeId совпадает с ID первоначальной покупки;
  • повторного списания и начисления browser traffic не происходит;
  • вместо balance.before/balance.after возвращается balance.current;
  • блок traffic отсутствует.

Если начисление browser traffic не завершилось, списание с баланса MegaIndex откатывается.

Browser accounts

Получить список аккаунтов

curl "$BASE_URL?method=accounts&key=YOUR_API_KEY"

Сокращённый пример ответа:

{
  "status": "OK",
  "project": {
    "id": 2,
    "code": "megaindex",
    "name": "MegaIndex"
  },
  "count": 1,
  "maxAccounts": 10,
  "unlimitedAccounts": false,
  "data": [
    {
      "id": 123,
      "login": "REDACTED_BROWSER_LOGIN",
      "password": "REDACTED_BROWSER_PASSWORD",
      "name": "Default browser account",
      "status": 1,
      "country": "en",
      "defaultProfileId": 456,
      "proxyMode": "none",
      "customProxy": null,
      "profile": {
        "id": 456,
        "accountId": 123,
        "profileId": "p0123456789abcdef0123456789abcdef",
        "isDefault": true,
        "name": "Default profile",
        "proxyMode": "inherit",
        "usedKb": 1075,
        "usedGb": 0.001,
        "requestCount": 8,
        "status": 1
      },
      "profilesCount": 1,
      "usedKb": 1075,
      "usedGb": 0.001,
      "requestCount": 8,
      "maxProfiles": 1000,
      "unlimitedProfiles": false,
      "connection": {
        "host": "browser.example.com:9222",
        "username": "REDACTED_USERNAME",
        "password": "REDACTED_BROWSER_PASSWORD",
        "profileId": "p0123456789abcdef0123456789abcdef"
      },
      "connectionUri": "REDACTED_CONNECTION_URI",
      "createdAt": "2026-07-23 17:53:21",
      "updatedAt": "2026-07-23 17:53:21"
    }
  ]
}

Важные поля:

  • count — текущее количество browser accounts;
  • maxAccounts — максимальное количество accounts, по умолчанию 10;
  • unlimitedAccounts — отключён ли количественный лимит;
  • defaultProfileId — числовой внутренний ID записи Default profile;
  • profile.profileId — строковый ID профиля, используемый при получении connectionUri и в CDP URL;
  • profilesCount и maxProfiles — текущее и максимальное количество профилей account;
  • usedKb, usedGb и requestCount — суммарная статистика account;
  • profile.isDefault: true — признак Default profile;
  • profile.proxyMode: "inherit" — профиль наследует прокси-настройки account.

Не путайте числовой profile.id и строковый profile.profileId. Для connection используйте строковый profileId.

Ответ также содержит служебные объекты project, serviceUser, proxySettings и подробный объект connection. Их не нужно изменять на стороне клиента.

Создать аккаунт

Browser account можно создать без сохранённого прокси. В этом случае custom proxy нужно сохранить позднее либо передать при получении connectionUri. Ограниченный IPv6 fallback доступен только для первоначального теста.

curl -X POST "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "accounts",
    "key": "YOUR_API_KEY",
    "name": "Main browser account"
  }'

Успешный ответ содержит status, project и созданный объект account. Вместе с account автоматически создаётся Default profile:

  • account.proxyMode имеет значение none;
  • account.customProxy имеет значение null;
  • profile.isDefault имеет значение true;
  • profile.name имеет значение Default profile;
  • profile.proxyMode имеет значение inherit;
  • account.defaultProfileId совпадает с числовым profile.id;
  • статистика нового account/profile начинается с нулевых значений;
  • profile.lastUsedAt до первого использования является пустой строкой.

При стандартном лимите можно создать до 10 accounts. Каждый account может содержать до 1000 profiles. Фактические ограничения возвращаются в maxAccounts, unlimitedAccounts, maxProfiles и unlimitedProfiles.

Поле name задаёт отображаемое имя browser account и возвращается в account.name.

Изменить, обновить пароль и удалить аккаунт

Метод accounts поддерживает PUT и DELETE.

Удаление account:

curl -X DELETE "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "accounts",
    "key": "YOUR_API_KEY",
    "id": 123
  }'

Успешный ответ:

{
  "status": "OK",
  "project": {
    "id": 2,
    "code": "megaindex",
    "name": "MegaIndex"
  }
}

Browser profiles

Получить список профилей

curl "$BASE_URL?method=profiles&accountId=123&page=1&limit=50&key=YOUR_API_KEY"

Параметры:

Параметр Тип Обязательный Описание
accountId integer да Числовой ID browser account.
page integer нет Номер страницы, начиная с 1.
limit integer нет Максимальное количество профилей на странице.

Сокращённый пример ответа:

{
  "status": "OK",
  "project": {
    "id": 2,
    "code": "megaindex",
    "name": "MegaIndex"
  },
  "maxProfiles": 1000,
  "unlimitedProfiles": false,
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "pages": 1
  },
  "data": [
    {
      "id": 456,
      "accountId": 123,
      "profileId": "p0123456789abcdef0123456789abcdef",
      "isDefault": true,
      "name": "Default profile",
      "zone": "scraping_browser",
      "country": "en",
      "proxyMode": "none",
      "customProxy": null,
      "profileData": {
        "comment": ""
      },
      "usedKb": 4677,
      "usedGb": 0.0045,
      "requestCount": 26,
      "status": 1,
      "source": "frontend_auto",
      "connectionUri": "REDACTED_CONNECTION_URI",
      "createdAt": "2026-08-05 10:34:49",
      "updatedAt": "2026-08-05 14:48:02",
      "lastUsedAt": "2026-08-05 14:48:02",
      "deletedAt": ""
    }
  ]
}

Объект pagination содержит текущую страницу, установленный лимит, общее количество профилей и количество страниц.

Признак isDefault: true означает, что профиль является Default profile своего account. Это не определяет режим прокси: Default profile может возвращаться как с proxyMode: "inherit", так и с proxyMode: "none", в зависимости от настроек и способа создания account/profile.

Поля connection и connectionUri содержат данные подключения. Не публикуйте и не записывайте их в открытые логи.

Создать профиль

curl -X POST "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "profiles",
    "key": "YOUR_API_KEY",
    "accountId": 123,
    "name": "Google SERP checks"
  }'

Для параллельных CDP-подключений используйте разные профили.

Поле name задаёт отображаемое имя профиля и возвращается в profile.name. Строковое поле profileId применяется во внешнем API и CDP URL, а числовое id является внутренним ID записи.

Успешное создание пользовательского профиля возвращает status, project и объект profile. Новый профиль:

  • получает сгенерированные сервером числовой id и строковый profileId;
  • имеет isDefault: false;
  • по умолчанию использует proxyMode: "inherit";
  • начинает с нулевых usedKb, usedGb и requestCount;
  • имеет source: "frontend";
  • до первого подключения имеет пустой lastUsedAt.

Для сравнения, автоматически созданный Default profile имеет isDefault: true и source: "frontend_auto".

Стандартный лимит — 1000 profiles на один account. Значения maxProfiles и unlimitedProfiles возвращаются как в объекте account, так и на верхнем уровне ответа списка профилей.

Custom proxy

Обязательность прокси

Browser account и profile можно создать без сохранённого прокси. Для рабочего подключения к браузеру custom proxy обязателен.

Исключение — ограниченный бесплатный IPv6 fallback для первоначального тестирования. В подтверждённом ответе он применился к Default profile обычного пользовательского account с proxyMode: "none", а не только к системному Default account. Профиль с proxyMode: "inherit" также остаётся без сохранённого прокси, если родительский account имеет режим none.

При доступном fallback запрос connection без customProxy возвращает 200 OK и готовый connectionUri. В connection.username при этом отсутствует сегмент -proxy-, а верхнеуровневое поле customProxy равно null.

Не используйте proxySettings.exists для определения наличия custom proxy. В подтверждённом ответе у профиля это поле было true, хотя proxyMode был none, customProxy был null, а подключение сформировалось без сегмента -proxy-.

Формат customProxy

{
  "type": "http",
  "host": "proxy.example.com",
  "port": 8000,
  "login": "proxy_user",
  "password": "proxy_password"
}
Поле Тип Обязательное Описание
type string да http, https, socks4 или socks5.
host string да Host или IP-адрес прокси.
port integer да Порт прокси.
login string нет Логин, если прокси требует авторизацию.
password string нет Пароль, если прокси требует авторизацию.

Фактическая страна выхода определяется самим custom proxy.

Приоритет прокси

Предполагаемый порядок выбора:

  1. custom proxy, переданный для конкретного connectionUri;
  2. custom proxy, сохранённый у browser profile;
  3. custom proxy, сохранённый у browser account;
  4. ограниченный IPv6 fallback, если он в данный момент доступен и после применения наследования у профиля нет сохранённого прокси.

Получение connectionUri

Подключение с сохранённым прокси

curl "$BASE_URL?method=connection&accountId=123&key=YOUR_API_KEY"

Для конкретного профиля:

curl "$BASE_URL?method=connection&accountId=123&profileId=PROFILE_ID&key=YOUR_API_KEY"

Подключение с прокси для текущей сессии

curl -X POST "$BASE_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "connection",
    "key": "YOUR_API_KEY",
    "accountId": 123,
    "customProxy": {
      "type": "http",
      "host": "proxy.example.com",
      "port": 8000,
      "login": "proxy_user",
      "password": "proxy_password"
    }
  }'

Пример ответа:

{
  "status": "OK",
  "connectionUri": "REDACTED_CONNECTION_URI",
  "connection": {
    "scheme": "ws",
    "host": "cb.2captcha.com:9222",
    "username": "REDACTED_CONNECTION_USERNAME",
    "password": "REDACTED_BROWSER_PASSWORD"
  },
  "account": {
    "id": 123,
    "name": "Main browser account",
    "proxyMode": "none"
  },
  "profile": {
    "id": 456,
    "accountId": 123,
    "profileId": "p0123456789abcdef0123456789abcdef",
    "isDefault": true,
    "name": "Default profile",
    "proxyMode": "none"
  },
  "customProxy": {
    "type": "http",
    "host": "proxy.example.com",
    "port": 8000,
    "login": "REDACTED_PROXY_LOGIN",
    "password": "REDACTED_PROXY_PASSWORD"
  }
}

Получение URI само по себе не запускает браузерную сессию. Сессия начинается после подключения CDP-клиента.

Переданный для подключения custom proxy возвращается в верхнеуровневом поле customProxy. В подтверждённом ответе он не был сохранён в account или profile: оба объекта сохранили proxyMode: "none" и customProxy: null. Таким образом, прокси из запроса применяется к сформированному подключению, но не становится сохранённой настройкой account/profile.

В connection.username присутствует сегмент -proxy-{encodedProxy}. Значение encodedProxy является Base64URL-представлением полного URL прокси, включая credentials. Base64URL — это обратимое кодирование, а не шифрование.

Считайте секретными и не логируйте:

  • весь connectionUri;
  • connection.username;
  • connection.password;
  • browser login и password внутри вложенного account;
  • весь верхнеуровневый объект customProxy, если в нём есть credentials.

Ответ connection содержит полные объекты выбранных account и profile. Их ID совпадают с accountId и profileId, переданными в запросе.

Подключение без custom proxy

Если у account/profile установлен proxyMode: "none" и доступен тестовый IPv6 fallback, запрос без customProxy завершается успешно:

{
  "status": "OK",
  "connectionUri": "REDACTED_CONNECTION_URI",
  "connection": {
    "scheme": "ws",
    "host": "cb.2captcha.com:9222",
    "username": "REDACTED_CONNECTION_USERNAME_WITHOUT_PROXY_SEGMENT",
    "password": "REDACTED_BROWSER_PASSWORD"
  },
  "account": {
    "id": 123,
    "proxyMode": "none",
    "customProxy": null
  },
  "profile": {
    "accountId": 123,
    "profileId": "p0123456789abcdef0123456789abcdef",
    "isDefault": true,
    "proxyMode": "none",
    "customProxy": null
  },
  "customProxy": null
}

Такое подключение использует ограниченный IPv6 fallback. Отсутствие -proxy- в username подтверждает, что custom proxy в URI не встроен.

Не используйте fallback как постоянную рабочую конфигурацию: его доступность ограничена и может быть отключена. Для рабочих сценариев передавайте custom proxy.

CDP-интерфейс Captcha

CDP-функциональность и решение CAPTCHA в MegaIndex совпадают с Browser API 2Captcha. После подключения к облачному браузеру можно использовать стандартные возможности Playwright/Puppeteer и дополнительный CDP-домен Captcha.

Решение CAPTCHA входит в Browser API и отдельно не оплачивается. MegaIndex списывает только browser traffic, израсходованный облачным браузером.

Назначение

CDP-домен Captcha позволяет управлять решением CAPTCHA на текущей вкладке облачного браузера.

Доступны два режима:

  1. Автоматическое решение после загрузки страницы.
  2. Ручной запуск через команду Captcha.solve.

События CDP позволяют отслеживать обнаружение CAPTCHA, отправку запроса в сервис, успешное решение и ошибку.

Подключение к CDP-сессии

Playwright

import { chromium } from 'playwright';

const browser = await chromium.connectOverCDP(connectionUri);
const context = browser.contexts()[0];
const page = await context.newPage();
const session = await context.newCDPSession(page);

Puppeteer

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.connect({
  browserWSEndpoint: connectionUri
});

const page = await browser.newPage();
const session = await page.target().createCDPSession();

Типы данных CDP

CaptchaOptions

Один элемент массива options. Обычно передаётся один объект:

{
  "type": "*",
  "submitForm": false,
  "selector": ".captcha-container",
  "detectSelector": ".captcha-container",
  "responseSelector": "textarea[name=\"g-recaptcha-response\"]"
}
Поле Тип Описание
type string Тип CAPTCHA. Передайте * для автоматического определения.
submitForm boolean Отправить форму после получения токена.
submitSelector string CSS-селектор кнопки отправки формы.
selector string CSS-селектор контейнера CAPTCHA.
detectSelector string CSS-селектор для обнаружения CAPTCHA.
responseSelector string CSS-селектор поля, куда нужно записать токен.
sitekeyAttributes string[] Атрибуты, из которых можно получить sitekey.
actionAttributes string[] Атрибуты, из которых можно получить action для reCAPTCHA v3.

SolveResult

Ответ команды Captcha.solve возвращается в поле result:

{
  "result": {
    "status": "solveFinished",
    "token": "03AGdBq26..."
  }
}
Поле Тип Описание
status string solveFinished, solveFailed, notDetected или invalid.
token string Токен при успешном решении.
errorMessage string Текст ошибки при неуспешном решении.

Команды CDP

Captcha.setAutoSolve

Включает или отключает автоматическое решение CAPTCHA на вкладке:

await session.send('Captcha.setAutoSolve', {
  autoSolve: true,
  options: [
    {
      type: '*'
    }
  ]
});
Параметр Тип Обязательный Описание
autoSolve boolean да true — решать автоматически; false — использовать только Captcha.solve.
options CaptchaOptions[] нет Настройки поиска и решения CAPTCHA.

При успехе команда не возвращает тело.

Возможная CDP-ошибка:

No active frame

Captcha.solve

Запускает явное решение CAPTCHA на текущей вкладке:

const response = await session.send('Captcha.solve', {
  detectTimeout: 15000,
  options: [
    {
      type: '*'
    }
  ]
});

console.log(response.result.status);
console.log(response.result.token);
Параметр Тип Обязательный Описание
detectTimeout integer нет Таймаут обнаружения CAPTCHA в миллисекундах. Внутренний лимит ответа примерно равен detectTimeout + 10s; без параметра используется около 60s.
options CaptchaOptions[] нет Параметры поиска и решения CAPTCHA.

Успешное решение:

{
  "result": {
    "status": "solveFinished",
    "token": "03AGdBq26..."
  }
}

CAPTCHA не найдена:

{
  "result": {
    "status": "notDetected"
  }
}

Возможные CDP-ошибки без SolveResult:

No active frame
Captcha.solve timed out waiting for extension response

События CDP

Подписка в Playwright:

session.on('Captcha.detected', () => {
  console.log('CAPTCHA detected');
});

session.on('Captcha.waitForSolve', () => {
  console.log('CAPTCHA sent to solver');
});

session.on('Captcha.solveFinished', () => {
  console.log('CAPTCHA solved');
});

session.on('Captcha.solveFailed', () => {
  console.log('CAPTCHA solve failed');
});
Событие Описание
Captcha.detected CAPTCHA обнаружена на странице.
Captcha.waitForSolve Запрос отправлен в сервис, идёт ожидание ответа.
Captcha.solveFinished CAPTCHA успешно решена.
Captcha.solveFailed Решение завершилось ошибкой.

Цепочка событий в автоматическом режиме:

Captcha.detected → Captcha.waitForSolve → Captcha.solveFinished | Captcha.solveFailed

События предназначены для отслеживания прогресса. Токен возвращается только в ответе команды Captcha.solve.

Рекомендуемые сценарии

Автоматическое решение CAPTCHA

Используйте автоматический режим, если браузер должен сам решать CAPTCHA после загрузки страницы:

await session.send('Captcha.setAutoSolve', {
  autoSolve: true,
  options: [{ type: '*' }]
});

const solved = new Promise((resolve, reject) => {
  session.once('Captcha.solveFinished', resolve);
  session.once('Captcha.solveFailed', reject);
});

await page.goto('https://example.com');
await solved;

Рекомендуемый порядок:

Captcha.setAutoSolve({ autoSolve: true, options })
  → навигация на страницу с CAPTCHA
  → ожидание Captcha.solveFinished или Captcha.solveFailed

В автоматическом режиме токен забирать и подставлять самостоятельно не нужно. Он записывается на странице и, если задано, форма отправляется автоматически через responseSelector, submitForm и submitSelector. События сообщают о готовности, но не содержат токен.

Ручное решение CAPTCHA

Используйте ручной запуск, чтобы контролировать момент начала решения и получить токен:

await session.send('Captcha.setAutoSolve', {
  autoSolve: false,
  options: [{ type: '*' }]
});

await page.goto('https://example.com');
await page.waitForTimeout(5000);

const { result } = await session.send('Captcha.solve', {
  detectTimeout: 15000,
  options: [{ type: '*' }]
});

if (result.status === 'solveFinished') {
  console.log('Token:', result.token);
} else {
  console.log('Captcha solve status:', result.status, result.errorMessage);
}

Рекомендуемый порядок:

Captcha.setAutoSolve({ autoSolve: false, options })
  → навигация
  → пауза 3–5 секунд для регистрации виджета
  → Captcha.solve({ detectTimeout, options })
  → проверка result.status

Не вызывайте Captcha.solve из обработчика Captcha.detected. Для ручного режима достаточно одного вызова после короткой паузы.

Таймауты CDP

Таймаут Рекомендация
Внутренний таймаут браузера detectTimeout + 10s или около 60s, если detectTimeout не передан.
Таймаут клиента Не меньше detectTimeout + 120–180s, чтобы учесть время ожидания решения.
Максимальная продолжительность браузерной сессии 30 минут. Выбирайте таймауты так, чтобы решение не вышло за пределы сессии.

Если CDP-клиент имеет собственный таймаут на session.send, увеличьте его для Captcha.solve, иначе клиент может прекратить ожидание раньше ответа сервиса.

Полный пример: MegaIndex Browser API + Playwright + авто-решение

import { chromium } from 'playwright';

const API_URL = 'http://89.108.119.8/test-browser-api/browser.php';
const API_KEY = process.env.MEGAINDEX_API_KEY;

async function createConnectionUri() {
  const response = await fetch(API_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      method: 'connection',
      key: API_KEY,
      accountId: 123,
      profileId: 'p0123456789abcdef0123456789abcdef',
      customProxy: {
        type: 'http',
        host: 'proxy.example.com',
        port: 8080,
        login: 'proxyuser',
        password: 'proxypass'
      }
    })
  });

  const data = await response.json();

  if (data.status !== 'OK') {
    throw new Error(`${data.errorCode}: ${data.error}`);
  }

  return data.connectionUri;
}

const connectionUri = await createConnectionUri();
const browser = await chromium.connectOverCDP(connectionUri);
const context = browser.contexts()[0];
const page = await context.newPage();
const session = await context.newCDPSession(page);

session.on('Captcha.detected', () => console.log('CAPTCHA detected'));
session.on('Captcha.waitForSolve', () => console.log('Waiting for MegaIndex'));
session.on('Captcha.solveFinished', () => console.log('CAPTCHA solved'));
session.on('Captcha.solveFailed', () => console.log('CAPTCHA solve failed'));

await session.send('Captcha.setAutoSolve', {
  autoSolve: true,
  options: [{ type: '*' }]
});

await page.goto('https://example.com');

Не храните API key и proxy credentials непосредственно в исходном коде рабочего приложения. Используйте переменные окружения или хранилище секретов.

Полный пример: ручной Captcha.solve

import { chromium } from 'playwright';

const connectionUri = process.env.MEGAINDEX_BROWSER_CDP_URL;
const browser = await chromium.connectOverCDP(connectionUri);
const context = browser.contexts()[0];
const page = await context.newPage();
const session = await context.newCDPSession(page);

await session.send('Captcha.setAutoSolve', {
  autoSolve: false,
  options: [{ type: '*' }]
});

await page.goto('https://example.com');
await page.waitForTimeout(5000);

const { result } = await session.send('Captcha.solve', {
  detectTimeout: 15000,
  options: [{ type: '*' }]
});

switch (result.status) {
  case 'solveFinished':
    console.log('CAPTCHA token:', result.token);
    break;
  case 'solveFailed':
    console.log('CAPTCHA solve failed:', result.errorMessage);
    break;
  case 'notDetected':
    console.log('CAPTCHA was not detected on the page');
    break;
  case 'invalid':
    console.log('Invalid solve request:', result.errorMessage);
    break;
  default:
    console.log('Unknown CAPTCHA status:', result.status);
}

Рекомендации по интеграции

  1. Получайте connectionUri через method=connection, а не собирайте WebSocket URL вручную.
  2. Для рабочих сценариев всегда передавайте custom proxy через запрос подключения или сохранённые настройки account/profile.
  3. Для стабильной изоляции используйте отдельные profiles под разные сценарии.
  4. Если нужен только факт успешного прохождения CAPTCHA, используйте автоматический режим и события.
  5. Если нужен токен, используйте ручной Captcha.solve.
  6. Увеличивайте таймаут CDP-клиента для ручного решения.
  7. Проверяйте result.status, а не только наличие ответа от команды.
  8. Для диагностики логируйте события, но не логируйте токены, connectionUri, connection.username, browser password и proxy credentials.

Отдельного баланса или тарифа для решения CAPTCHA нет: оплачивается только browser traffic.

История и статистика

История

curl "$BASE_URL?method=history&page=1&limit=50&key=YOUR_API_KEY"

Метод возвращает историю покупок browser traffic:

{
  "status": "OK",
  "project": {
    "id": 2,
    "code": "megaindex",
    "name": "MegaIndex"
  },
  "data": [
    {
      "id": 10,
      "flow": 1,
      "trafficKb": 1048576,
      "price": 5,
      "amount": 5,
      "valute": "usd",
      "status": 1,
      "createdAt": "2026-08-05 16:20:19"
    }
  ]
}
Поле Тип Описание
id integer ID операции покупки.
flow integer Купленный объём browser traffic в GB.
trafficKb integer Тот же объём в KB. Один GB соответствует 1048576 KB.
price number Цена одного GB.
amount number Полная сумма операции: flow × price.
valute string Валюта операции. Название поля в API — именно valute.
status integer Числовой статус операции.
createdAt string Дата и время создания операции в формате YYYY-MM-DD HH:mm:ss.

Операции в подтверждённом ответе расположены от новых к старым.

Статистика browser traffic

curl "$BASE_URL?method=statistics&key=YOUR_API_KEY"

Сокращённый пример ответа:

{
  "status": "OK",
  "project": {
    "id": 2,
    "code": "megaindex",
    "name": "MegaIndex"
  },
  "period": {
    "dateFrom": "2026-07-06",
    "dateTo": "2026-08-05"
  },
  "traffic": {
    "totalKb": 3145728,
    "usedKb": 0,
    "availableKb": 3145728,
    "totalGb": 3,
    "usedGb": 0,
    "availableGb": 3
  },
  "usage": {
    "trafficKb": 5752,
    "trafficGb": 0.0055,
    "requestCount": 34
  },
  "accounts": [
    {
      "id": 123,
      "login": "REDACTED_BROWSER_LOGIN",
      "name": "Default browser account",
      "status": 1,
      "trafficKb": 1075,
      "trafficGb": 0.001,
      "requestCount": 8,
      "lastUsedAt": "2026-08-05 10:00:00"
    }
  ],
  "profileUsage": {
    "trafficKb": 5752,
    "trafficGb": 0.0055,
    "requestCount": 34
  },
  "profiles": [
    {
      "id": 456,
      "accountId": 123,
      "profileId": "p0123456789abcdef0123456789abcdef",
      "name": "Default profile",
      "trafficKb": 1075,
      "trafficGb": 0.001,
      "requestCount": 8,
      "totalUsedKb": 1075,
      "totalUsedGb": 0.001,
      "totalRequestCount": 8,
      "periodLastUsedAt": "2026-08-05 10:00:00",
      "lastUsedAt": "2026-08-05 10:39:02"
    }
  ]
}

Основные блоки:

  • period — период, за который рассчитаны показатели использования;
  • traffic — общий приобретённый, использованный и доступный объём browser traffic;
  • usage — суммарный расход и количество запросов за выбранный период;
  • accounts — расход за период с группировкой по browser account;
  • profileUsage — суммарный расход профилей за период;
  • profiles — периодические и накопленные показатели отдельных профилей.

В объектах profiles поля trafficKb, trafficGb и requestCount относятся к выбранному периоду, а totalUsedKb, totalUsedGb и totalRequestCount содержат накопленные значения.

В подтверждённом ответе без явных дат API выбрал период с 6 июля по 5 августа 2026 года.

Ошибки

Все ошибки возвращаются в JSON:

{
  "errorId": 1,
  "errorCode": "ERROR_WRONG_USER_KEY",
  "error": "API key is invalid."
}
errorCode HTTP Значение
ERROR_KEY_DOES_NOT_EXIST 401 API key не передан.
ERROR_WRONG_USER_KEY 401 API key не найден в MegaIndex.
ERROR_ACCOUNT_SUSPENDED 403 Аккаунт отключён.
ERROR_METHOD 405 Неподдерживаемый HTTP method.
ERROR_NO_SUCH_METHOD 404 Неизвестный API method.
ERROR_FLOW_AMOUNT 400 Некорректное количество GB.
ERROR_IDEMPOTENCY_KEY 400 Некорректный idempotency key.
ERROR_INSUFFICIENT_FUNDS 400 Недостаточно средств на балансе MegaIndex.
ERROR_GB_PRICE 400 Не удалось определить цену browser traffic.
ERROR_CONNECTION_URI 404 Нет данных для подключения к браузеру.
ERROR_BROWSER_BACKEND_UNAVAILABLE 502 Browser backend временно недоступен.
ERROR_BROWSER_BACKEND_BAD_RESPONSE 502 Browser backend вернул некорректный ответ.

Пример неверного API key:

{
  "errorId": 1,
  "errorCode": "ERROR_WRONG_USER_KEY",
  "error": "API key is invalid."
}

HTTP status: 401 Unauthorized.

Пример неизвестного значения method:

{
  "errorId": 1,
  "errorCode": "ERROR_NO_SUCH_METHOD",
  "error": "Method is not supported."
}

HTTP status: 404 Not Found.

Ограничения и безопасность

  • Для каждого параллельного процесса используйте отдельный browser profile.
  • Не передавайте API key, connectionUri, browser password или proxy password третьим лицам.
  • Не публикуйте connection.username: встроенный в него Base64URL-сегмент custom proxy может содержать обратимо закодированные proxy login и password.
  • Учитывайте, что ответ connection возвращает custom proxy вместе с credentials; не записывайте полный JSON-ответ в открытые логи.
  • Не сохраняйте секреты во frontend-коде и публичных логах.
  • При повторе покупки используйте тот же idempotencyKey только для того же заказа.
  • Учитывайте отдельно остаток browser traffic MegaIndex и лимит proxy traffic у своего провайдера.

Максимальная продолжительность браузерной сессии — 30 минут.

Короткий FAQ

Что оплачивается в MegaIndex?

MegaIndex учитывает и продаёт browser traffic в GB. Дополнительный трафик приобретается с баланса MegaIndex.

Входит ли proxy traffic в browser traffic?

Нет. Это независимые ресурсы. MegaIndex не учитывает и не оплачивает трафик вашего custom proxy.

Можно ли создать browser account без прокси?

Да. Прокси можно добавить позднее на уровне account или profile либо передать при получении connectionUri.

Можно ли подключиться без собственного прокси?

Для первоначального теста профиля с proxyMode: "none" может быть доступен ограниченный IPv6 fallback. Для рабочих подключений требуется custom proxy.

Сколько тестового browser traffic предоставляется?

Новый пользователь получает 1 GB тестового browser traffic.

Можно ли повторить запрос покупки после сетевой ошибки?

Да. Для того же заказа повторно передайте тот же idempotencyKey, чтобы исключить двойное списание.

Поддерживается ли автоматическое решение CAPTCHA?

Да. MegaIndex поддерживает тот же CDP-интерфейс Captcha, что и Browser API 2Captcha.

Нужно ли отдельно оплачивать решение CAPTCHA?

Нет. Решение CAPTCHA входит в Browser API. MegaIndex учитывает и списывает только browser traffic.