Documentação da API
Versão 1.2.0 · Base URL: https://cv.empreflow.com.br
A SolveCaptcha API é um serviço de visão computacional baseado em GPU local (CUDA). Oferece três operações principais: classificação de imagens (ResNet50), detecção de CAPTCHA (OpenCV) e análise de grade reCAPTCHA (YOLOv8 + OCR).
Autenticação
Inclua sua chave de API no header X-API-Key de cada requisição.
X-API-Key: cvapi_sua_chave_aqui
Comportamento por cenário
| Situação | Resultado |
|---|---|
| Sem X-API-Key | Acesso permitido (uso registrado como "internal", sem débito) |
| Chave válida com créditos | Créditos debitados, uso registrado |
| Chave inválida | HTTP 401 INVALID_KEY |
| Chave sem créditos | HTTP 402 INSUFFICIENT_CREDITS |
| Chave desativada | HTTP 403 FORBIDDEN |
Preços e Créditos
Cada chamada consome créditos da sua API Key. Créditos não expiram.
| Endpoint | Custo | Descrição |
|---|---|---|
| /image/classify | 0,5 crédito | Classificação via ResNet50 |
| /captcha/detect | 0,5 crédito | Detecção de tipo + coordenadas |
| /captcha/analyze | 1 crédito | Análise completa da grade 3×3 |
Endpoints
Verifica o status da API, GPU e modelos carregados. Não requer autenticação.
Resposta 200
{
"status": "ok",
"gpu": true,
"device": "cuda",
"models": ["yolov8n", "resnet50"],
"version": "1.2.0"
}
Classifica o conteúdo de uma imagem usando ResNet50 (ImageNet — 1.000 categorias). Ideal para categorização de produtos em e-commerce.
Body (JSON)
| Campo | Tipo | Descrição |
|---|---|---|
| image_b64 | string* | Imagem em base64 (JPEG, PNG, WEBP, BMP) |
| top_k | int | Número de resultados (1–20, padrão: 5) |
Resposta 200
{
"category": "computer keyboard",
"confidence": 0.3442,
"top_results": [
{ "category": "computer keyboard", "confidence": 0.3442 },
{ "category": "space bar", "confidence": 0.1973 },
{ "category": "typewriter keyboard","confidence": 0.0623 }
],
"credits_consumed": 0.5,
"credits_remaining": 9999.5 // somente se autenticado
}
Detecta a presença e tipo de reCAPTCHA em um screenshot. Retorna coordenadas absolutas para clicar (no sistema de coordenadas do screenshot enviado).
Body (JSON)
| Campo | Tipo | Descrição |
|---|---|---|
| screenshot_b64 | string* | Screenshot em base64 (PNG recomendado) |
| width | int* | Largura do screenshot em pixels |
| height | int* | Altura do screenshot em pixels |
Resposta — Checkbox detectado
{
"captcha_detected": true,
"captcha_type": "checkbox",
"confidence": 0.9,
"absolute_coordinates": { "x": 312, "y": 584 },
"description": "checkbox detectado via OpenCV em (312, 584)",
"credits_consumed": 0.5
}
Resposta — Grade de imagens
{
"captcha_detected": true,
"captcha_type": "image_grid",
"confidence": 0.9,
"absolute_coordinates": { "x": 445, "y": 720 },
"description": "grid de imagens reCAPTCHA detectado",
"credits_consumed": 0.5
}
Tipos de CAPTCHA
| captcha_type | Descrição |
|---|---|
| checkbox | reCAPTCHA "Não sou um robô" — clique simples no checkbox |
| image_grid | Grade 3×3 com imagens para selecionar — usar /captcha/analyze |
| none | Nenhum CAPTCHA encontrado no screenshot |
Analisa uma grade reCAPTCHA 3×3. Lê a instrução via OCR, identifica o objeto-alvo com YOLOv8 e retorna quais células clicar com coordenadas absolutas.
Body (JSON)
| Campo | Tipo | Descrição |
|---|---|---|
| screenshot_b64 | string* | Screenshot com a grade reCAPTCHA visível |
| width | int* | Largura do screenshot em pixels |
| height | int* | Altura do screenshot em pixels |
Resposta 200
{
"grid_detected": true,
"captcha_solved": false,
"instruction": "selecione todas as imagens que contem semaforo",
"grid_size": "3x3",
"cell_analysis": [
{ "row": 0, "col": 0, "contains_object": false, "description": "car(0.82)" },
{ "row": 0, "col": 1, "contains_object": true, "description": "traffic light detectado (conf=0.91)" }
// ... 7 células restantes
],
"cells_to_click": [
{ "row": 0, "col": 1, "x": 452, "y": 398 },
{ "row": 1, "col": 0, "x": 337, "y": 513 }
],
"no_more_images": false,
"verify_button": { "x": 485, "y": 710 },
"credits_consumed": 1.0
}
Objetos reconhecidos (COCO 80 classes)
A instrução do CAPTCHA é lida via OCR e mapeada para classes COCO:
Retorna saldo de créditos e estatísticas de uso da sua chave. Requer autenticação.
Resposta 200
{
"api_key": "cvapi_abc123...",
"owner": "cliente@email.com",
"credits_remaining": 9842.5,
"total_consumed": 157.5,
"active": true,
"created_at": "2026-03-21T14:00:00+00:00",
"last_30_days": {
"total_calls": 157,
"captcha_detect": 50,
"captcha_analyze": 80,
"image_classify": 27
}
}
Códigos de Erro
Todos os erros retornam JSON com detail e error_code.
{
"detail": "Saldo insuficiente. Disponivel: 0.5. Necessario: 1.0",
"error_code": "INSUFFICIENT_CREDITS"
}
| HTTP | error_code | Descrição |
|---|---|---|
| 400 | BAD_REQUEST | Imagem inválida ou parâmetros ausentes |
| 401 | INVALID_KEY | Chave de API inválida ou inexistente |
| 402 | INSUFFICIENT_CREDITS | Saldo insuficiente — recarregue créditos |
| 403 | FORBIDDEN | Chave desativada ou admin key incorreta |
| 422 | VALIDATION_ERROR | Corpo da requisição mal formado |
| 500 | INFERENCE_ERROR | Erro interno durante inferência do modelo |
Exemplos Completos
Python
import requests, base64, pathlib
CV_API = "https://cv.empreflow.com.br"
API_KEY = "cvapi_sua_chave"
def classify_image(path, top_k=5):
b64 = base64.b64encode(pathlib.Path(path).read_bytes()).decode()
r = requests.post(
f"{CV_API}/image/classify",
json={"image_b64": b64, "top_k": top_k},
headers={"X-API-Key": API_KEY}
)
r.raise_for_status()
return r.json()
result = classify_image("camiseta.jpg", top_k=3)
print(result["category"]) # "jersey"
print(result["confidence"]) # 0.7234
for r in result["top_results"]:
print(f"{r['category']:30} {r['confidence']:.1%}")
# jersey 72.3%
# sweatshirt 18.1%
# cardigan 5.2%
import requests, base64, pathlib, pyautogui, time
CV_API = "https://cv.empreflow.com.br"
API_KEY = "cvapi_sua_chave"
HEADERS = {"X-API-Key": API_KEY}
def screenshot_b64():
img = pyautogui.screenshot()
from io import BytesIO
buf = BytesIO()
img.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode(), img.width, img.height
def solve_captcha():
b64, w, h = screenshot_b64()
# 1. Detectar tipo de CAPTCHA
det = requests.post(f"{CV_API}/captcha/detect",
json={"screenshot_b64": b64, "width": w, "height": h},
headers=HEADERS).json()
if not det["captcha_detected"]:
return False
if det["captcha_type"] == "checkbox":
x, y = det["absolute_coordinates"].values()
pyautogui.click(x, y)
return True
# 2. Resolver grade de imagens
for _ in range(5):
b64, w, h = screenshot_b64()
grid = requests.post(f"{CV_API}/captcha/analyze",
json={"screenshot_b64": b64, "width": w, "height": h},
headers=HEADERS).json()
if grid["no_more_images"]:
vb = grid["verify_button"]
pyautogui.click(vb["x"], vb["y"])
return True
for cell in grid["cells_to_click"]:
pyautogui.click(cell["x"], cell["y"])
time.sleep(0.3)
time.sleep(1.5)
return False
import requests
r = requests.get(
"https://cv.empreflow.com.br/usage",
headers={"X-API-Key": "cvapi_sua_chave"}
)
data = r.json()
print(f"Créditos restantes: {data['credits_remaining']:.1f}")
print(f"Total consumido: {data['total_consumed']:.1f}")
print(f"Chamadas totais: {data['last_30_days']['total_calls']}")
# Créditos restantes: 9842.5
# Total consumido: 157.5
# Chamadas totais: 157
JavaScript / Node.js
const fs = require('fs');
const API = 'https://cv.empreflow.com.br';
const KEY = 'cvapi_sua_chave';
async function classifyImage(filePath, topK = 5) {
const b64 = fs.readFileSync(filePath).toString('base64');
const res = await fetch(`${API}/image/classify`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': KEY },
body: JSON.stringify({ image_b64: b64, top_k: topK })
});
return res.json();
}
async function analyzeCaptcha(screenshotPath, width, height) {
const b64 = fs.readFileSync(screenshotPath).toString('base64');
const res = await fetch(`${API}/captcha/analyze`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': KEY },
body: JSON.stringify({ screenshot_b64: b64, width, height })
});
return res.json();
}
// Uso
const result = await classifyImage('produto.jpg');
console.log(`${result.category} (${(result.confidence * 100).toFixed(1)}%)`);
// → laptop (87.2%)
cURL
# Classificar produto
curl -X POST https://cv.empreflow.com.br/image/classify \
-H "X-API-Key: cvapi_sua_chave" \
-H "Content-Type: application/json" \
-d "{\"image_b64\": \"$(base64 -w0 produto.jpg)\", \"top_k\": 5}"
# Resolver CAPTCHA grade
curl -X POST https://cv.empreflow.com.br/captcha/analyze \
-H "X-API-Key: cvapi_sua_chave" \
-H "Content-Type: application/json" \
-d "{\"screenshot_b64\": \"$(base64 -w0 screen.png)\", \"width\": 1920, \"height\": 1080}"
# Ver saldo
curl https://cv.empreflow.com.br/usage \
-H "X-API-Key: cvapi_sua_chave"
PHP
<?php
define('CV_API', 'https://cv.empreflow.com.br');
define('API_KEY', 'cvapi_sua_chave');
function cvPost(string $endpoint, array $data): array {
$ch = curl_init(CV_API . $endpoint);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-API-Key: ' . API_KEY,
],
CURLOPT_TIMEOUT => 30,
]);
$res = curl_exec($ch);
curl_close($ch);
return json_decode($res, true);
}
// Classificar produto
$result = cvPost('/image/classify', [
'image_b64' => base64_encode(file_get_contents('produto.jpg')),
'top_k' => 5,
]);
echo $result['category']; // "laptop"
// Resolver CAPTCHA
$grid = cvPost('/captcha/analyze', [
'screenshot_b64' => base64_encode(file_get_contents('screen.png')),
'width' => 1920,
'height' => 1080,
]);
foreach ($grid['cells_to_click'] as $cell) {
echo "Clicar em ({$cell['x']}, {$cell['y']})\n";
}