Marketplace Product Photo Cleaner

Marketplace Product Photo Cleaner API

Use this endpoint for Product Photo. PixelAPI, Lensora and the public docs now consistently point to POST /v1/image/product-photo-catalogue-clean. This is a catalogue/seller-photo cleaner, not the old preset-based cinematic studio-scene product.

Endpoint

POST https://api.pixelapi.dev/v1/image/product-photo-catalogue-clean

Auth: Authorization: Bearer YOUR_API_KEY

Form fields

FieldRequiredDescription
imageYesCatalogue/seller product image. JPG, PNG or WebP. Max 20MB.
art_noNoArticle number label. Default: Art no. 1595. Max 40 characters.
size_textNoSize or range label. Default: M to 4XL. Max 40 characters.
footerNoFooter caption. Max 80 characters.
output_formatNojpeg, png or webp. Default: jpeg.

Pricing

Submit a job — curl

curl -X POST https://api.pixelapi.dev/v1/image/product-photo-catalogue-clean \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=@catalogue-photo.jpg" \
  -F "art_no=Art no. 1595" \
  -F "size_text=M to 4XL" \
  -F "footer=Three colour options shown | Folded catalogue view | Size range: M to 4XL" \
  -F "output_format=jpeg"

Queued response

{
  "generation_id": "e49b2dd6-aa2a-46e1-a334-93f4d25da6d4",
  "status": "queued",
  "credits_used": 0.039,
  "pipeline": ["remove-background", "catalogue-clean-layout"],
  "estimated_seconds": 20
}

Poll status

GET https://api.pixelapi.dev/v1/image/{generation_id}

When complete, the status response contains an output_url you can download or store.

Python example

import time
import requests

API = "https://api.pixelapi.dev"
KEY = "YOUR_API_KEY"

with open("catalogue-photo.jpg", "rb") as f:
    submit = requests.post(
        f"{API}/v1/image/product-photo-catalogue-clean",
        headers={"Authorization": f"Bearer {KEY}"},
        files={"image": f},
        data={
            "art_no": "Art no. 1595",
            "size_text": "M to 4XL",
            "footer": "Three colour options shown | Folded catalogue view | Size range: M to 4XL",
            "output_format": "jpeg",
        },
        timeout=60,
    )
submit.raise_for_status()
job = submit.json()

for _ in range(60):
    time.sleep(2)
    status = requests.get(
        f"{API}/v1/image/{job['generation_id']}",
        headers={"Authorization": f"Bearer {KEY}"},
        timeout=20,
    ).json()
    if status.get("status") == "completed":
        print(status.get("output_url"))
        break
    if status.get("status") == "failed":
        raise RuntimeError(status.get("error_message") or "Job failed")

Node.js example

import fs from "node:fs";
import FormData from "form-data";
import axios from "axios";

const API = "https://api.pixelapi.dev";
const KEY = process.env.PIXELAPI_KEY;

const form = new FormData();
form.append("image", fs.createReadStream("catalogue-photo.jpg"));
form.append("art_no", "Art no. 1595");
form.append("size_text", "M to 4XL");
form.append("footer", "Three colour options shown | Folded catalogue view | Size range: M to 4XL");
form.append("output_format", "jpeg");

const submit = await axios.post(`${API}/v1/image/product-photo-catalogue-clean`, form, {
  headers: { ...form.getHeaders(), Authorization: `Bearer ${KEY}` },
});

for (let i = 0; i < 60; i++) {
  await new Promise(r => setTimeout(r, 2000));
  const status = await axios.get(`${API}/v1/image/${submit.data.generation_id}`, {
    headers: { Authorization: `Bearer ${KEY}` },
  });
  if (status.data.status === "completed") { console.log(status.data.output_url); break; }
  if (status.data.status === "failed") { throw new Error(status.data.error_message || "Job failed"); }
}

Error codes

CodeMeaning
400Empty upload, image too large, invalid image bytes, or invalid output format.
401Missing or invalid Bearer API key.
402Insufficient credits. Top up at pricing.
422Form validation error.
500Failed to queue or process job; refundable failures are refunded.
503Queue temporarily full; refundable failures are refunded.

Try it