Em operações de e-commerce de alto volume e marketplaces com milhares de lojistas, o cadastramento de novos catálogos enfrenta um gargalo recorrente: as fotos fornecidas por fabricantes e distribuidores possuem formatos discrepantes, iluminação heterogênea e fundos poluídos. Ferramentas de edição em lote para desktop exigem operação manual e não se comunicam de forma nativa com sistemas ERP, PIM (Product Information Management) ou CMS. Por outro lado, delegar o tratamento a equipes de design gera filas de espera de 24 a 72 horas por SKU, elevando o custo marginal por item cadastrado.
A API REST do Cutout.pro disponibiliza recursos de visão computacional voltados à automação de recorte de produtos, enquadramento de objetos e preenchimento de fundo em cores sólidas. Ao integrar esses endpoints a pipelines assíncronos no backend, times de engenharia conseguem padronizar milhares de imagens em segundos, gerando fotos prontas para os padrões da Amazon, Mercado Livre e Shopify: fundo branco puro (#FFFFFF), proporções quadradas e sombras de contato naturais.
1. Arquitetura da API e fluxo de autenticação
Todas as funcionalidades do Cutout.pro são expostas via HTTPS. A autenticação é uniforme e exige o envio da chave de acesso no cabeçalho HTTP personalizado:
APIKEY: sua_chave_de_api_cutout_pro
Monitoramento preventivo de saldo e créditos
Grandes cargas de importação de catálogo podem enviar dezenas de milhares de requisições em um único lote. Caso os créditos se esgotem durante o processo, as requisições falharão em massa com o código de erro 4001 (créditos insuficientes). Por isso, o pipeline de ingestão deve validar o saldo antes de disparar os trabalhos.
O Cutout.pro fornece um endpoint específico para consulta de assinatura e créditos:
- Endpoint:
GET https://www.cutout.pro/api/v1/mySubscription - Cabeçalhos:
APIKEY: <SUA_API_KEY>,Accept: application/json
Exemplo de retorno JSON:
{
"code": 0,
"data": {
"monthBalance": 1250,
"imageBalance": 5000,
"videoBalance": 0,
"monthStartDate": "2026-10-01 00:00:00",
"monthExpireDate": "2026-11-01 00:00:00"
},
"msg": null,
"time": 1728729600000
}
Configurar essa checagem no orquestrador de tarefas permite pausar o processamento e emitir alertas operacionais antes de gerar milhares de chamadas tarifadas desnecessárias.
2. Escolha de endpoints e parâmetros cruciais
Para o recorte de produtos e mercadorias de e-commerce, o Cutout.pro indica o parâmetro mattingType=6 (recorte geral para produtos, objetos e roupas) ou mattingType=1. A plataforma oferece três modos de consumo de acordo com a infraestrutura do backend:
| Modo | Endpoint | Método e Content-Type | Carga de resposta | Caso de uso ideal |
|---|---|---|---|---|
| Modo 1: Fluxo binário | https://www.cutout.pro/api/v1/matting | POST / multipart/form-data | Imagem binária pura (image/png) | Gravação direta em disco ou buffers de memória |
| Modo 2: Base64 em JSON | https://www.cutout.pro/api/v1/matting2 | POST / multipart/form-data | JSON com data.imageBase64 | Microsserviços que trafegam cargas JSON RPC |
| Modo 3: URL remota | https://www.cutout.pro/api/v1/mattingByUrl | GET / query string | JSON com data.imageBase64 | Imagens já hospedadas em S3, Cloudflare R2 ou CDN |
Parâmetros essenciais para e-commerce
mattingType(inteiro, obrigatório): Definir como6para recorte de itens e produtos.crop(booleano, opcional): Quando configurado comotrue, o algoritmo remove bordas transparentes vazias e enquadra o recorte exatamente na caixa delimitadora do produto.cropMargin(string, opcional): Adiciona margem em torno do produto quandocrop=true. Aceita valores absolutos em pixels (ex.:"30px") ou porcentagens (ex.:"10%").bgcolor(string hexadecimal, opcional): Preenche o fundo transparente com uma cor sólida sem o prefixo#(ex.:FFFFFFpara branco puro). O valor'blur'aplica desfoque ao fundo.outputFormat(string, opcional): Formato de saída desejado (png,webpoujpg_<qualidade>, comojpg_85).preview(booleano, opcional): Quando definido comotrue, limita a resolução em até 500x500 pixels e debita apenas 0.25 crédito (contra 1 crédito para resolução original de até 4096x4096px e <15MB). Ideal para pré-visualizações rápidas em cadastros de lojistas.
3. Arquitetura para processamento em lote e controle de taxa
A API do Cutout.pro opera de maneira síncrona: cada requisição HTTP bloqueia a conexão até que o servidor conclua o processamento da imagem e devolva o resultado. Entretanto, a plataforma impõe uma restrição estrita de taxa de 5 requisições concorrentes por segundo (5 QPS).
Submeter requisições sem controle de vazão acarreta no retorno frequente do erro 5005 (Too many requests in the queue, please wait). Para processar lotes de mais de 10.000 SKUs com estabilidade, é indispensável estruturar a comunicação por meio de filas de mensageria assíncronas.
Topologia de microsserviço recomendada
[ERP / PIM Ingestão em Lote]
│ (Lote de SKUs)
▼
[Message Broker: Redis / RabbitMQ]
│
▼
[Cluster de Workers (Celery / BullMQ)]
├── Limitador Token Bucket (Travado em <= 4.5 QPS)
├── Chamada à API Cutout.pro (POST /api/v1/matting?mattingType=6)
│ └── Recuo exponencial ao receber erro 5005
├── Motor local de pós-processamento (Pillow / Sharp)
│ ├── Centralização em tela quadrada (ex.: 2000x2000px)
│ ├── Ocupação visual padrão de 85%
│ └── Síntese de sombra de contato suave (Contact Shadow)
├── Armazenamento em nuvem (AWS S3 / Cloudflare R2)
└── Webhook de retorno para o ERP (Atualização do status do SKU)
Estratégia de tolerância a falhas
- Controle de vazão via Token Bucket: Mantenha um limitador centralizado no Redis para que o somatório de requisições de todos os workers não ultrapasse 4.5 QPS.
- Tratamento de exceções:
5005(Fila cheia / Taxa excedida): Aplicar recuo exponencial com variação aleatória (intervalos de 1.5s, 3s, 6s).1002(Arquivo > 15MB) ou5008(Formato inválido): Direcionar o item para uma Dead-Letter Queue (DLQ) para conferência visual da equipe do catálogo.4001(Créditos esgotados): Suspender temporariamente as filas e acionar alerta emergencial para o time de suporte e compras.
4. Pipeline de padronização de imagens: Dimensões, margens e sombras
Embora a API aceite o parâmetro bgcolor=FFFFFF para entregar o produto sobre fundo branco, os principais canais de venda exigem critérios geométricos rigorosos:
- Tela estritamente quadrada (proporção 1:1, ex.: 2000x2000 pixels).
- O item deve ocupar entre 80% e 85% da área total da imagem para manter consistência visual na grade da loja.
- Fundos brancos sintéticos sem sombra costumam conferir um aspecto artificial de adesivo colado. Uma sombra de contato suave na base do produto traz profundidade e realismo.
O padrão arquitetural recomendado consiste em solicitar ao Cutout.pro o recorte transparente em PNG (crop=true, sem bgcolor) e executar o enquadramento e a geração da sombra localmente no worker com bibliotecas rápidas como Pillow (Python) ou Sharp (Node.js).
Implementação prática em Python com Pillow
import io
import time
import requests
from PIL import Image, ImageFilter
CUTOUT_API_KEY = "SUA_API_KEY_AQUI"
API_URL = "https://www.cutout.pro/api/v1/matting?mattingType=6&crop=true"
def remove_background(image_bytes: bytes, max_retries: int = 3) -> bytes:
"""Consome a API do Cutout.pro com recuo exponencial contra limites de taxa."""
headers = {"APIKEY": CUTOUT_API_KEY}
files = {"file": ("product.jpg", image_bytes, "image/jpeg")}
for attempt in range(max_retries):
response = requests.post(API_URL, headers=headers, files=files, timeout=30)
if response.status_code == 200 and response.headers.get("Content-Type", "").startswith("image/"):
return response.content
try:
err = response.json()
code = err.get("code")
msg = err.get("msg")
if code == 5005: # Limite de taxa
time.sleep((2 ** attempt) + 0.5)
continue
elif code == 4001:
raise RuntimeError("Créditos do Cutout.pro esgotados.")
else:
raise ValueError(f"Falha no Cutout.pro: {code} - {msg}")
except requests.exceptions.JSONDecodeError:
response.raise_for_status()
raise TimeoutError("Número máximo de tentativas excedido no Cutout.pro.")
def standardize_product_image(
transparent_png_bytes: bytes,
target_canvas_size: int = 2000,
fill_ratio: float = 0.85
) -> Image.Image:
"""
Padroniza a imagem em um fundo branco quadrado, escala o produto para 85%
do enquadramento e gera uma sombra de contato realista.
"""
# 1. Carregar recorte transparente
product = Image.open(io.BytesIO(transparent_png_bytes)).convert("RGBA")
prod_w, prod_h = product.size
# 2. Redimensionar preservando proporção
max_dim = int(target_canvas_size * fill_ratio)
scale = min(max_dim / prod_w, max_dim / prod_h)
new_w, new_h = int(prod_w * scale), int(prod_h * scale)
product_resized = product.resize((new_w, new_h), Image.Resampling.LANCZOS)
# 3. Criar tela branca pura quadrada
canvas = Image.new("RGBA", (target_canvas_size, target_canvas_size), (255, 255, 255, 255))
# 4. Sintetizar sombra de contato suave
alpha_mask = product_resized.split()[3]
shadow_height = max(10, int(new_h * 0.08))
# Achatar canal alfa na vertical para simular a base do produto
shadow_footprint = alpha_mask.resize((new_w, shadow_height), Image.Resampling.BILINEAR)
shadow_footprint = shadow_footprint.filter(ImageFilter.GaussianBlur(radius=15))
# Criar camada cinza-escura com opacidade em 35%
shadow_layer = Image.new("RGBA", (new_w, shadow_height), (40, 40, 40, 0))
shadow_layer.putalpha(shadow_footprint.point(lambda p: int(p * 0.35)))
# 5. Posicionar elementos na tela
pos_x = (target_canvas_size - new_w) // 2
pos_y = (target_canvas_size - new_h) // 2
# Inserir sombra ligeiramente abaixo da base do produto
shadow_y = pos_y + new_h - int(shadow_height * 0.6)
canvas.paste(shadow_layer, (pos_x, shadow_y), shadow_layer)
# Inserir o produto em primeiro plano
canvas.paste(product_resized, (pos_x, pos_y), product_resized)
# Retornar imagem final no espaço de cor RGB
return canvas.convert("RGB")
def process_sku_file(raw_path: str, output_path: str):
with open(raw_path, "rb") as f:
raw_bytes = f.read()
# Etapa 1: Recorte via API
cutout_bytes = remove_background(raw_bytes)
# Etapa 2: Padronização de escala e síntese de sombra
final_img = standardize_product_image(cutout_bytes)
# Etapa 3: Exportação em JPEG otimizado
final_img.save(output_path, "JPEG", quality=90, optimize=True)
5. Boas práticas e otimização de custos
- Uso de
mattingByUrlpara economia de tráfego de saída: Se as fotos de fornecedores já estiverem salvas em buckets como AWS S3 ou Cloudflare R2, priorize a chamada ao endpointmattingByUrl. Ao informar apenas a URL pública, evita-se o tráfego de reenvio de arquivos grandes a partir do seu servidor. - Processamento em dois estágios: Durante a triagem preliminar de catálogos pelo time comercial, utilize
preview=true(custo de 0.25 crédito). Apenas quando o produto for aprovado para publicação oficial o pipeline dispara a chamada com resolução cheia (1 crédito). - Armazenamento de máscaras transparentes: Salve sempre os PNGs transparentes originais retornados pela API em armazenamento frio. Caso a identidade visual da loja seja alterada no futuro (como trocar o fundo branco por cinza suave ou alterar as margens), todo o catálogo poderá ser regenerado localmente sem custos adicionais de API.