Criar uma chave de API
Open Chaves de API, create a key with images:write and images:read. Add webhooks:manage apenas se for utilizar webhooks; depois copie a chave imediatamente. A chave completa só é apresentada uma vez.
img_live_… chave no código do navegador ou num repositório público.export PIXMENDER_API_KEY="img_live_your_key"Pedir um URL de carregamento seguro
Crie primeiro um registo do recurso. Utilize o tipo MIME exato: JPEG, PNG, WebP, AVIF, GIF, HEIC ou HEIF. Os ficheiros podem ter até 20 MB.
curl --request POST https://api.pixmender.com/v1/uploads \
--header "Authorization: Bearer $PIXMENDER_API_KEY" \
--header "Content-Type: application/json" \
--data '{"content_type":"image/jpeg","filename":"photo.jpg"}'{
"id": "ast_01...",
"status": "pending_upload",
"upload_url": "https://storage.pixmender.com/...",
"upload_method": "POST",
"upload_fields": {
"bucket": "pixmender-assets",
"key": "originals/usr_.../ast_01....jpg",
"Content-Type": "image/jpeg",
"Policy": "...",
"X-Amz-Signature": "..."
},
"upload_url_expires_at": "2026-08-25T10:30:00.000Z",
"asset_expires_at": "2026-08-26T10:15:00.000Z"
}upload_url_expires_at é o prazo curto da política de carregamento. asset_expires_at é o prazo independente de retenção da imagem carregada.
Carregar os bytes da imagem
Envie através de POST um corpo multipart/form-data diretamente para upload_url. Adicione primeiro todos os valores de upload_fields e a imagem como campo final file . A política assinada aceita entre 1 byte e 20 MB. Não envie a chave de API do PixMender para o URL de armazenamento.
export UPLOAD_URL="https://storage.pixmender.com/..."
# Add every upload_fields entry returned above before the file field.
curl --request POST "$UPLOAD_URL" \
--form-string "bucket=$UPLOAD_BUCKET" \
--form-string "key=$UPLOAD_KEY" \
--form-string "Content-Type=image/jpeg" \
--form-string "Policy=$UPLOAD_POLICY" \
--form-string "X-Amz-Algorithm=$UPLOAD_ALGORITHM" \
--form-string "X-Amz-Credential=$UPLOAD_CREDENTIAL" \
--form-string "X-Amz-Date=$UPLOAD_DATE" \
--form-string "X-Amz-Signature=$UPLOAD_SIGNATURE" \
--form "[email protected];type=image/jpeg"Criar uma tarefa de processamento
Envie o ID do recurso carregado e uma lista ordenada de operações. O custo exato é reservado e devolvido automaticamente em caso de falha. Otimizar custa 0,1 créditos separadamente e é gratuito com outra operação. Ampliar custa 0,5 créditos; as restantes operações, 1 crédito. A API exporta PNG, JPEG, WebP e AVIF. O cabeçalho Idempotency-Key é obrigatório: reutilize a mesma chave apenas para pedidos idênticos, para que uma nova tentativa de transporte não crie outra tarefa faturável enquanto a chave for válida.
As chaves novas são válidas durante a tarefa e por 24 horas após conclusão, falha ou cancelamento. As novas tentativas não prolongam esse prazo. Reutilizar uma chave expirada cria um novo pedido com custos normais. As chaves anteriores a esta política mantêm a duração ilimitada. O histórico e a retenção de ficheiros são independentes.
curl --request POST https://api.pixmender.com/v1/images/process \
--header "Authorization: Bearer $PIXMENDER_API_KEY" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: request-001" \
--data '{
"input": { "asset_id": "ast_01..." },
"operations": [
{ "type": "denoise" },
{
"type": "upscale",
"scale": 4,
"model": "realesrgan-x4plus"
},
{ "type": "optimize" }
],
"output_format": "webp",
"compression_preset": "balanced"
}'output_size: { width: 2560, height: 2560 } para obter esse tamanho exato com um recorte centrado. As dimensões são inteiros de 1 a 10000. Com ambas as dimensões, o valor predefinido é cover. Com apenas uma dimensão, o valor predefinido é inside e o outro lado é calculado proporcionalmente. Um valor explícito de output_size.fit: "inside" ajusta toda a imagem aos limites sem recortar. Ambos os modos ampliam imagens pequenas quando necessário e mantêm as proporções. O redimensionamento ocorre depois da IA e antes da codificação e otimização. Apenas imagens estáticas.Redimensionar separadamente custa 0,1 créditos: envie um operations array with output_size. Com outra operação, redimensionar é gratuito: otimizar e redimensionar custa 0,1 créditos; ampliar, otimizar e redimensionar custa 0,5. O preço mantém-se se a imagem já couber. Tarefas falhadas ou canceladas devolvem a reserva completa. Cada tamanho ou modo novo requer uma nova chave de idempotência; as novas tentativas reutilizam a mesma.
compression_preset:lossless, balanced, or small. Se for omitido, mantêm-se o modo equilibrado predefinido e o controlo de qualidade.Without encoder_version, a API utiliza o codificador de produção localmente ou em workers compatíveis. Para ativar a beta, envie no nível superior encoder_version: "v8" com uma chave API. A otimização beta só é executada localmente; as operações de IA anteriores mantêm os seus fornecedores. Os limiares SSIMULACRA2 são 60 / 75 / 90 para Compact / Balanced / Visual Lossless, com um limite de 120 segundos. A produção mantém o controlo de qualidade e os limites.
{
"id": "job_01...",
"status": "queued",
"credits_reserved": 1.5,
"input_asset_id": "ast_01...",
"result_asset_id": null
}Consultar o estado da tarefa
Consulte a cada 1–3 segundos até o estado ser succeeded,failed, canceled, or expired. Em caso de êxito, utilize result_asset_id para descarregar. As tarefas otimizadas também devolvem tamanhos, poupança, formato escolhido, classe de conteúdo, resultado do controlo percetual, esforço de pesquisa e motivo final em optimization.
queuedvalidatingprocessingsucceededfailedcancel_requestedcanceledexpiredcurl https://api.pixmender.com/v1/jobs/job_01... \
--header "Authorization: Bearer $PIXMENDER_API_KEY"{
"id": "job_01...",
"status": "succeeded",
"credits_charged": 1.5,
"credits_refunded": 0,
"input_byte_size": 2471936,
"input_content_type": "image/jpeg",
"result_asset_id": "ast_result_01...",
"result_filename": "photo.avif",
"result_byte_size": 812640,
"result_content_type": "image/avif",
"optimization": {
"source_bytes": 2471936,
"result_bytes": 812640,
"savings_percent": 67.125,
"format": "avif",
"quality": 57,
"similarity": 0.99124,
"guard_passed": true,
"attempts": 12,
"candidate_formats": [
"avif",
"webp",
"jpeg"
],
"content_class": "photo",
"deadline_reached": false,
"original_preserved": false,
"reason": "optimized",
"encode_ms": 2840
},
"error": null
}Descarregar o resultado
A API devolve um URL assinado temporário válido durante 10 minutos. O ficheiro processado permanece disponível durante 24 horas, salvo eliminação anterior.
curl 'https://api.pixmender.com/v1/assets/ast_result_01.../download?disposition=attachment' \
--header "Authorization: Bearer $PIXMENDER_API_KEY"
# Response: { "url": "https://storage.pixmender.com/...", "expires_in": 600 }
curl --location "https://storage.pixmender.com/..." --output photo.webpDelete originals and results
Depois de transferir todos os ficheiros necessários, invoque DELETE /v1/assets/{assetId}para cada original e resultado. A eliminação é gratuita e requer images:write. Elimina essa imagem e as pré-visualizações em cache. Mantém os outros resultados e o histórico. Repetir o pedido devolve a mesma resposta de sucesso.
Um recurso utilizado por uma tarefa em fila ou em execução devolve 409; aguarde a conclusão ou o cancelamento. Um 503 indica que o acesso está bloqueado mas a limpeza do armazenamento está pendente; repita o pedido. Os recursos desconhecidos ou de outro utilizador devolvem 404.
curl -X DELETE "https://api.pixmender.com/v1/assets/ast_example" -H "Authorization: Bearer $PIXMENDER_API_KEY"{"id":"ast_example","deleted":true}await client.deleteAsset(assetId); // TypeScript
client.delete_asset(asset_id) # Python
$client->deleteAsset($assetId); // PHPReferência de operações
Um fluxo contém entre 1 e 5 operações. Se for usado, optimizemust be last. upscale deve ser a última operação de processamento e só pode ser seguido por optimize.
Para redimensionar sem outras operações, envie um operations array and specify output_size.
remove_watermarkRemover marcas de água visíveisTarefa: rights_attested: trueremove_textRemover legendas e letras—remove_logoRemover marcas comerciais—remove_objectRemover um objeto descritoé necessário um promptrestoreReparar danos e degradação—denoiseReduzir ruído e artefactos de compressão—deblurMelhorar detalhes desfocados—face_enhanceAperfeiçoar detalhes do retrato—upscaleAumentar a resoluçãoscale: 2 | 4; passo final de processamentooptimizeCompressão percetual conforme o conteúdo; AUTO escolhe a melhor opçãodeve ficar no fimsource mantém o formato de entrada verificadoReceber webhooks assinados
Crie um endpoint com o âmbito webhooks:manage ou faça a gestão em Webhooks. O PixMender envia job.succeeded, job.failed, and job.canceled. Devolva uma resposta 2xx em 10 segundos; as entregas falhadas são repetidas com espera exponencial.
curl --request POST https://api.pixmender.com/v1/webhooks \
--header "Authorization: Bearer $PIXMENDER_API_KEY" \
--header "Content-Type: application/json" \
--data '{"url":"https://example.com/pixmender","events":["job.succeeded","job.failed"]}'webhook-id.webhook-timestamp.raw-body. Guarde o segredo whsec_… apresentado na criação; só aparece uma vez.import { createHmac, timingSafeEqual } from "node:crypto";
const eventId = request.headers.get('webhook-id');
const timestamp = request.headers.get('webhook-timestamp');
const signatureHeader = request.headers.get('webhook-signature');
if (!eventId || !timestamp || !signatureHeader?.startsWith('v1=')) {
throw new Error('Missing webhook signature headers');
}
const received = signatureHeader.slice(3);
if (!/^[a-f0-9]{64}$/i.test(received)) {
throw new Error('Invalid webhook signature format');
}
const rawBody = await request.text();
const timestampNumber = Number(timestamp);
const age = Math.abs(Date.now() / 1000 - timestampNumber);
if (!Number.isFinite(timestampNumber) || age > 300) {
throw new Error('Stale webhook');
}
const secret = process.env.PIXMENDER_WEBHOOK_SECRET;
if (!secret) throw new Error('Webhook secret is not configured');
const expected = createHmac('sha256', secret)
.update(`${eventId}.${timestamp}.${rawBody}`)
.digest('hex');
const receivedBytes = Buffer.from(received, 'hex');
const expectedBytes = Buffer.from(expected, 'hex');
if (receivedBytes.length !== expectedBytes.length ||
!timingSafeEqual(receivedBytes, expectedBytes)) {
throw new Error('Invalid webhook signature');
}Os cabeçalhos de entrega são webhook-id, webhook-timestamp, and webhook-signature: v1=…. Elimine duplicados pelo ID do webhook.
Utilizar um SDK no servidor
Os SDK no servidor combinam carregamento assinado, criação e consulta da tarefa e transferência num método. Mantenha a chave de API fora do código do navegador.
import { PixMender } from "@pixmender/sdk";
const client = new PixMender({
apiKey: process.env.PIXMENDER_API_KEY!,
});
const result = await client.processImage({
file: "./photo.jpg",
// Optimize must be the final operation.
operations: [{ type: "denoise" }, { type: "upscale", scale: 4 }, { type: "optimize" }],
idempotencyKey: "workflow-run-123",
outputFormat: "webp",
compressionPreset: "balanced",
});
await result.downloadTo("./photo-enhanced.webp");import os
from pixmender import PixMender
client = PixMender(api_key=os.environ["PIXMENDER_API_KEY"])
result = client.process_image(
file="photo.jpg",
operations=[{"type": "restore"}, {"type": "optimize"}],
idempotency_key="workflow-run-123",
output_format="webp",
compression_preset="balanced",
)
result.download_to("photo-enhanced.webp")use PixMender\PixMender;
$client = new PixMender($_ENV['PIXMENDER_API_KEY']);
$result = $client->processImage(
__DIR__ . '/photo.jpg',
[['type' => 'restore'], ['type' => 'optimize']],
'workflow-run-123',
outputFormat: 'webp',
compressionPreset: 'balanced',
);
$result->downloadTo(__DIR__ . '/photo-enhanced.webp');# TypeScript
npm install https://pixmender.com/downloads/pixmender-sdk-0.1.0.tgz
# Python
pip install https://pixmender.com/downloads/pixmender-0.1.0-py3-none-any.whl
# PHP / Composer
composer config repositories.pixmender composer https://pixmender.com/downloads/composer
composer require pixmender/pixmender-php:^0.1Ligar ferramentas de automatização
As integrações do n8n e Make aceitam uma imagem binária, executam o fluxo assíncrono completo e devolvem a imagem processada como saída binária para o passo seguinte.
# Run in the custom-nodes directory of a self-hosted n8n instance
npm install https://pixmender.com/downloads/n8n-nodes-pixmender-0.1.0.tgzMigrar do Tinify
As integrações HTTP existentes do Tinify podem manter o formato de otimização. Aponte-as para https://api.pixmender.com, keep Basic Auth, use api como utilizador e a sua chave de API do PixMender como palavra-passe.
curl https://api.pixmender.com/shrink \
--user "api:$PIXMENDER_API_KEY" \
--data-binary "@photo.png" \
--dump-header /dev/stdoutUm pedido bem-sucedido devolve 201 Created. O corpo JSON inclui size, type, dimensions, compression ratio e o endereço público de transferência emoutput.url. O mesmo URL é devolvido no cabeçalho Location e funciona sem chave de API até o resultado expirar.
{
"input": {
"size": 98868,
"type": "image/jpeg"
},
"output": {
"size": 88373,
"type": "image/jpeg",
"width": 1280,
"height": 853,
"ratio": 0.8938,
"url": "https://api.pixmender.com/output/job_..."
}
}curl https://api.pixmender.com/output/job_... \
--output "photo-optimized.png"curl https://api.pixmender.com/shrink \
--user "api:$PIXMENDER_API_KEY" \
--header "Content-Type: application/json" \
--data '{"source":{"url":"https://example.com/photo.jpg"}}'/shrink utiliza o otimizador de produção no mesmo formato e o seu controlo de qualidade; não disponibiliza todos os modos e formatos da API principal. Cada otimização concluída custa 0,1 créditos.