Legibl docs PHP 0.1.0-dev · Python 0.1.0

Supported captcha types

Four types, named exactly. The list is short on purpose: a type that is claimed but not implemented costs a customer a production incident to discover.

Supported

Type Identifier Task type Solution key Submitted as
reCAPTCHA v2 recaptcha_v2 RecaptchaV2TaskProxyless gRecaptchaResponse g-recaptcha-response
reCAPTCHA v2 invisible recaptcha_v2_invisible RecaptchaV2TaskProxyless with isInvisible: true gRecaptchaResponse g-recaptcha-response
Cloudflare Turnstile turnstile TurnstileTaskProxyless token cf-turnstile-response, or the page's data-response-field-name
Image OCR image_ocr ImageToTextTask text the page's own answer field

Where each type is handled automatically

“Supported” is not one thing. The API accepts all four types; the SDKs' automatic interception path covers three of them.

Type Detected by detect() Solved by the SDK's service client Accepted by createTask
recaptcha_v2 yes yes yes
recaptcha_v2_invisible yes yes yes
turnstile yes yes yes
image_ocr separate call no yes
Image OCR is not automatic in the SDKs

Detect::detect() and legibl.detect() route between reCAPTCHA and Turnstile only. Image captchas are found by the separate Detect::imageCaptcha() / legibl.extract_image_captcha() helpers, and the SDK's service client (HttpSolver) returns no solution for an image_ocr extraction — it builds reCAPTCHA and Turnstile tasks only. To solve an image captcha today, call createTask with an ImageToTextTask yourself. This is a gap in the SDKs, not in the service.

Not supported

These are named here because their absence is the kind of thing a prospect should learn from documentation rather than from a failing job.

TypeStatusWhat happens if you send one
hCaptcha not supported No detection, no task type. A page carrying it yields no_challenge; a task carrying it is rejected with ERROR_TASK_NOT_SUPPORTED.
DataDome not supported As above.
Kasada not supported As above.
PerimeterX / HUMAN not supported As above.
Read this before assuming a clean page

A no_challenge outcome means the SDK found no challenge it knows about. On a target protected by one of the unsupported systems, that is exactly what you will see. It is not evidence that the page was served normally. Check the response body before concluding anything.

Two properties worth knowing before you integrate

Invisibility is reported for reCAPTCHA and never for Turnstile

reCAPTCHA signals invisibility in the markup — data-size="invisible", or a sitekey bound to a data-callback element rather than a rendered checkbox — so the SDKs report it and set isInvisible on the task.

Whether a Turnstile widget is managed, non-interactive or invisible is configured against the sitekey in the Cloudflare dashboard and is absent from the page. The SDKs therefore never populate invisible for Turnstile. Claiming to know it from the markup would be asserting something unknowable.

Turnstile's action and cdata are forwarded

Both alter the token Cloudflare issues. Dropping them produces a token the target rejects — a failure that looks like poor solver accuracy while actually being the integration's fault. The SDKs read data-action and data-cdata from the widget and pass them through on the task.

No captcha type currently requires a proxy

CaptchaType::ADDRESS_BOUND (PHP) and ADDRESS_BOUND (Python) are both empty. reCAPTCHA and Turnstile issue tokens validated against the sitekey rather than the requester, which is why they can be solved remotely at all. You can still configure a proxy per target, and doing so drops the Proxyless suffix from the task type; nothing forces you to.