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 не показывает его остаток, не списывает за него деньги и не контролирует тариф прокси-провайдера.
Практически это означает, что во время рабочего подключения могут одновременно расходоваться:
- browser traffic в MegaIndex;
- proxy traffic у внешнего провайдера.
Получить цены
curl "$BASE_URL?method=prices&key=YOUR_API_KEY"
С явным указанием валюты:
curl "$BASE_URL?method=prices¤cy=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.
Приоритет прокси
Предполагаемый порядок выбора:
- custom proxy, переданный для конкретного
connectionUri; - custom proxy, сохранённый у browser profile;
- custom proxy, сохранённый у browser account;
- ограниченный 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 на текущей вкладке облачного браузера.
Доступны два режима:
- Автоматическое решение после загрузки страницы.
- Ручной запуск через команду
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);
}
Рекомендации по интеграции
- Получайте
connectionUriчерезmethod=connection, а не собирайте WebSocket URL вручную. - Для рабочих сценариев всегда передавайте custom proxy через запрос подключения или сохранённые настройки account/profile.
- Для стабильной изоляции используйте отдельные profiles под разные сценарии.
- Если нужен только факт успешного прохождения CAPTCHA, используйте автоматический режим и события.
- Если нужен токен, используйте ручной
Captcha.solve. - Увеличивайте таймаут CDP-клиента для ручного решения.
- Проверяйте
result.status, а не только наличие ответа от команды. - Для диагностики логируйте события, но не логируйте токены,
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.