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).

✓ API online — verifique em tempo real em cv.empreflow.com.br/health
LATÊNCIA CLASSIFY
7ms
LATÊNCIA YOLO
13ms
GPU
GTX 1050 Ti
FRAMEWORK
FastAPI

Autenticação

Inclua sua chave de API no header X-API-Key de cada requisição.

Header obrigatório (exceto /health)
X-API-Key: cvapi_sua_chave_aqui
Como obter uma API Key: Fale com a gente via WhatsApp, escolha um plano e receba sua chave em até 15 minutos.

Comportamento por cenário

SituaçãoResultado
Sem X-API-KeyAcesso permitido (uso registrado como "internal", sem débito)
Chave válida com créditosCréditos debitados, uso registrado
Chave inválidaHTTP 401 INVALID_KEY
Chave sem créditosHTTP 402 INSUFFICIENT_CREDITS
Chave desativadaHTTP 403 FORBIDDEN

Preços e Créditos

Cada chamada consome créditos da sua API Key. Créditos não expiram.

EndpointCustoDescrição
/image/classify0,5 créditoClassificação via ResNet50
/captcha/detect0,5 créditoDetecção de tipo + coordenadas
/captcha/analyze1 créditoAnálise completa da grade 3×3
Conversão: 1.000 créditos = R$0,175. Pagamento via PIX.

Endpoints

GET /health

Verifica o status da API, GPU e modelos carregados. Não requer autenticação.

Resposta 200

JSON
{
  "status":  "ok",
  "gpu":     true,
  "device":  "cuda",
  "models":  ["yolov8n", "resnet50"],
  "version": "1.2.0"
}
POST /image/classify

Classifica o conteúdo de uma imagem usando ResNet50 (ImageNet — 1.000 categorias). Ideal para categorização de produtos em e-commerce.

⚡ 0,5 crédito por chamada

Body (JSON)

CampoTipoDescrição
image_b64string*Imagem em base64 (JPEG, PNG, WEBP, BMP)
top_kintNúmero de resultados (1–20, padrão: 5)

Resposta 200

JSON
{
  "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
}
As categorias seguem o padrão ImageNet 1000 em inglês. Inclui: eletrônicos, roupas, móveis, alimentos, veículos, animais, ferramentas e muito mais.
POST /captcha/detect

Detecta a presença e tipo de reCAPTCHA em um screenshot. Retorna coordenadas absolutas para clicar (no sistema de coordenadas do screenshot enviado).

⚡ 0,5 crédito por chamada

Body (JSON)

CampoTipoDescrição
screenshot_b64string*Screenshot em base64 (PNG recomendado)
widthint*Largura do screenshot em pixels
heightint*Altura do screenshot em pixels

Resposta — Checkbox detectado

captcha_type: "checkbox"
{
  "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_type: "image_grid"
{
  "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_typeDescrição
checkboxreCAPTCHA "Não sou um robô" — clique simples no checkbox
image_gridGrade 3×3 com imagens para selecionar — usar /captcha/analyze
noneNenhum CAPTCHA encontrado no screenshot
POST /captcha/analyze

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.

⚡ 1 crédito por chamada

Body (JSON)

CampoTipoDescrição
screenshot_b64string*Screenshot com a grade reCAPTCHA visível
widthint*Largura do screenshot em pixels
heightint*Altura do screenshot em pixels

Resposta 200

JSON
{
  "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
}
Quando no_more_images: true e cells_to_click: [], clique em verify_button para concluir o CAPTCHA.

Objetos reconhecidos (COCO 80 classes)

A instrução do CAPTCHA é lida via OCR e mapeada para classes COCO:

SemáforoHidranteÔnibus CarroBicicletaMotocicleta CaminhãoPessoaBarco AviãoBanco de praça
GET /usage

Retorna saldo de créditos e estatísticas de uso da sua chave. Requer autenticação.

Resposta 200

JSON
{
  "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.

Formato de erro
{
  "detail":     "Saldo insuficiente. Disponivel: 0.5. Necessario: 1.0",
  "error_code": "INSUFFICIENT_CREDITS"
}
HTTPerror_codeDescrição
400BAD_REQUESTImagem inválida ou parâmetros ausentes
401INVALID_KEYChave de API inválida ou inexistente
402INSUFFICIENT_CREDITSSaldo insuficiente — recarregue créditos
403FORBIDDENChave desativada ou admin key incorreta
422VALIDATION_ERRORCorpo da requisição mal formado
500INFERENCE_ERRORErro 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";
}