Call the CAPTCHA solving API from n8n

By solvethree4 min read

Use n8n’s HTTP Request node to create the task, then branch on its status. If it’s still pending or solving, wait and retrieve the same task ID—don’t send another POST.

On this page

Set up the site and credential

  1. 1.

    Activate the site profile

    Set up the target hostname in the solvethree console and make sure its profile is active for your workspace. Sending a hostname and action in a task doesn’t create the profile.

  2. 2.

    Create a Header Auth credential in n8n

    Configure it to send an Authorization header whose value is Bearer followed by your workspace API key. Store the key in the credential, not in the task JSON.

Configure the create request

Name the HTTP Request node Create task. The polling node will reference this name to recover the original task ID.

Create task node configuration
Create task node configuration
FieldSetting
MethodPOST
URLhttps://api.solvethree.com/v1/tasks
AuthenticationGeneric Credential Type
Generic Auth TypeHeader Auth; select the credential you created
Send Query ParametersEnable; add waitMs with value 15000
Send BodyEnable; select JSON and use the body below
reCAPTCHA Enterprise · request shape
{
  "site": "accounts.example.com",
  "action": "login",
  "proxy": "http://user:[email protected]:8080",
  "requestId": "example_login_001"
}

Replace site, action, and proxy with the hostname, action, and proxy for your request. Send exactly one of proxy or proxyCandidates; this example uses one proxy. Don’t add type or url. The default reCAPTCHA type is Enterprise v3.

Replace the example requestId with a unique value for each new logical task. Keep that value unchanged if you need to recover this task after a timeout. It accepts 1–64 ASCII letters, numbers, underscores, or hyphens.

waitMs belongs in the URL query, not the JSON body. Set the HTTP request timeout above the requested 15-second wait to allow for network overhead; 30 seconds is a reasonable starting configuration, not a solve-time guarantee. The Header Auth credential supplies authentication, so you don’t need to duplicate it under Send Headers.

Branch on status, not HTTP success

Handle non-success HTTP responses before inspecting the task payload. For a successful response, connect an IF or Switch node and inspect {{ $json.status }}.

Route both create and poll responses through these checks
Route both create and poll responses through these checks
StatusNext action
readyLeave the polling loop and use the solution.
failedStop polling. Record errorCode and error for diagnosis.
pending or solvingCheck the polling deadline, then wait and GET the existing task.

For a ready reCAPTCHA task, submit the returned token using the returned userAgent and secChUa identity and the proxy that succeeded. A ready task means a solution was generated; it doesn’t establish that the website accepted the subsequent request.

Failed solves are refunded. Diagnose the reported error rather than retrying unchanged inputs or assuming the workspace has insufficient credit.

Wait, then GET the original ID

  1. 1.

    Save a fixed deadline

    Before Create task runs, store a polling deadline in the workflow—for example, two minutes after creation starts. This is your workflow’s stopping policy, not a solvethree API limit. Keep the deadline outside the HTTP response so later responses don’t overwrite it.

  2. 2.

    Gate each polling pass

    For pending or solving, use an IF node to compare the current time with the saved deadline. If it has expired, end the loop and retain the task ID. Otherwise, use a Wait node to pause for two seconds, then check the deadline again before the GET.

  3. 3.

    Retrieve the existing task

    Configure a second HTTP Request node with the settings below. Route its response back through the same status branch. Never route the polling branch back to Create task.

Polling HTTP Request node configuration
Polling HTTP Request node configuration
FieldSetting
MethodGET
URLhttps://api.solvethree.com/v1/tasks/{{ $('Create task').item.json.id }}
AuthenticationGeneric Credential Type
Generic Auth TypeHeader Auth; select the same credential
Send Query ParametersEnable; add waitMs with value 15000
Send BodyDisable

The task ID expression is {{ $('Create task').item.json.id }}. It reads id from the named create node even when the latest item contains a poll response or other workflow data. Keep the node name in the expression consistent with your workflow.

GET accepts a wait of up to 15 seconds. Give this HTTP request the same timeout allowance as the create request. The deadline stops new polling attempts; an already-running request can finish after it.

The equivalent GET request outside n8n is:

Task API · retrieve an existing task
curl --fail-with-body --max-time 30 \
  "https://api.solvethree.com/v1/tasks/$TASK_ID?waitMs=15000" \
  -H "Authorization: Bearer $SOLVETHREE_API_KEY"

Recover a timed-out POST without creating another task

A connection timeout doesn’t prove that creation failed. If you received an ID, retrieve that task. If you didn’t, repeat the POST with the same task inputs and the same requestId to recover the existing task. Reusing that ID with different task inputs causes a conflict.

Likewise, reaching your polling deadline is a local stop condition, not a failed task status. Keep the original ID so a later execution can retrieve it instead of paying for another solve.

Run your first task.

Start with $5 in workspace credit.

Create a workspace