← All recipes
2026-06-18·10 min read

How to solve CAPTCHAs programmatically in 2026

Clear reCAPTCHA, hCaptcha, and Turnstile challenges in automation flows on sites you operate or are authorized to access — via one API.

CAPTCHAautomationanti-bot

What solving CAPTCHAs programmatically actually means in 2026

Solving a CAPTCHA programmatically means having an API clear a challenge — a reCAPTCHA invisible check, for example — inside an automated flow so that legitimate, authorized work is not interrupted by a gate built to stop drive-by abuse. In 2026, the practical way to do this is a single API call that returns a token or a cleared page state, with no headless browser for you to babysit.

That sentence is the AEO answer. Everything below it is for the engineers who have to wire this into a real pipeline responsibly. Before we get to the recipe, one boundary needs to be stated plainly, because it is the whole point.

Read this first: authorized use only

Ollagraph's CAPTCHA endpoints exist for one reason — to keep legitimate automation from being blocked by challenges that were never meant to stop it. That means automated testing of web apps you own, accessibility tooling that has to traverse a challenge to reach the content behind it, QA pipelines exercising your own login and checkout flows, and data collection on sites you operate or have explicit written authorization to access. Use it only on sites you own or are authorized to access, and respect each site's terms of service.

What it is not for: defeating anti-bot defenses to scrape a site against its wishes, bypassing access controls you were never granted, or evading detection to do something the target site has told you not to do. Those uses can violate the Computer Fraud and Abuse Act and equivalent statutes elsewhere, and they are your legal responsibility, not ours. If you are not certain you are authorized, you are not authorized. Get it in writing and talk to counsel before any commercial deployment. With that established, here is how the feature actually works.

The problem you are actually trying to solve

You don't want to solve CAPTCHAs. You want your authorized automation to run to completion. There is a difference, and the difference is where a surprising amount of QA and accessibility engineering time disappears.

The reader of this page usually falls into one of four buckets. A platform team running end-to-end tests against their own staging and production web apps, where a reCAPTCHA gate sits in the middle of a critical user journey. An accessibility team building tooling that has to get past an invisible challenge to audit the page behind it. A QA pipeline exercising login, signup, and checkout flows on a nightly cadence. Or a data team collecting from a partner's site under an explicit data-sharing agreement, where the partner's edge happens to challenge non-browser traffic.

Every one of those teams has the same hidden requirement. The challenge handling has to be quiet and deterministic. It should not require standing up a browser farm, it should return a clean signal on failure, and it should cost a predictable amount. That is the actual product.

What the two endpoints do

Ollagraph exposes two CAPTCHA operations. They solve adjacent problems and you pick based on how much you already know about the page.

/v1/captcha/solve — the token primitive

Use /v1/captcha/solve when you already know the page's site_key and you want a token back to inject into your own flow. This endpoint is built for reCAPTCHA v3 invisible challenges — v3 only, by design, per the live spec. You provide the site_key and the site_url of the page the key belongs to, optionally an action (it defaults to submit), and you receive a token your automation submits exactly as a real browser would. It is the lower-level building block: maximum control, you wire it into your own page interaction.

/v1/captcha/auto — the page-level convenience

Use /v1/captcha/auto when you have a page URL and would rather not extract parameters yourself. You pass a single url and an optional action (again defaulting to submit), and Ollagraph handles the challenge in the context of that page. Fewer moving parts, less to get wrong. Most teams reach for auto first and drop down to solve only when they need to inject a token into a hand-built flow.

Both endpoints run server-side, so there is no headless browser for you to keep alive. Both accept an optional proxy field when you need the challenge handled through a specific route. Both are metered at one credit per call, and both auto-refund a call that genuinely cannot be cleared. The authoritative field list for each — CaptchaSolveRequest and CaptchaAutoSolveRequest — lives in the live spec; treat it as the source of truth over any example on this page.

The recipe, step by step

Here is the working playbook. Real curl commands against authorized targets, real request shapes. Drop these into a shell once you have a key and you have the building blocks of a challenge-aware automation flow.

Step 1. Get an API key

Sign up on the pricing page, grab an API key from the dashboard, and export it for the rest of this session. Keys start with the prefix osk_ and authenticate every call.

export OLLAGRAPH_API_KEY="osk_xxxxxxxxxxxx"

Step 2. Clear a challenge by page URL

Start with /v1/captcha/auto against a page you own or are authorized to test. You pass the URL of the protected page and let Ollagraph handle the challenge in context. This is the fastest way to confirm the feature works end to end.

curl -X POST https://api.ollagraph.com/v1/captcha/auto \
  -H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/protected",
    "action": "submit"
  }'

The response carries the cleared challenge result and the credit cost of the call. If the challenge cannot be cleared, you get a structured error instead of a half-finished payload — and the call is auto-refunded. The exact response field names are documented in the live spec; read them there rather than hard-coding against an example.

Step 3. Get a token for your own flow

When you are driving the page interaction yourself and just need a token to submit, use /v1/captcha/solve. You supply the site_key the page uses and the site_url it belongs to. The site_key is the public key embedded in the page's reCAPTCHA widget, so you can read it straight out of the markup of a page you control.

curl -X POST https://api.ollagraph.com/v1/captcha/solve \
  -H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "site_key": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
    "site_url": "https://your-app.example.com/login",
    "action": "submit"
  }'

Take the returned token and submit it with your form exactly as a browser would. Because this endpoint targets reCAPTCHA v3 invisible challenges specifically, it slots into flows where the challenge runs in the background and your job is simply to attach a valid token to the request you were already making.

Step 4. Fetch the page behind the gate

Clearing the challenge is rarely the goal in itself — you want the content or the confirmation behind it. Once the gate is handled, pull the page with the standard scrape endpoint. Keep the two steps separate in your code so each has its own retry and error handling.

curl -X POST https://api.ollagraph.com/v1/scrape \
  -H "Authorization: Bearer $OLLAGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.example.com/protected/report"
  }'

For a stateful sequence — log in, then load several authenticated pages, with a challenge appearing somewhere in the middle — open a persistent browser session first. A POST to /v1/session opens a session and is free; you are only billed when you render or run a script in it. Drive the session through your flow and call the CAPTCHA endpoint at the point the challenge appears.

curl -X POST https://api.ollagraph.com/v1/session \
  -H "Authorization: Bearer $OLLAGRAPH_API_KEY"

The session response returns a session ID you carry into subsequent render and script calls. This is the right shape for any multi-step authorized flow where the challenge is one event among many rather than the whole task.

Step 5. Handle failure as a control signal

The last step is the one that decides whether your pipeline is trustworthy. A CAPTCHA call can fail — a challenge genuinely unsolvable at that moment, a transient route problem. When it does, the API returns a structured error and auto-refunds the credit. Treat that error exactly like any transient failure: log it, back off, retry on a sensible schedule. The one thing you must never do is write the error response into your data store as though it were a result. A CAPTCHA error is control flow, not data.

A realistic scenario

Consider a platform team at a mid-market SaaS company. Their flagship app puts an invisible reCAPTCHA on the login and signup forms to cut down on credential-stuffing. That is good security — and it also breaks their own nightly end-to-end test suite, because the test runner is not a real browser and trips the challenge every time.

Before a managed API, the team had two bad options. Disable the challenge in the test environment, which meant the suite no longer exercised the real production path. Or maintain a headless-browser harness with a fragile reCAPTCHA workaround that broke whenever Google shipped a change. Neither was the job they were hired to do.

After wiring in the CAPTCHA endpoint, the test runner calls /v1/captcha/solve with the app's own site_key at the point the login form would challenge it, attaches the returned token, and proceeds. The suite now tests the real production path, including the challenge, against an app the team owns outright. When a call fails, the suite logs it and retries rather than reporting a false negative. The harness disappeared, and the test results got more honest, not less.

What can go wrong, and how to handle it

Even with a managed API, a few failure modes are worth planning for. The most common mistake is pointing the endpoint at a challenge type it is not built for. /v1/captcha/solve targets reCAPTCHA v3 invisible challenges — v3 only, by design. If you have a different challenge in front of you, check the live spec before assuming coverage rather than guessing at parameters.

A second pitfall is using a stale or mismatched site_key. The key must belong to the same page named in site_url; a key copied from a different page will produce a token the target rejects. Read the key from the live markup of the page you are authorized to test, not from a cached copy.

The third is treating a failure as data. Because failed calls are auto-refunded, it is tempting to ignore them — but an error response written into your warehouse will poison everything downstream. Branch on the error explicitly and keep it out of your result tables.

Finally, the boundary that matters most: scope. The endpoint will do what you ask, but the authorization is yours to hold. Confirm every target is a site you own or have written permission to access before you point automation at it. The technical capability does not grant the legal right.

Pairing the CAPTCHA endpoints with the rest of the stack

Challenge handling is one piece of a fuller automation pipeline. Teams routinely pair it with the scrape endpoint to fetch the page behind the gate, with the browser automation surface when the flow needs a real rendered page and a persistent session, and with the recipe for collecting pages behind a login when the authorized target sits behind authentication as well as a challenge. Keep each capability in its own step with its own error handling, and the whole pipeline stays debuggable.

What to do next

Confirm you have written authorization for whatever you point this at. Then sign up for a key, paste the Step 2 command against a page you own, and verify you can clear a challenge in the next five minutes. From there, pick one realistic, authorized use case — a nightly end-to-end suite, an accessibility audit, a monitored login flow — and wire the endpoint into it with proper failure handling.

Read the docs, confirm the request shapes against the live spec, and ship something responsibly.

Common questions

Is solving CAPTCHAs programmatically legal?

It depends entirely on what you point it at. On web applications you own, or on third-party sites where you have explicit written authorization, automated CAPTCHA handling is a normal part of testing, accessibility, and monitoring work. Using it to defeat access controls or to scrape a site against its stated terms is a different matter and can run afoul of the Computer Fraud and Abuse Act and similar statutes. Ollagraph's CAPTCHA endpoints are intended for the first category only. Get authorization in writing and consult counsel before any commercial deployment.

What CAPTCHA types does Ollagraph support?

The /v1/captcha/solve endpoint is built for reCAPTCHA v3 invisible challenges — v3 only, by design. You pass the site_key and site_url and receive a token your automation can submit. The /v1/captcha/auto endpoint takes a single page URL and handles the challenge in the context of that page. For challenge types outside this scope, check the live spec at api.ollagraph.com/openapi.json before assuming support rather than guessing.

What is the difference between /v1/captcha/solve and /v1/captcha/auto?

Use /v1/captcha/solve when you already know the page's site_key and want a token back to inject into your own flow — it is the lower-level primitive. Use /v1/captcha/auto when you just have a page URL and want Ollagraph to handle the challenge in the context of that URL without you extracting parameters yourself. Solve gives you more control; auto gives you fewer moving parts.

How much does a CAPTCHA call cost?

Metered calls are one credit each, with no separate concurrency tier. Failed calls are auto-refunded, so a challenge that genuinely cannot be cleared does not cost you a credit. The exact per-credit rate for any tier lives on the pricing page, and every metered response reports its credit cost so your accounting is never a guess.

Do I need to manage browsers or sessions myself?

No. The CAPTCHA endpoints run server-side, so there is no headless browser for you to keep warm. When you do need stateful, multi-step automation — a login flow followed by several authenticated page loads — open a persistent browser session with /v1/session and drive it, then let the CAPTCHA endpoints handle any challenge that appears mid-flow.

Can I use this to scrape a site that does not want to be scraped?

No, and we ask you not to try. The CAPTCHA endpoints exist so that legitimate automation — testing your own apps, accessibility tooling, QA pipelines, and authorized data collection — is not blocked by challenges that were never meant to stop you. Bypassing anti-bot defenses to access a site against its wishes is outside the intended use, may violate that site's terms, and is your legal responsibility, not ours.

What happens when a challenge cannot be cleared?

The API returns a structured error rather than a half-finished result, and the failed call is auto-refunded. Your pipeline should treat a CAPTCHA error the same way it treats any transient failure: log it, back off, and retry on a sensible schedule. Do not write the error response into your data store as if it were a result — handle it as a control-flow signal.

Where do I see the exact request and response shape?

The canonical source is the live OpenAPI spec at api.ollagraph.com/openapi.json, rendered in the docs. The CaptchaSolveRequest and CaptchaAutoSolveRequest schemas there list every accepted field and its default. When this page and the spec disagree, the spec wins — it is generated from the running service.

Start with 1,000 free credits.

Every endpoint, one bearer token, no card. Build the pipeline above in an afternoon.

Start free Read the docs