CAPSOLVER
Blog
How to Solve ImageToText Using CapSolver and n8n

How to Solve ImageToText Using CapSolver and n8n

Logo of CapSolver

Ethan Collins

Pattern Recognition Specialist

18-Mar-2026

Image-based CAPTCHAs are everywhere โ€” login forms, registration pages, ticketing sites, and government portals. They show a distorted image of letters, numbers, or a mix of both, and require the user to type what they see. Automating these with traditional tools means building your own OCR pipeline, dealing with noise filters, and handling edge cases for every font and distortion style.

What if you could solve image CAPTCHAs automatically inside your n8n workflows โ€” whether you're building a reusable solver API or automating a form submission that requires reading a captcha image โ€” all without training a single model?

In this guide, you'll learn how to combine n8n (a visual workflow automation tool) with CapSolver (an AI-powered captcha solving service) to solve Image To Text captchas on demand โ€” either as a standalone API endpoint or as a step inside any automation workflow.

What you'll build:

Solver API โ€” a reusable endpoint your other tools can call:

  • An Image To Text solver API that accepts a base64 image and returns recognized text

Direct-use workflow โ€” CapSolver embedded as a step inside a larger automation:

  • A form automation that fetches a captcha image from a target site, converts it to base64, solves it with CapSolver, and submits the form with the recognized text

What is Image To Text (ImageToTextTask)?

Image To Text is CapSolver's OCR-based recognition service. You send a base64-encoded image of a captcha, and CapSolver returns the recognized text โ€” letters, numbers, or both โ€” immediately.

This is fundamentally different from other CapSolver operations like reCAPTCHA or Turnstile:

Feature Image To Text (Recognition) reCAPTCHA / Turnstile (Token)
Resource type Recognition Token
Input Base64 image Website URL + site key
Result Recognized text (instant) Token (requires polling)
Proxy needed No Depends on task type
Use case Read distorted text from an image Generate a verification token

The key distinction is that Recognition operations return results instantly โ€” there's no task creation followed by polling. You send the image, CapSolver reads it, and the text comes back in a single request-response cycle.

Required Parameters

Parameter Value Description
body Base64 string The captcha image, base64-encoded. No newlines, no data:image/...;base64, prefix โ€” just the raw base64 string
module "common" The recognition module. "common" handles general alphanumeric OCR

Optional Parameters

Parameter Description
websiteURL The URL of the page where the captcha appears (helps CapSolver optimize recognition)
images (1-9) Additional images for the "number" module when solving multi-image numeric captchas

Module Types

Module Purpose
common General OCR โ€” letters, numbers, mixed characters. The default for most captchas
number Numeric-only captchas. Supports batch solving with up to 9 additional images via images parameter

Prerequisites

Before getting started, make sure you have the following:

  1. An n8n instance โ€” Either self-hosted or n8n Cloud
  2. A CapSolver account โ€” Sign up here and get your API key
  3. The CapSolver n8n node โ€” Already available as an official node in n8n (no installation needed)

Important: Make sure you have sufficient balance in your CapSolver account. ImageToText tasks consume credits based on usage.


Setting Up CapSolver in n8n

CapSolver is available as an official integration in n8n โ€” no community node installation required. You can find it directly in the node panel when building your workflows.

Since it's an official integration, you need to create a credential in n8n so that the CapSolver node can authenticate with your account.

Step 1: Open the Credentials Page

Go to your n8n instance and navigate to Settings -> Credentials. You'll see all your configured credentials here.

n8n credentials page showing CapSolver account

Step 2: Create the CapSolver Credential

  1. Click Create credential (top right)
  2. Search for "CapSolver" and select CapSolver API
  3. Enter your API Key โ€” copy it directly from the CapSolver Dashboard
  4. Leave Allowed HTTP Request Domains set to All (default)
  5. Click Save

n8n will automatically test the connection. You should see a green "Connection tested successfully" banner confirming your API key is valid.

CapSolver credential configuration with successful connection test

Important: Every CapSolver node in your workflows will reference this credential. You only need to create it once โ€” all your solver workflows will share the same credential.

Now you're ready to build your Image To Text solver workflow!


Understanding Base64 Encoding for Captcha Images

Before diving into the workflows, it's important to understand the base64 requirements for ImageToTextTask. This is the most common source of errors.

What CapSolver Expects

The body parameter must contain a clean base64 string โ€” the raw encoded bytes of the image file. Specifically:

  • No data: prefix โ€” if you have data:image/png;base64,iVBORw0KGgo..., you must strip the data:image/png;base64, part
  • No newlines โ€” the base64 string must be a single continuous line with no \n characters
  • No whitespace โ€” no spaces, tabs, or other whitespace characters

How to Get a Clean Base64 String in n8n

When you fetch an image with an HTTP Request node in n8n, the response arrives as binary data. To convert it to base64 for CapSolver, use a Code node:

javascript Copy
// Convert binary image data to clean base64
const binaryData = $input.first().binary.data;
const base64String = binaryData.data; // Already base64 in n8n's binary format

// Strip the data: prefix if present (safety check)
const cleanBase64 = base64String.replace(/^data:image\/\w+;base64,/, '');

// Remove any newlines
const finalBase64 = cleanBase64.replace(/\n/g, '');

return [{ json: { body: finalBase64 } }];

Common Mistakes

Mistake Result
Sending data:image/png;base64,... CapSolver rejects the body as invalid
Base64 string contains newlines CapSolver cannot decode the image
Sending the image URL instead of base64 Wrong parameter โ€” body expects base64, not a URL
Sending an empty string CapSolver returns an error

Workflow 1: Image To Text Solver API

This workflow creates a POST API endpoint that accepts a base64 captcha image and returns the recognized text.

How It Works

The workflow consists of six nodes:

  1. Receive Solver Request โ€” Webhook that receives POST requests with image data
  2. Validate Image Input โ€” Code node that checks body exists and is valid base64
  3. Solve Image Captcha โ€” CapSolver node using Resource=Recognition, Operation=Image To Text
  4. Image Captcha Error? โ€” IF node that branches on whether solving failed
  5. Respond to Webhook โ€” Returns the recognized text on success
  6. Respond to Webhook Error โ€” Returns the error message on failure

Node Configuration

1. Receive Solver Request (Webhook)

Setting Value
HTTP Method POST
Path solver-image-to-text
Respond Response Node

This creates an endpoint at: https://your-n8n-instance.com/webhook/solver-image-to-text

2. Validate Image Input (Code)

This node checks that the request body contains a valid body parameter and strips any accidental data: prefix or newlines:

javascript Copy
const body = $input.first().json.body;

if (!body || !body.body) {
  return [{ json: { error: 'Missing required field: body (base64 encoded image)' } }];
}

let imageBase64 = String(body.body);

// Strip data: prefix if accidentally included
imageBase64 = imageBase64.replace(/^data:image\/\w+;base64,/, '');

// Remove newlines and whitespace
imageBase64 = imageBase64.replace(/[\n\r\s]/g, '');

// Basic base64 validation
if (!/^[A-Za-z0-9+/]+=*$/.test(imageBase64)) {
  return [{ json: { error: 'Invalid base64 encoding in body field' } }];
}

return [{
  json: {
    body: imageBase64,
    module: body.module || 'common'
  }
}];

3. Solve Image Captcha (CapSolver)

Parameter Value Description
Resource Recognition Selects the Recognition resource (not Token)
Operation Image To Text The ImageToTextTask operation
Body {{ $json.body }} The clean base64 image string
Module {{ $json.module }} The recognition module (default: common)

Important: In the CapSolver node, you must select Resource = Recognition first, then Operation = Image To Text. This is different from Token operations like reCAPTCHA or Turnstile. Also select your CapSolver credentials in this node.

4. Image Captcha Error? (IF)

Setting Value
Condition ={{ $json.error }} is not empty
True branch Routes to the Error Respond to Webhook node
False branch Routes to the Success Respond to Webhook node

The CapSolver node continues on error (onError: continueRegularOutput), so failures arrive here as { "error": "..." } rather than crashing the workflow.

5. Respond to Webhook (Success)

Setting Value
Respond With JSON
Response Body ={{ JSON.stringify($json.data) }}

6. Respond to Webhook Error

Setting Value
Respond With JSON
Response Body ={{ JSON.stringify({ error: $json.error }) }}

Error messages follow one of two formats:

Failure point Format
Task creation rejected (wrong key, no balance, invalid base64, etc.) {"error": "Failed to create task: Request failed with status code 400"}
Image could not be recognized {"error": "Solve failed: <reason>"}

Test It

Send a POST request to your webhook endpoint:

bash Copy
curl -X POST https://your-n8n-instance.com/webhook/solver-image-to-text \
  -H "Content-Type: application/json" \
  -d '{
    "body": "iVBORw0KGgoAAAANSUhEUgAA...",
    "module": "common"
  }'

Expected Response:

json Copy
{
  "solution": {
    "text": "xK7mQ"
  },
  "status": "ready"
}

The solution.text field contains the recognized captcha text. This is the value you would type into a captcha input field.

Import This Workflow

Copy the JSON below and import it into n8n via Menu -> Import from JSON:

Click to expand workflow JSON
json Copy
{
  "name": "Image To Text โ€” Solver API",
  "nodes": [
    {
      "parameters": {
        "content": "## Image To Text โ€” Solver API\n\n**Who it's for:** Developers who need an OCR-based captcha solving endpoint for their applications.\n\n**What it does:** Accepts a base64-encoded captcha image via webhook, validates the input, solves it using CapSolver's ImageToTextTask recognition, and returns the recognized text.\n\n**How it works:**\n1. Webhook receives a POST with `body` (base64 image) and optional `module`\n2. Code node validates the base64 input and strips any data: prefix\n3. CapSolver Recognition node solves the image captcha instantly\n4. IF node checks for errors\n5. Response returns recognized text or error details\n\n**Setup:**\n1. Add your CapSolver API key under **Settings โ†’ Credentials**\n2. Activate the workflow to enable the webhook endpoint\n3. POST base64 images to `/webhook/solver-image-to-text`",
        "height": 480,
        "width": 460,
        "color": 1
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-620, -280],
      "id": "sticky-itt-main-001",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "### Receive & Validate\nWebhook accepts POST with base64 image. Code node validates and cleans the input.",
        "height": 480,
        "width": 700,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-140, -280],
      "id": "sticky-itt-section-002",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "### Solve Image Captcha\nCapSolver Recognition node โ€” returns recognized text instantly (no polling).",
        "height": 480,
        "width": 400,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [580, -280],
      "id": "sticky-itt-section-003",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "### Error Check & Response\nIF node branches on error. Success returns recognized text, failure returns error details.",
        "height": 480,
        "width": 900,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [1000, -280],
      "id": "sticky-itt-section-004",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "### Validation Logic\nStrips data: prefix, removes newlines, checks base64 format.",
        "height": 480,
        "width": 400,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [160, -280],
      "id": "sticky-itt-section-005",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "content": "### Response Handling\nSuccess: returns solution with recognized text. Error: returns error message.",
        "height": 480,
        "width": 500,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [1420, -280],
      "id": "sticky-itt-section-006",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "solver-image-to-text",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [-100, 0],
      "id": "itt-11111111-1111-1111-1111-111111111101",
      "name": "Receive Solver Request",
      "webhookId": "itt-aaaa-bbbb-cccc-dddd-111111111101"
    },
    {
      "parameters": {
        "jsCode": "const body = $input.first().json.body;\n\nif (!body || !body.body) {\n  return [{ json: { error: 'Missing required field: body (base64 encoded image)' } }];\n}\n\nlet imageBase64 = String(body.body);\n\n// Strip data: prefix if accidentally included\nimageBase64 = imageBase64.replace(/^data:image\\/\\w+;base64,/, '');\n\n// Remove newlines and whitespace\nimageBase64 = imageBase64.replace(/[\\n\\r\\s]/g, '');\n\n// Basic base64 validation\nif (!/^[A-Za-z0-9+\\/]+=*$/.test(imageBase64)) {\n  return [{ json: { error: 'Invalid base64 encoding in body field' } }];\n}\n\nreturn [{\n  json: {\n    body: imageBase64,\n    module: body.module || 'common'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [200, 0],
      "id": "itt-11111111-1111-1111-1111-111111111102",
      "name": "Validate Image Input"
    },
    {
      "parameters": {
        "resource": "recognition",
        "operation": "Image To Text",
        "body": "={{ $json.body }}",
        "module": "={{ $json.module }}"
      },
      "type": "n8n-nodes-capsolver.capSolver",
      "typeVersion": 1,
      "position": [620, 0],
      "id": "itt-11111111-1111-1111-1111-111111111103",
      "name": "Solve Image Captcha",
      "onError": "continueRegularOutput",
      "credentials": {
        "capSolverApi": {
          "id": "YOUR_CREDENTIAL_ID",
          "name": "CapSolver account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "itt-err-001",
              "leftValue": "={{ $json.error }}",
              "operator": {
                "type": "string",
                "operation": "isNotEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [1040, 0],
      "id": "itt-11111111-1111-1111-1111-111111111104",
      "name": "Image Captcha Error?"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ error: $json.error }) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [1460, -100],
      "id": "itt-11111111-1111-1111-1111-111111111105",
      "name": "Respond to Webhook Error"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json.data) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [1460, 100],
      "id": "itt-11111111-1111-1111-1111-111111111106",
      "name": "Respond to Webhook"
    }
  ],
  "connections": {
    "Receive Solver Request": {
      "main": [
        [
          {
            "node": "Validate Image Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Image Input": {
      "main": [
        [
          {
            "node": "Solve Image Captcha",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Solve Image Captcha": {
      "main": [
        [
          {
            "node": "Image Captcha Error?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image Captcha Error?": {
      "main": [
        [
          {
            "node": "Respond to Webhook Error",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  }
}

Workflow 2: Form Automation โ€” Solve Image Captcha & Submit

This workflow automates end-to-end form submission on a site protected by an image captcha. It fetches the captcha image from the target site, converts it to base64, solves it with CapSolver, and submits the form with the recognized text.

It supports two activation modes:

  • Schedule: run automatically every 6 hours
  • Webhook: trigger on demand and return the result as JSON

How It Works

Schedule path:

Copy
Every 6 Hours โ†’ Set Target Config โ†’ Fetch Captcha Image โ†’ Convert to Base64
  โ†’ Solve Image Captcha โ†’ Submit Form with Solution โ†’ Check Submission Result
  โ†’ Mark Success / Mark Failed

Webhook path:

Copy
Webhook Trigger โ†’ Set Target Config [Webhook] โ†’ Fetch Captcha Image [Webhook]
  โ†’ Convert to Base64 [Webhook] โ†’ Solve Image Captcha [Webhook]
  โ†’ Submit Form with Solution [Webhook] โ†’ Check Submission Result [Webhook]
  โ†’ Mark Success [Webhook] / Mark Failed [Webhook] โ†’ Respond to Webhook

Node Configuration

1. Trigger Nodes

Schedule Trigger:

Setting Value
Interval Every 6 hours

Webhook Trigger:

Setting Value
HTTP Method POST
Path image-captcha-form
Respond Response Node

2. Set Target Config

This node stores all configuration for the target site in one place:

Config Field Purpose
captchaImageURL The URL that serves the captcha image (e.g., https://example.com/captcha.png)
formActionURL The endpoint that receives the form POST
captchaFieldName The form field name for the captcha answer (e.g., captcha, captcha_code, verification)
module The CapSolver recognition module (common for general OCR, number for numeric only)
userAgent The user agent string to send with requests

3. Fetch Captcha Image (HTTP Request)

Setting Value
Method GET
URL ={{ $json.captchaImageURL }}
Response Format File (binary)

This downloads the captcha image as binary data. The response will be available in $binary.data.

Note: Some sites require cookies or session headers to serve the captcha image. If the captcha is session-bound, you may need to add a prior request to get the session cookie and pass it along.

4. Convert to Base64 (Code)

javascript Copy
// Convert the binary captcha image to a clean base64 string
const binaryData = $input.first().binary.data;
const base64String = binaryData.data;

// Strip data: prefix if present
const cleanBase64 = base64String.replace(/^data:image\/\w+;base64,/, '');

// Remove any newlines
const finalBase64 = cleanBase64.replace(/\n/g, '');

// Pass along the target config from the Set Target Config node
const config = $('Set Target Config').first().json;

return [{
  json: {
    body: finalBase64,
    module: config.module || 'common',
    captchaFieldName: config.captchaFieldName,
    formActionURL: config.formActionURL,
    userAgent: config.userAgent
  }
}];

5. Solve Image Captcha (CapSolver Recognition)

Parameter Value
Resource Recognition
Operation Image To Text
Body {{ $json.body }}
Module {{ $json.module }}

This returns the recognized text immediately in $json.data.solution.text.

6. Submit Form with Solution (HTTP Request)

Setting Value
Method POST
URL ={{ $('Set Target Config').first().json.formActionURL }}
Content Type form-urlencoded
Body Fields Form fields + captcha answer

The captcha answer goes into the field specified by captchaFieldName:

Field Value
username your-username
password your-password
{{ captchaFieldName }} ={{ $json.data.solution.text }}

7. Check Submission Result (IF)

Setting Value
Condition {{ $json.statusCode < 400 }} โ€” checks the HTTP response indicates success
True branch Mark Success
False branch Mark Failed

Test It

Send a POST request to trigger the form automation:

bash Copy
curl -X POST https://your-n8n-instance.com/webhook/image-captcha-form \
  -H "Content-Type: application/json" \
  -d '{}'

Expected Response (success):

json Copy
{
  "action": "form_submission",
  "status": "success",
  "captchaText": "xK7mQ",
  "message": "Form submitted successfully with solved captcha",
  "submittedAt": "2026-03-16T12:00:00.000Z"
}

Expected Response (failure):

json Copy
{
  "action": "form_submission",
  "status": "failed",
  "statusCode": 403,
  "message": "Form submission was rejected by the target site",
  "submittedAt": "2026-03-16T12:00:00.000Z"
}

Import This Workflow

Copy the JSON below and import it into n8n via Menu -> Import from JSON:

Click to expand workflow JSON
json Copy
{
  "name": "Form Automation โ€” Solve Image Captcha & Submit",
  "nodes": [
    {
      "parameters": {
        "content": "## Form Automation โ€” Solve Image Captcha & Submit\n\n**Who it's for:** Teams automating form submissions on sites protected by image-based CAPTCHAs.\n\n**What it does:** Fetches a captcha image from the target site, converts it to base64, solves it using CapSolver OCR, and submits the form with the recognized text.\n\n**How it works:**\n1. Schedule (every 6h) or Webhook triggers the flow\n2. Set Target Config defines the target URLs, field names, and module\n3. HTTP Request fetches the captcha image as binary\n4. Code node converts binary to clean base64\n5. CapSolver Recognition solves the image instantly\n6. HTTP Request submits the form with the recognized text\n7. IF node checks submission success\n\n**Setup:**\n1. Add your CapSolver API key under **Settings โ†’ Credentials**\n2. Update Set Target Config with your target site details\n3. Update form fields in Submit Form to match the target\n4. Activate the workflow",
        "height": 480,
        "width": 460,
        "color": 1
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-920, -380],
      "id": "sticky-fa-main-001",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "### Schedule Path\nRuns automatically every 6 hours. Fetches captcha, solves, and submits the form.",
        "height": 480,
        "width": 2800,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-440, -280],
      "id": "sticky-fa-section-002",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "### Webhook Path\nOn-demand trigger โ€” same logic, returns result as JSON response.",
        "height": 480,
        "width": 2800,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-440, 240],
      "id": "sticky-fa-section-003",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "### Fetch & Convert\nDownload captcha image, convert binary to base64.",
        "height": 480,
        "width": 700,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [170, -280],
      "id": "sticky-fa-section-004",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "### Solve & Submit\nCapSolver reads the image, form is submitted with the answer.",
        "height": 480,
        "width": 700,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [890, -280],
      "id": "sticky-fa-section-005",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "content": "### Result Handling\nCheck HTTP status, mark success or failure.",
        "height": 480,
        "width": 700,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [1610, -280],
      "id": "sticky-fa-section-006",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [-400, 0],
      "id": "fa-22222222-2222-2222-2222-222222222201",
      "name": "Every 6 Hours"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-cfg-001",
              "name": "captchaImageURL",
              "value": "https://YOUR-TARGET-SITE.com/captcha.png",
              "type": "string"
            },
            {
              "id": "fa-cfg-002",
              "name": "formActionURL",
              "value": "https://YOUR-TARGET-SITE.com/submit",
              "type": "string"
            },
            {
              "id": "fa-cfg-003",
              "name": "captchaFieldName",
              "value": "captcha",
              "type": "string"
            },
            {
              "id": "fa-cfg-004",
              "name": "module",
              "value": "common",
              "type": "string"
            },
            {
              "id": "fa-cfg-005",
              "name": "userAgent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-96, 0],
      "id": "fa-22222222-2222-2222-2222-222222222202",
      "name": "Set Target Config"
    },
    {
      "parameters": {
        "url": "={{ $json.captchaImageURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "user-agent",
              "value": "={{ $json.userAgent }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [208, 0],
      "id": "fa-22222222-2222-2222-2222-222222222203",
      "name": "Fetch Captcha Image"
    },
    {
      "parameters": {
        "jsCode": "// Convert the binary captcha image to a clean base64 string\nconst binaryData = $input.first().binary.data;\nconst base64String = binaryData.data;\n\n// Strip data: prefix if present\nconst cleanBase64 = base64String.replace(/^data:image\\/\\w+;base64,/, '');\n\n// Remove any newlines\nconst finalBase64 = cleanBase64.replace(/\\n/g, '');\n\n// Pass along the target config\nconst config = $('Set Target Config').first().json;\n\nreturn [{\n  json: {\n    body: finalBase64,\n    module: config.module || 'common',\n    captchaFieldName: config.captchaFieldName,\n    formActionURL: config.formActionURL,\n    userAgent: config.userAgent\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [512, 0],
      "id": "fa-22222222-2222-2222-2222-222222222204",
      "name": "Convert to Base64"
    },
    {
      "parameters": {
        "resource": "recognition",
        "operation": "Image To Text",
        "body": "={{ $json.body }}",
        "module": "={{ $json.module }}"
      },
      "type": "n8n-nodes-capsolver.capSolver",
      "typeVersion": 1,
      "position": [930, 0],
      "id": "fa-22222222-2222-2222-2222-222222222205",
      "name": "Solve Image Captcha",
      "onError": "continueRegularOutput",
      "credentials": {
        "capSolverApi": {
          "id": "YOUR_CREDENTIAL_ID",
          "name": "CapSolver account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Set Target Config').first().json.formActionURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "content-type",
              "value": "application/x-www-form-urlencoded"
            },
            {
              "name": "user-agent",
              "value": "={{ $('Set Target Config').first().json.userAgent }}"
            }
          ]
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "bodyParameters": {
          "parameters": [
            {
              "name": "username",
              "value": "YOUR_USERNAME"
            },
            {
              "name": "password",
              "value": "YOUR_PASSWORD"
            },
            {
              "name": "={{ $('Set Target Config').first().json.captchaFieldName }}",
              "value": "={{ $json.data.solution.text }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [1234, 0],
      "id": "fa-22222222-2222-2222-2222-222222222206",
      "name": "Submit Form with Solution"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "fa-if-001",
              "leftValue": "={{ $json.statusCode }}",
              "rightValue": 400,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [1538, 0],
      "id": "fa-22222222-2222-2222-2222-222222222207",
      "name": "Check Submission Result"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-ms-001",
              "name": "action",
              "value": "form_submission",
              "type": "string"
            },
            {
              "id": "fa-ms-002",
              "name": "status",
              "value": "success",
              "type": "string"
            },
            {
              "id": "fa-ms-003",
              "name": "captchaText",
              "value": "={{ $('Solve Image Captcha').first().json.data.solution.text }}",
              "type": "string"
            },
            {
              "id": "fa-ms-004",
              "name": "message",
              "value": "Form submitted successfully with solved captcha",
              "type": "string"
            },
            {
              "id": "fa-ms-005",
              "name": "submittedAt",
              "value": "={{ new Date().toISOString() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1842, -80],
      "id": "fa-22222222-2222-2222-2222-222222222208",
      "name": "Mark Success"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-mf-001",
              "name": "action",
              "value": "form_submission",
              "type": "string"
            },
            {
              "id": "fa-mf-002",
              "name": "status",
              "value": "failed",
              "type": "string"
            },
            {
              "id": "fa-mf-003",
              "name": "statusCode",
              "value": "={{ $json.statusCode }}",
              "type": "number"
            },
            {
              "id": "fa-mf-004",
              "name": "message",
              "value": "Form submission was rejected by the target site",
              "type": "string"
            },
            {
              "id": "fa-mf-005",
              "name": "submittedAt",
              "value": "={{ new Date().toISOString() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1842, 120],
      "id": "fa-22222222-2222-2222-2222-222222222209",
      "name": "Mark Failed"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "image-captcha-form",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [-400, 520],
      "id": "fa-22222222-2222-2222-2222-222222222210",
      "name": "Webhook Trigger",
      "webhookId": "fa-aaaa-bbbb-cccc-dddd-222222222210",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-cfg-011",
              "name": "captchaImageURL",
              "value": "https://YOUR-TARGET-SITE.com/captcha.png",
              "type": "string"
            },
            {
              "id": "fa-cfg-012",
              "name": "formActionURL",
              "value": "https://YOUR-TARGET-SITE.com/submit",
              "type": "string"
            },
            {
              "id": "fa-cfg-013",
              "name": "captchaFieldName",
              "value": "captcha",
              "type": "string"
            },
            {
              "id": "fa-cfg-014",
              "name": "module",
              "value": "common",
              "type": "string"
            },
            {
              "id": "fa-cfg-015",
              "name": "userAgent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-96, 520],
      "id": "fa-22222222-2222-2222-2222-222222222211",
      "name": "Set Target Config [Webhook]"
    },
    {
      "parameters": {
        "url": "={{ $json.captchaImageURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "user-agent",
              "value": "={{ $json.userAgent }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [208, 520],
      "id": "fa-22222222-2222-2222-2222-222222222212",
      "name": "Fetch Captcha Image [Webhook]"
    },
    {
      "parameters": {
        "jsCode": "// Convert the binary captcha image to a clean base64 string\nconst binaryData = $input.first().binary.data;\nconst base64String = binaryData.data;\n\n// Strip data: prefix if present\nconst cleanBase64 = base64String.replace(/^data:image\\/\\w+;base64,/, '');\n\n// Remove any newlines\nconst finalBase64 = cleanBase64.replace(/\\n/g, '');\n\n// Pass along the target config\nconst config = $('Set Target Config [Webhook]').first().json;\n\nreturn [{\n  json: {\n    body: finalBase64,\n    module: config.module || 'common',\n    captchaFieldName: config.captchaFieldName,\n    formActionURL: config.formActionURL,\n    userAgent: config.userAgent\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [512, 520],
      "id": "fa-22222222-2222-2222-2222-222222222213",
      "name": "Convert to Base64 [Webhook]"
    },
    {
      "parameters": {
        "resource": "recognition",
        "operation": "Image To Text",
        "body": "={{ $json.body }}",
        "module": "={{ $json.module }}"
      },
      "type": "n8n-nodes-capsolver.capSolver",
      "typeVersion": 1,
      "position": [930, 520],
      "id": "fa-22222222-2222-2222-2222-222222222214",
      "name": "Solve Image Captcha [Webhook]",
      "onError": "continueRegularOutput",
      "credentials": {
        "capSolverApi": {
          "id": "YOUR_CREDENTIAL_ID",
          "name": "CapSolver account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Set Target Config [Webhook]').first().json.formActionURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "content-type",
              "value": "application/x-www-form-urlencoded"
            },
            {
              "name": "user-agent",
              "value": "={{ $('Set Target Config [Webhook]').first().json.userAgent }}"
            }
          ]
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "bodyParameters": {
          "parameters": [
            {
              "name": "username",
              "value": "YOUR_USERNAME"
            },
            {
              "name": "password",
              "value": "YOUR_PASSWORD"
            },
            {
              "name": "={{ $('Set Target Config [Webhook]').first().json.captchaFieldName }}",
              "value": "={{ $json.data.solution.text }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true
            }
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [1234, 520],
      "id": "fa-22222222-2222-2222-2222-222222222215",
      "name": "Submit Form with Solution [Webhook]"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "fa-if-002",
              "leftValue": "={{ $json.statusCode }}",
              "rightValue": 400,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [1538, 520],
      "id": "fa-22222222-2222-2222-2222-222222222216",
      "name": "Check Submission Result [Webhook]"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-ms-011",
              "name": "action",
              "value": "form_submission",
              "type": "string"
            },
            {
              "id": "fa-ms-012",
              "name": "status",
              "value": "success",
              "type": "string"
            },
            {
              "id": "fa-ms-013",
              "name": "captchaText",
              "value": "={{ $('Solve Image Captcha [Webhook]').first().json.data.solution.text }}",
              "type": "string"
            },
            {
              "id": "fa-ms-014",
              "name": "message",
              "value": "Form submitted successfully with solved captcha",
              "type": "string"
            },
            {
              "id": "fa-ms-015",
              "name": "submittedAt",
              "value": "={{ new Date().toISOString() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1842, 440],
      "id": "fa-22222222-2222-2222-2222-222222222217",
      "name": "Mark Success [Webhook]"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "fa-mf-011",
              "name": "action",
              "value": "form_submission",
              "type": "string"
            },
            {
              "id": "fa-mf-012",
              "name": "status",
              "value": "failed",
              "type": "string"
            },
            {
              "id": "fa-mf-013",
              "name": "statusCode",
              "value": "={{ $json.statusCode }}",
              "type": "number"
            },
            {
              "id": "fa-mf-014",
              "name": "message",
              "value": "Form submission was rejected by the target site",
              "type": "string"
            },
            {
              "id": "fa-mf-015",
              "name": "submittedAt",
              "value": "={{ new Date().toISOString() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1842, 640],
      "id": "fa-22222222-2222-2222-2222-222222222218",
      "name": "Mark Failed [Webhook]"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [2146, 520],
      "id": "fa-22222222-2222-2222-2222-222222222219",
      "name": "Respond to Webhook"
    }
  ],
  "connections": {
    "Every 6 Hours": {
      "main": [
        [
          {
            "node": "Set Target Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Target Config": {
      "main": [
        [
          {
            "node": "Fetch Captcha Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Captcha Image": {
      "main": [
        [
          {
            "node": "Convert to Base64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to Base64": {
      "main": [
        [
          {
            "node": "Solve Image Captcha",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Solve Image Captcha": {
      "main": [
        [
          {
            "node": "Submit Form with Solution",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit Form with Solution": {
      "main": [
        [
          {
            "node": "Check Submission Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Submission Result": {
      "main": [
        [
          {
            "node": "Mark Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Set Target Config [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Target Config [Webhook]": {
      "main": [
        [
          {
            "node": "Fetch Captcha Image [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Captcha Image [Webhook]": {
      "main": [
        [
          {
            "node": "Convert to Base64 [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to Base64 [Webhook]": {
      "main": [
        [
          {
            "node": "Solve Image Captcha [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Solve Image Captcha [Webhook]": {
      "main": [
        [
          {
            "node": "Submit Form with Solution [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit Form with Solution [Webhook]": {
      "main": [
        [
          {
            "node": "Check Submission Result [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Submission Result [Webhook]": {
      "main": [
        [
          {
            "node": "Mark Success [Webhook]",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark Failed [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Success [Webhook]": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Failed [Webhook]": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  }
}

Recognition vs. Token: Why Image To Text Is Different

If you've used the CapSolver n8n node for reCAPTCHA, Turnstile, or other challenge types, you've been using the Token resource. Image To Text uses the Recognition resource, and the difference matters:

Token Operations (reCAPTCHA, Turnstile, etc.)

  1. CapSolver creates a task on its servers
  2. The task runs asynchronously โ€” the node polls for the result
  3. Solving can take several seconds to over a minute
  4. The result is a token you submit to the target site for verification
  5. You need a websiteURL and websiteKey

Recognition Operations (Image To Text)

  1. CapSolver processes the image immediately in a single request
  2. No polling โ€” the result comes back in the same response
  3. Solving is near-instant (typically under 1 second)
  4. The result is recognized text you type into a captcha input field
  5. You need a base64 image, not a URL or site key

This is why the CapSolver n8n node has two separate resources:

Resource Operations
Token reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile, Cloudflare Challenge, GeeTest V3, GeeTest V4, DataDome, AWS WAF, MTCaptcha
Recognition Image To Text

When configuring the CapSolver node for Image To Text, make sure you select Resource = Recognition first โ€” this changes the available operations and parameters.


What You Will Probably Need to Change

These workflows are templates. On a real target, you should expect to customize:

1. The Captcha Image Source

The form automation template fetches the image from a single URL (captchaImageURL). In practice, the captcha image may be:

  • served from a dynamic URL that changes on each request
  • embedded in the page HTML as a base64 <img> tag
  • tied to a session cookie (so you need the cookie to get the matching image)
  • served with cache-busting query parameters

Many image captcha systems are session-bound โ€” the captcha image is linked to a server-side session. If you fetch the image in one request and submit the answer in another, you need to:

  • capture the session cookie from the image request
  • pass that same cookie when submitting the form
  • possibly extract a CSRF token from the page

3. The Captcha Field Name

Different sites use different form field names for the captcha answer:

Common field names
captcha
captcha_code
verification
captcha_text
answer
security_code

Inspect the form HTML to find the exact field name.

4. The Recognition Module

Most image captchas work with module: "common". But if the captcha contains only numbers, try module: "number" โ€” it's optimized for numeric recognition and may give better results.

5. Additional Form Fields

The template includes placeholder username and password fields. Your target may require:

  • different field names
  • additional hidden fields
  • CSRF tokens
  • referrer headers
  • specific cookies

Troubleshooting

"Not found ImageToTextTask access"

This error means your CapSolver account or package doesn't include ImageToText access. Check your CapSolver dashboard to verify your package includes this service.

CapSolver Returns Wrong Text

Image captcha recognition is not 100% accurate. If you're getting incorrect results:

  • Try a different module โ€” "common" vs "number" vs specific module IDs
  • Check that your base64 encoding is correct โ€” invalid encoding can produce garbled input
  • Verify the image is not corrupted or blank
  • Some heavily distorted captchas have lower success rates

"Invalid base64 encoding" or Empty Response

Common causes:

  • The data:image/...;base64, prefix was not stripped
  • Newlines are present in the base64 string
  • The image URL returned HTML instead of an image (check the Content-Type)
  • The HTTP Request node returned an error page, not the image

Session Mismatch

If the form submission always fails even with correct recognized text, the most likely cause is a session mismatch between the image fetch and the form submission. Ensure you're passing the same session cookies across both requests.

Form Submission Returns 403 or Captcha Error

This usually means:

  • The captcha answer was submitted too late (some captchas expire)
  • The session cookie was missing
  • The captcha field name is wrong
  • A CSRF token is missing
  • Additional hidden fields are required

Best Practices

  1. Submit the recognized text immediately โ€” image captchas often expire within 60-120 seconds.
  2. Preserve session cookies between the image fetch and form submission.
  3. Strip the data: prefix โ€” always clean your base64 before sending to CapSolver.
  4. Use the right module โ€” "common" for mixed alphanumeric, "number" for digits only.
  5. Validate the base64 in a Code node before sending to CapSolver to catch encoding errors early.
  6. Check the image โ€” if recognition fails, log the base64 string and decode it manually to verify it's a valid captcha image.
  7. Handle retries โ€” if the recognized text is rejected, you may want to add a retry loop that fetches a new captcha image and tries again.
  8. No proxy needed โ€” unlike Token operations, Image To Text doesn't require a proxy. The image data is sent directly to CapSolver's servers.

Ready to get started? Sign up for CapSolver and use bonus code n8n for an extra 8% bonus on your first recharge!

CapSolver bonus code banner

Conclusion

You've learned how to build an Image To Text solver API and a form automation workflow using n8n and CapSolver โ€” no traditional coding or OCR model training required.

In this guide, we covered:

  • How Image To Text differs from Token operations โ€” Recognition is instant, no polling, no proxy needed
  • Base64 encoding requirements โ€” clean strings only, no data: prefix, no newlines
  • An API solver endpoint that accepts base64 images and returns recognized text
  • A form automation workflow that fetches a captcha image, converts it, solves it, and submits the form
  • How to convert images to base64 in n8n using Code nodes
  • Best practices for session handling, module selection, and error management

The key takeaway: Image To Text is the simplest CapSolver operation to integrate โ€” you send a base64 image and get text back immediately. The challenge is usually in the surrounding workflow: fetching the image correctly, preserving session state, and submitting the answer to the right form field.

Tip: These workflows use Schedule + Webhook triggers, but you can swap the trigger node to any n8n trigger โ€” manual, app event, form submission, etc. After solving the captcha, use n8n's built-in nodes to save results to Google Sheets, databases, cloud storage, or send alerts via Telegram/Slack/Email.


Frequently Asked Questions

What is ImageToTextTask?

ImageToTextTask is CapSolver's OCR-based captcha recognition service. You send a base64-encoded image of a captcha, and CapSolver returns the recognized text โ€” letters, numbers, or both. It uses the Recognition resource in the CapSolver n8n node, which is different from the Token resource used for reCAPTCHA, Turnstile, and other challenge types.

How much does it cost to solve an image captcha?

Pricing varies based on usage. Check the CapSolver pricing page for current ImageToText rates. Image recognition tasks are generally among the most affordable CapSolver operations.

How long does it take to solve an image captcha?

Image To Text is a Recognition operation, which means results come back instantly โ€” typically under 1 second. There's no task creation or polling delay like with Token operations.

Do I need a proxy for Image To Text?

No. Unlike Token operations (reCAPTCHA, Turnstile, Cloudflare Challenge), Image To Text does not require a proxy. You're sending the image data directly to CapSolver โ€” there's no browser interaction or site visit involved.

What image formats are supported?

CapSolver accepts common image formats (PNG, JPEG, GIF, BMP) as base64-encoded data. The image should contain a visible captcha โ€” no blank, corrupted, or overly large images.

What does the module parameter do?

The module parameter tells CapSolver which recognition engine to use:

  • "common" โ€” General OCR for letters, numbers, and mixed characters. This is the default and works for most captchas.
  • "number" โ€” Optimized for numeric-only captchas. Also supports batch solving with up to 9 additional images.
  • "module_001" through "module_032" โ€” Specialized engines for specific captcha styles. Check the CapSolver documentation for details on each module.

Does CapSolver support case-sensitive recognition?

No. CapSolver's Image To Text recognition does not support case sensitivity. If the target site requires a case-sensitive captcha answer, the recognition result may not match. This is a known limitation.

Can I use this workflow with n8n Cloud?

Yes. This workflow works with both self-hosted n8n and n8n Cloud. The CapSolver node is already available as an official integration โ€” just add your API credentials.

How do I handle captchas that are session-bound?

Many sites tie the captcha image to a server session. To handle this:

  1. Make an initial request to the captcha page to get the session cookie
  2. Use that cookie when fetching the captcha image
  3. Pass the same cookie when submitting the form with the recognized text

In n8n, you can extract cookies from the HTTP Request response headers and pass them to subsequent requests.

What if CapSolver returns wrong text?

Image captcha recognition is not 100% accurate โ€” especially for heavily distorted or noisy images. If you're getting incorrect results:

  • Try a different module ("common", "number", or a specific module ID)
  • Verify your base64 encoding is correct
  • Add a retry loop that fetches a new captcha image on failure
  • Check the CapSolver documentation for module recommendations for specific captcha styles

CapSolver returned a token but the website still rejected it โ€” why?

For Image To Text, CapSolver returns recognized text, not a token. If the form submission is rejected:

  • Verify the captcha answer is correct by checking the solution.text value
  • Check session handling โ€” the captcha may have expired or the session cookie may be missing
  • Verify the form field name โ€” the captcha answer might need to go in a different field
  • Look for additional required fields โ€” CSRF tokens, hidden inputs, or timestamps
  • Check timing โ€” some captchas expire quickly, so submit the answer immediately after recognition

Compliance Disclaimer: The information provided on this blog is for informational purposes only. CapSolver is committed to compliance with all applicable laws and regulations. The use of the CapSolver network for illegal, fraudulent, or abusive activities is strictly prohibited and will be investigated. Our captcha-solving solutions enhance user experience while ensuring 100% compliance in helping solve captcha difficulties during public data crawling. We encourage responsible use of our services. For more information, please visit our Terms of Service and Privacy Policy.

More