API de processamento de imagens

Carregue uma imagem, execute até cinco operações ordenadas e descarregue o resultado num único fluxo assíncrono.

URL de base
https://api.pixmender.com
Documentação interativa
Swagger UI
1Criar chave
2Request upload
3Upload image
4Create job
5Check status
6Descarregar
01

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.

Guarde-a no servidorNunca exponha uma img_live_… chave no código do navegador ou num repositório público.
Terminal
export PIXMENDER_API_KEY="img_live_your_key"
02

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.

Request
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"}'
Response
{
  "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.

03

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.

Request
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"
04

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.

Request
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"
  }'
Optional output sizeSet 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.

Predefinição de compressãoThe production API retains 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.

202 Accepted
{
  "id": "job_01...",
  "status": "queued",
  "credits_reserved": 1.5,
  "input_asset_id": "ast_01...",
  "result_asset_id": null
}
05

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_requestedcanceledexpired
Request
curl https://api.pixmender.com/v1/jobs/job_01... \
  --header "Authorization: Bearer $PIXMENDER_API_KEY"
Resposta concluída
{
  "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
}
06

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.

Request
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.webp

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

Request
curl -X DELETE "https://api.pixmender.com/v1/assets/ast_example" -H "Authorization: Bearer $PIXMENDER_API_KEY"
Response
{"id":"ast_example","deleted":true}
SDK methods
await client.deleteAsset(assetId); // TypeScript
client.delete_asset(asset_id)       # Python
$client->deleteAsset($assetId);     // PHP
07

Referê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.

TypePurposeCampos adicionais
remove_watermarkRemover marcas de água visíveisTarefa: rights_attested: true
remove_textRemover legendas e letras—
remove_logoRemover marcas comerciais—
remove_objectRemover um objeto descritoé necessário um prompt
restoreReparar 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 processamento
optimizeCompressão percetual conforme o conteúdo; AUTO escolhe a melhor opçãodeve ficar no fim
Formatos de saídasource · png · jpeg · webp · avif; source mantém o formato de entrada verificado
Modelos de ampliaçãorealesrgan-x4plus · realesrgan-x4plus-anime · realesr-animevideov3
08

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

Criar endpoint
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"]}'
Verificar o corpo em brutoAs assinaturas usam HMAC-SHA256 sobre webhook-id.webhook-timestamp.raw-body. Guarde o segredo whsec_… apresentado na criação; só aparece uma vez.
Verificação da assinatura com Node.js
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.

09

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.

TypeScript · @pixmender/sdk
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");
Python · pixmender
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")
PHP · pixmender/pixmender-php
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');
Transferências diretasVersion 0.1.0 · alojado pelo PixMender
Somas SHA-256
TypeScriptNode.js 18+
@pixmender/sdk
PythonPython 3.10+
pixmender
PHPPHP 8.1+
pixmender/pixmender-php
Instalar diretamente de pixmender.com
# 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.1
10

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

Transferências diretasVersion 0.1.0 · pacotes de código-fonte diretos
n8nSelf-hosted installation
n8n-nodes-pixmender
MakeDeveloper app components
PixMender Custom App
Instalar no n8n autoalojado
# Run in the custom-nodes directory of a self-hosted n8n instance
npm install https://pixmender.com/downloads/n8n-nodes-pixmender-0.1.0.tgz
11

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

Otimizar uma imagem local
curl https://api.pixmender.com/shrink \
  --user "api:$PIXMENDER_API_KEY" \
  --data-binary "@photo.png" \
  --dump-header /dev/stdout

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

201 Created
{
  "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_..."
  }
}
Descarregar sem autorização
curl https://api.pixmender.com/output/job_... \
  --output "photo-optimized.png"
Otimizar o URL de uma imagem
curl https://api.pixmender.com/shrink \
  --user "api:$PIXMENDER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"source":{"url":"https://example.com/photo.jpg"}}'
Âmbito de compatibilidadeSuporta otimização de PNG, JPEG, WebP e AVIF até 5 MB e 60 megapíxeis. Este endpoint não permite redimensionar, converter, preservar metadados nem armazenar. /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.