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.
POST https://api.pixelapi.dev/v1/image/product-photo-catalogue-clean
Auth: Authorization: Bearer YOUR_API_KEY
| Field | Required | Description |
|---|---|---|
image | Yes | Catalogue/seller product image. JPG, PNG or WebP. Max 20MB. |
art_no | No | Article number label. Default: Art no. 1595. Max 40 characters. |
size_text | No | Size or range label. Default: M to 4XL. Max 40 characters. |
footer | No | Footer caption. Max 80 characters. |
output_format | No | jpeg, png or webp. Default: jpeg. |
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"
{
"generation_id": "e49b2dd6-aa2a-46e1-a334-93f4d25da6d4",
"status": "queued",
"credits_used": 0.039,
"pipeline": ["remove-background", "catalogue-clean-layout"],
"estimated_seconds": 20
}
GET https://api.pixelapi.dev/v1/image/{generation_id}
When complete, the status response contains an output_url you can download or store.
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")
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"); }
}
| Code | Meaning |
|---|---|
| 400 | Empty upload, image too large, invalid image bytes, or invalid output format. |
| 401 | Missing or invalid Bearer API key. |
| 402 | Insufficient credits. Top up at pricing. |
| 422 | Form validation error. |
| 500 | Failed to queue or process job; refundable failures are refunded. |
| 503 | Queue temporarily full; refundable failures are refunded. |