A API da CaptchaAI aceita as duas coisas — formulário (application/x-www-form-urlencoded) e JSON — e devolve exatamente o mesmo resultado nos dois casos. Não existe formato "mais rápido" nem "mais preciso": a escolha certa depende da sua stack, não da taxa de resolução do CAPTCHA.
Isso importa na prática para quem está integrando automação de testes. Se sua suíte de QA já roda em Node.js com TypeScript, o corpo em JSON evita conversões manuais de objeto para query string. Se você mantém workers de automação em Python legado — ou está migrando uma integração antiga com o 2Captcha —, o formulário costuma ser a opção com menos atrito, inclusive quando os workers rodam na região sa-east-1 da AWS (São Paulo): a escolha de formato não muda a latência de rede nem o tempo de resolução.
Este guia mostra as diferenças reais entre os formatos, qual escolher em cada cenário e como evitar os erros mais comuns de quem mistura os dois no mesmo projeto.
Diferenças técnicas entre JSON e formulário
| Fator | Formulário codificado | JSON |
|---|---|---|
| Tipo de conteúdo | application/x-www-form-urlencoded |
application/json |
| Estrutura de dados | Pares chave-valor simples | Permite objetos aninhados |
| Dados binários | Upload multipart para arquivos | Base64 dentro do campo body |
| Suporte a arrays | Limitado | Nativo |
| Palavra-chave em Python | data={} |
json={} |
| Node.js | URLSearchParams / querystring |
JSON.stringify() |
| Legibilidade | Direto para parâmetros simples | Melhor para dados aninhados |
| Compatibilidade | Funciona em qualquer stack | Funciona em qualquer stack |
Na prática, a linha que mais pesa na decisão é a de dados binários — se o seu fluxo envolve upload de imagem, veja a seção sobre CAPTCHA de imagem mais abaixo.
Qual formato escolher em cada cenário
| Cenário | Recomendado | Por quê |
|---|---|---|
| Scripts simples e pontuais | Formulário codificado | Mais direto, sem dependências extras |
| Integração com API REST | JSON | Segue o padrão que a maioria das APIs modernas usa |
| Upload de arquivos | Formulário multipart | Envio binário direto, sem conversão |
| Imagens grandes em base64 | Formulário codificado | Lida melhor com payloads grandes |
| TypeScript / JS moderno | JSON | Suporte nativo a objetos |
| Integração com sistema legado | Formulário codificado | Compatibilidade universal |
| Migração do 2Captcha | Formulário codificado | Mesmo formato que o 2Captcha já usa |
Sem um cenário claro — por exemplo, um script Python simples que só envia um reCAPTCHA v2 e consulta o resultado —, comece pelo formulário codificado: é a opção com menos peças móveis, e migrar para JSON depois é uma mudança pequena.
Como enviar cada formato
Formulário codificado (o padrão da API)
É o formato usado pela API original, o mesmo que o 2Captcha aceita desde sempre:
import requests
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
Tipo de conteúdo: application/x-www-form-urlencoded
Corpo em JSON
Se sua aplicação já fala JSON nativamente, envie o mesmo payload como objeto — a CaptchaAI aceita os dois campos exatamente iguais, só muda o encoding:
import requests
resp = requests.post("https://ocr.captchaai.com/in.php", json={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
Tipo de conteúdo: application/json
Formato de resposta: sempre inclua json=1
Sem json=1, a resposta da API vem em texto simples — algo como "OK|12345678", que exige parsing manual por posição de caractere. Com json=1 no payload, a resposta sai estruturada, independentemente de você ter enviado a requisição como formulário ou como JSON:
# Without json=1 — plain text response
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
})
# Response: "OK|12345678"
# With json=1 — JSON response
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
# Response: {"status": 1, "request": "12345678"}
Parsear o texto simples na unha é uma fonte comum de bugs bobos em pipeline de automação. Trate json=1 como padrão em qualquer integração nova.
Exemplos completos em Python
Envio e consulta seguem o mesmo padrão nos dois formatos — a única diferença real está na chamada de envio. A consulta sempre usa GET com parâmetros de URL.
Formulário codificado
import requests
# Submit
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
task_id = resp.json()["request"]
# Poll (always GET with query params)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1,
})
Corpo JSON
import requests
# Submit with JSON
resp = requests.post("https://ocr.captchaai.com/in.php", json={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
task_id = resp.json()["request"]
# Poll (same as form-encoded — GET with params)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1,
})
Exemplos completos em Node.js
Em Node.js a diferença de sintaxe é mais visível: o formulário exige serializar o objeto manualmente com querystring, enquanto o JSON aceita o objeto direto no corpo da requisição.
Formulário codificado
const axios = require('axios');
const qs = require('querystring');
// Submit
const resp = await axios.post(
'https://ocr.captchaai.com/in.php',
qs.stringify({
key: 'YOUR_API_KEY',
method: 'userrecaptcha',
googlekey: 'SITE_KEY',
pageurl: 'https://example.com',
json: 1,
})
);
const taskId = resp.data.request;
Corpo JSON
const axios = require('axios');
// Submit with JSON
const resp = await axios.post(
'https://ocr.captchaai.com/in.php',
{
key: 'YOUR_API_KEY',
method: 'userrecaptcha',
googlekey: 'SITE_KEY',
pageurl: 'https://example.com',
json: 1,
}
);
const taskId = resp.data.request;
CAPTCHA de imagem: formulário multipart vs JSON com base64
Para CAPTCHA de imagem, a escolha do formato pesa mais, porque agora existe dado binário no meio do caminho. Você tem três rotas equivalentes:
Formulário com upload de arquivo (multipart)
A rota mais direta quando o arquivo já está em disco:
# File upload — form-encoded with multipart
resp = requests.post("https://ocr.captchaai.com/in.php",
data={
"key": "YOUR_API_KEY",
"method": "post",
"json": 1,
},
files={
"file": open("captcha.png", "rb"),
},
)
JSON com Base64
Útil quando a imagem já está em memória (por exemplo, capturada de um <canvas> ou de um response de rede) e você prefere manter tudo em um único corpo JSON:
import base64
# Base64 in JSON body
with open("captcha.png", "rb") as f:
body = base64.b64encode(f.read()).decode()
resp = requests.post("https://ocr.captchaai.com/in.php", json={
"key": "YOUR_API_KEY",
"method": "base64",
"body": body,
"json": 1,
})
Formulário com Base64
A mesma string base64, só que enviada como campo de formulário em vez de corpo JSON:
# Base64 in form data
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "base64",
"body": body,
"json": 1,
})
Para imagens grandes, o formulário codificado costuma lidar melhor com o payload — a codificação base64 já aumenta o tamanho do arquivo em cerca de 33%, e algumas bibliotecas HTTP têm limites de corpo JSON mais conservadores.
Erros comuns e como evitar
| Erro | Problema | Correção |
|---|---|---|
Usar json={} sem incluir "json": 1 no payload |
A resposta volta em texto simples | Sempre inclua "json": 1 no corpo |
Misturar data= e json= na mesma chamada com requests |
A requisição sai malformada | Escolha um dos dois, nunca os dois juntos |
| Esquecer o header Content-Type | O servidor não consegue interpretar o corpo | Deixe a biblioteca HTTP definir o header automaticamente |
| Enviar corpo JSON para o endpoint de consulta | /res.php só aceita parâmetros via GET |
Sempre use GET com query params para consultar o resultado |
Perguntas frequentes
O formato da requisição influencia no consumo do plano?
Não. A CaptchaAI cobra por thread ativa, não por chamada de API — o formato da requisição (JSON ou formulário) não afeta o consumo do seu plano nem a velocidade de resolução.
Preciso definir o header Content-Type manualmente?
Normalmente não. Deixe a biblioteca HTTP (requests, axios etc.) definir o header automaticamente com base em como você montou a chamada. Setar manualmente só costuma ser necessário em clientes HTTP de baixo nível.
JSON funciona para enviar imagem em base64?
Sim. Para CAPTCHA de imagem, envie o arquivo como string base64 no campo body ao usar JSON — é a alternativa ao upload multipart do formulário, útil quando a imagem já está em memória.
Posso enviar com JSON e consultar com parâmetros de URL?
Sim. A consulta (/res.php) sempre usa GET com query params, independentemente de como você enviou a tarefa original. As duas chamadas são independentes uma da outra.
Migrando do 2Captcha, qual formato devo usar?
Fique com o formulário codificado. A API original do 2Captcha só aceita esse formato; o suporte a JSON é um adicional da CaptchaAI, então manter o formulário reduz o atrito da migração.
Guias relacionados
Escolha o formato que fizer mais sentido para a sua stack — teste a API da CaptchaAI e comece a integrar ainda hoje.