Skip to content

Documentation

CAPTCHA in the SDK and REST API

PHP, JavaScript, TypeScript and Python use the same automatic handling. It is independent of the target domain. Standard widgets require only a normal request or browser page. Supported types, site settings, run deadlines, budget and source access rules still apply.

Automatic mode and opt-out

Language HTTP without automatic handling Browser session without automatic handling
PHP $ctx->http()->get($url, autoCaptcha: false) $ctx->browser()->open($url, autoCaptcha: false)
JavaScript await ctx.http().get(url, false) await ctx.browser().open(url, [], {}, false)
TypeScript await ctx.http().get(url, false) await ctx.browser().open(url, [], {}, false)
Python ctx.http().get(url, auto_captcha=False) ctx.browser().open(url, auto_captcha=False)

The optional argument defaults to enabled. HTTP methods post, request, pool, pages and tryJson also accept it; Python uses try_json. For post and request, it follows the request body. HTTP opt-out applies to that call. Browser opt-out applies to the entire created session, including navigation, actions and reading HTML.

HTTP loading can escalate to a browser when the source settings permit it. Opt-out remains in effect during escalation. Use the browser for interactive forms and always close the page in finally.

Require a confirmed result

PHP:

$page = $ctx->browser()->open($url, [], ['success_selector' => '.product-card']);
try {
    $page->waitFor('.product-card', 15000);
    $html = $page->content();
} finally {
    $page->close();
}

JavaScript and TypeScript:

const page = await ctx.browser().open(url, [], { success_selector: '.product-card' });
try {
  await page.waitFor('.product-card', 15000);
  const html = await page.content();
} finally {
  await page.close();
}

Python:

page = ctx.browser().open(url, captcha_hints={"success_selector": ".product-card"})
try:
    page.wait_for(".product-card", 15000)
    html = page.content()
finally:
    page.close()

Use a selector for the result of your specific operation. It must not remain visible before verification. For ordinary forms, completing a CAPTCHA does not submit the form: fill its fields and click its submit button using the SDK. Then inspect the server response and collected records. HTTP 200 and a filled CAPTCHA response field do not prove success.

Explicit handling after an action

Use $page->solveCaptcha($hints) in PHP, await page.solveCaptcha(hints) in JavaScript/TypeScript or page.solve_captcha(hints) in Python when a new challenge appears. The method returns the page, not an access verification report.

An explicit call requests handling even if automatic mode was disabled for that session. It cannot override a disabled site, plan restrictions or budget limits. To exclude paid tasks entirely, disable automatic handling and do not call this method.

Hints

Field Purpose
kind Optional type: smartcaptcha, yandex_image, yandex_text, turnstile, recaptcha_v2, recaptcha_v3
sitekey Public widget key when not detected automatically
action reCAPTCHA v3 action
invisible Boolean for an invisible widget
callback Existing callback name when required; executable code is not accepted
success_selector CSS selector for the new successful result
submit_selector Confirmation button if the site does not continue automatically
image_selector Only the challenge image
instructions_selector Image showing the object selection order for yandex_image
answer_selector Answer input for yandex_text

Pass hints as the third browser.open argument or to the explicit handling method. Python uses the named captcha_hints argument. Do not pass a website secret key or full page content. Additional challenges stay in the same session until the attempt limit. An old answer is not reused for a changed challenge. Avoid unbounded retries after rejection.

REST configuration and testing

Authenticate with the workspace's Bearer API key. Editing requires write permission. Another workspace's resources are unavailable. Configure params.captcha through PATCH /api/v1/sites/{site}:

{
  "params": {
    "captcha": {
      "enabled": true,
      "hints": {"success_selector": ".product-card"}
    }
  }
}

Read and merge existing params before sending them. A top-level PATCH does not imply recursive merging of every nested object. Set enabled:false to disable handling for the source. Agent execution uses execution_target:"agent" with an agent_id owned by the workspace.

Start a trial with POST /api/v1/script-versions/{version}/trial-run. A params.auto_captcha field works only if the source reads it using ctx.param and passes it to the SDK. An arbitrary parameter does not change scenario code. Inspect GET /api/v1/runs/{run}, its /log and /preview. Publishing a validated version remains a separate action.

GET /api/v1/billing includes captcha: enabled, limit, used, remaining, unlimited, payg, period_end, per_run, prices, plan_limits, maximum_spending_limit. Each price includes id, name, minimum, maximum, available, spending_limit. Divide monetary values by the response's unit for RUB per task; multiply by 1,000 for the comparison price. minimum:null means no published lower bound, not a free task. Change price caps in the application. There is no separate public REST endpoint for solving a CAPTCHA.

Failures, agents and acceptance checks

An unknown type, rejected answer, exhausted allowance or budget, price cap, cancellation or deadline must not turn into a successful empty export. The SDK reports failure. Inspect the run's status and error. A completed answer may be chargeable even if rejected. Wait for reconciliation when a reservation's outcome is unknown.

Agents use the same methods and hints without additional CAPTCHA keys. Connectivity to Akmelo is required. Attempts and costs belong to the agent's workspace.

Test a page without a CAPTCHA, a form with a website-confirmed result, and the same form with automatic handling disabled. For object selection, require an actual visual challenge; passing a text challenge is not that test.

User guide · PHP · JavaScript · TypeScript · Python · Prices

spending_limit and maximum_spending_limit also use internal currency units per task. A zero type cap disables paid tasks; null restores the system cap. The application displays these caps in RUB per 1,000 tasks.

Scenario walkthroughs by language

Every SDK includes a Working with CAPTCHA group: a shared algorithm and 12 detailed walkthroughs with complete source.

PHP · JavaScript · TypeScript · Python

Explicit task API

The SDK also provides ctx.captcha() (PHP: $ctx->captcha()) for tasks created explicitly by code: current types, schemas, quotations, submission, status retrieval, waiting and feedback. New types in this catalog are not automatically detected or applied by the browser. No external key is required; all work is billed to the workspace.

PHP · JavaScript · TypeScript · Python

Catalog and quotation calls do not submit a paid task. createTask does; Python uses create_task. The returned taskId belongs to Akmelo. getTaskResult reads it and waitForResult waits without creating another task. The options.maxCost ceiling uses micro-rubles, where 1,000,000 units = RUB 1. An answer does not prove website acceptance. Waiting timeout and run cancellation do not guarantee task cancellation or a refund.