PixelAPI Documentation

Complete API reference for AI product photography and image editing. Remove backgrounds, generate scenes, upscale, and more.

🆕 New endpoints: Background removal, background replacement, face restoration, and object removal are now available! Jump to new endpoints →

Quickstart

Remove your first product background in 3 steps:

  1. Sign in at pixelapi.dev/app with Google. You get 10 free credits instantly.
  2. Copy your API key from the dashboard.
  3. Remove a background:
curl -X POST https://api.pixelapi.dev/v1/image/remove-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

This returns a generation_id. Poll for the result:

curl https://api.pixelapi.dev/v1/image/GENERATION_ID \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0"

When status is "completed", the output_url contains your transparent PNG.

⚠️ Important: Always set a custom User-Agent header (e.g. MyApp/1.0). Requests without a proper User-Agent may be blocked by our CDN.

Authentication

All API requests require a Bearer token in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Get your API key from the dashboard after signing in with Google.

💡 Your API key starts with pk_live_. Keep it secret — anyone with your key can use your credits.

Rate Limits & Plans

PlanPriceCredits/moRequests/min
Free$0105
Starter$10/mo10,00020
Pro$50/mo60,00060
Scale$200/mo300,000200

Credit Costs

OperationCreditsCost (Starter)
Background Removal2$0.002
Background Replace5$0.005
Image Generation (FLUX/SDXL)3$0.003
4x Upscaling20$0.020
Face Restoration3$0.003
Object Removal5$0.005
Audio Generation (≤15s)5$0.005
Audio Generation (16–30s)10$0.010

Rate limit headers are included in every response: X-RateLimit-Remaining, X-RateLimit-Reset.

Polling for Results

All image processing is asynchronous. Every endpoint returns a generation_id immediately. Poll GET /v1/image/{id} until done:

  1. Submit a job → get generation_id
  2. Poll GET /v1/image/{id} every 2–3 seconds
  3. Status progresses: queuedprocessingcompleted

Typical completion times:

✂️ Remove Background NEW

4 credits · $0.004 POST /v1/image/remove-background

Remove the background from an image and return a transparent PNG. Works great with product photos, portraits, objects, and complex edges.

Request — File Upload

Content-Type: multipart/form-data

ParameterTypeDescription
imagefilerequired*Image file (JPEG, PNG, WebP). Max 10MB.

Request — URL

Content-Type: application/json

ParameterTypeDescription
image_urlstringrequired*Public URL of the image to process.

*Provide either image (file upload) or image_url (JSON), not both.

Response

{
  "generation_id": "bg-rm-a1b2c3d4-...",
  "status": "queued",
  "operation": "remove-background",
  "credits_used": 4.0
}

cURL Example — File Upload

curl -X POST https://api.pixelapi.dev/v1/image/remove-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

cURL Example — URL

curl -X POST https://api.pixelapi.dev/v1/image/remove-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp/1.0" \
  -d '{"image_url": "https://example.com/product.jpg"}'

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")

# From local file
result = client.remove_background("product.jpg")
print(result.url)  # Transparent PNG URL

# From URL
result = client.remove_background(image_url="https://example.com/product.jpg")
print(result.url)

🎨 Replace Background NEW

8 credits · $0.008 POST /v1/image/replace-background

Remove the background from a product image and replace it with an AI-generated scene. Describe the background you want with a text prompt.

Request — File Upload

Content-Type: multipart/form-data

ParameterTypeDescription
imagefilerequiredProduct image file (JPEG, PNG, WebP). Max 10MB.
promptstringrequiredText description of the desired background scene.

Request — JSON with URL

Content-Type: application/json

ParameterTypeDescription
image_urlstringrequiredPublic URL of the product image.
promptstringrequiredText description of the desired background scene.

Response

{
  "generation_id": "bg-rp-e5f6g7h8-...",
  "status": "queued",
  "operation": "replace-background",
  "credits_used": 8.0
}

cURL Example

curl -X POST https://api.pixelapi.dev/v1/image/replace-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]" \
  -F "prompt=product on marble countertop, soft natural window light, minimal scandinavian kitchen"

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")

result = client.replace_background(
    "product.jpg",
    prompt="product on marble countertop, soft natural window light, minimal"
)
print(result.url)  # Product composited onto AI scene
💡 Prompt tips: Be specific about the scene, lighting, and style. Good: "product on rustic wooden table, morning sunlight from left, cozy café background, shallow depth of field". Bad: "nice background".

👤 Restore Face NEW

5 credits · $0.005 POST /v1/image/restore-face

Enhance and restore faces in photos using CodeFormer. Fix blurry portraits, enhance low-res headshots, and improve team photos.

Request

Content-Type: multipart/form-data

ParameterTypeDescription
imagefilerequired*Image file containing faces (JPEG, PNG, WebP). Max 10MB.

Or JSON with image_url (string).

Response

{
  "generation_id": "face-i9j0k1l2-...",
  "status": "queued",
  "operation": "restore-face",
  "credits_used": 5.0
}

cURL Example

curl -X POST https://api.pixelapi.dev/v1/image/restore-face \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")
result = client.restore_face("blurry-portrait.jpg")
print(result.url)  # Enhanced image

🧹 Remove Object NEW

8 credits · $0.008 POST /v1/image/remove-object

Remove unwanted objects from images using AI inpainting. Provide a mask image or a text description of what to remove.

Request

Content-Type: multipart/form-data

ParameterTypeDescription
imagefilerequiredSource image file (JPEG, PNG, WebP). Max 10MB.
maskfileoptionalMask image — white areas will be removed/inpainted. Same dimensions as source.
promptstringoptionalText description of the object to remove (e.g., "the watermark in the corner"). Used when no mask is provided.

Provide either mask or prompt (or both for best results).

Response

{
  "generation_id": "obj-rm-m3n4o5p6-...",
  "status": "queued",
  "operation": "remove-object",
  "credits_used": 8.0
}

cURL Example — With Mask

curl -X POST https://api.pixelapi.dev/v1/image/remove-object \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]" \
  -F "[email protected]"

cURL Example — With Prompt

curl -X POST https://api.pixelapi.dev/v1/image/remove-object \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]" \
  -F "prompt=remove the watermark in the bottom right corner"

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")

# With mask
result = client.remove_object("photo.jpg", mask="mask.png")

# With prompt
result = client.remove_object("photo.jpg", prompt="remove the shadow on the left")

print(result.url)  # Cleaned image

🖼️ Generate Image

5 credits · $0.005 POST /v1/image/generate

Generate an image from a text prompt using FLUX Schnell or SDXL.

Request Body

Content-Type: application/json

ParameterTypeDescription
modelstringrequiredflux-schnell or sdxl
promptstringrequiredText description of the image to generate
negative_promptstringoptionalWhat to avoid (SDXL only)
widthintoptional512–1536, default 1024
heightintoptional512–1536, default 1024
stepsintoptionalInference steps. SDXL: 20–50 (default 30). FLUX: 1–8 (default 4)
guidance_scalefloatoptionalPrompt adherence. Default 7.5 (SDXL), 0 (FLUX)
seedintoptionalFor reproducible results

Response

{
  "generation_id": "a1b2c3d4-...",
  "status": "queued",
  "model": "flux-schnell",
  "credits_used": 5.0
}

cURL Example

curl -X POST https://api.pixelapi.dev/v1/image/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp/1.0" \
  -d '{
    "model": "flux-schnell",
    "prompt": "Professional product photo of wireless earbuds, studio lighting, white background",
    "width": 1024,
    "height": 1024
  }'

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")
result = client.image.generate(
    prompt="Professional product photo of wireless earbuds, studio lighting",
    model="flux-schnell",
    width=1024,
    height=1024
)
print(result.url)

🔍 Upscale Image

20 credits · $0.02 POST /v1/image/upscale

Upscale an image to 4x resolution using Real-ESRGAN. Great for making low-res product images print-ready.

Request

Content-Type: multipart/form-data or application/json

ParameterTypeDescription
imagefilerequired*Image file to upscale. Max 10MB.
image_urlstringrequired*Public URL of image to upscale.

Response

{
  "generation_id": "up-q7r8s9t0-...",
  "status": "queued",
  "operation": "upscale",
  "credits_used": 20.0
}

cURL Example

curl -X POST https://api.pixelapi.dev/v1/image/upscale \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

Python SDK

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")
result = client.upscale("low-res-product.jpg")
print(result.url)  # 4x upscaled image

📋 Get Job Status

GET /v1/image/{generation_id}

Poll this endpoint until status is completed, failed, or blocked. Works for all job types (background removal, generation, upscaling, etc.).

Response (completed)

{
  "id": "bg-rm-a1b2c3d4-...",
  "status": "completed",
  "output_url": "https://api.pixelapi.dev/outputs/images/2026/02/19/abc123.png",
  "operation": "remove-background",
  "credits_used": 4.0,
  "created_at": "2026-02-19T08:00:00Z"
}

Status Values

StatusMeaning
queuedJob is waiting to be processed
processingJob is being processed on the GPU
completedDone — output_url contains the result
failedProcessing failed — check error field
blockedContent policy violation
💡 Polling tip: Poll every 2–3 seconds. Output URLs expire after 24 hours — download promptly.

📦 List Models

GET /v1/models

Returns all available models and operations with their pricing and capabilities.

Available Models & Operations

Model / OperationEndpointCreditsSpeed
flux-schnellPOST /v1/image/generate3~3–5s
sdxlPOST /v1/image/generate3~8–13s
upscale-4xPOST /v1/image/upscale20~10–30s
remove-backgroundPOST /v1/image/remove-background2~2–3s
replace-backgroundPOST /v1/image/replace-background5~5–10s
restore-facePOST /v1/image/restore-face3~3–5s
remove-objectPOST /v1/image/remove-object5~5–15s

🎵 Generate Audio NEW

5–10 credits POST /v1/audio/generate

Generate music, sound effects, and audio clips from text descriptions using Meta's MusicGen model. Returns a WAV audio file URL.

Request

Content-Type: application/json

ParameterTypeDescription
promptstringrequiredText description of the audio to generate (3–500 chars). E.g. "upbeat electronic dance music with heavy bass"
durationintegeroptionalDuration in seconds. Range: 5–30. Default: 15
modelstringoptionalModel to use. Currently: musicgen-small (default)

Credit Costs

Response

{
  "generation_id": "a1b2c3d4-...",
  "status": "queued",
  "model": "musicgen-small",
  "duration": 15,
  "credits_used": 8.0,
  "estimated_seconds": 30
}

Poll GET /v1/image/{generation_id} until status is "completed". The output_url will contain a WAV file.

cURL Example

curl -X POST https://api.pixelapi.dev/v1/audio/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp/1.0" \
  -d '{
    "prompt": "upbeat Indian flute melody with tabla beats",
    "duration": 10
  }'

Python Example

import requests, time

API_KEY = "pk_live_your_key"
headers = {"Authorization": f"Bearer {API_KEY}", "User-Agent": "MyApp/1.0"}

# Generate audio
resp = requests.post("https://api.pixelapi.dev/v1/audio/generate",
    headers=headers,
    json={"prompt": "calm lofi hip hop beat with vinyl crackle", "duration": 15}
)
gen_id = resp.json()["generation_id"]

# Poll for result
while True:
    result = requests.get(f"https://api.pixelapi.dev/v1/image/{gen_id}", headers=headers).json()
    if result["status"] == "completed":
        print(f"Audio URL: {result['output_url']}")
        break
    time.sleep(3)

JavaScript Example

const resp = await fetch('https://api.pixelapi.dev/v1/audio/generate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
    'User-Agent': 'MyApp/1.0'
  },
  body: JSON.stringify({
    prompt: 'epic orchestral trailer music with drums',
    duration: 20
  })
});
const { generation_id } = await resp.json();

// Poll for result
let result;
do {
  await new Promise(r => setTimeout(r, 3000));
  result = await fetch(`https://api.pixelapi.dev/v1/image/${generation_id}`, {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  }).then(r => r.json());
} while (result.status !== 'completed');

console.log('Audio URL:', result.output_url);

Example Prompts

💡 Tip: Be descriptive with your prompts. Include genre, instruments, mood, and tempo for best results. Generated audio is royalty-free for commercial use.

🎬 Generate Video NEW

50–100 credits POST /v1/video/generate

Generate video clips from text prompts using WAN 2.1 T2V (14B FP8). Returns an MP4 video URL. Videos are generated at 16fps.

Request

Content-Type: application/json

ParameterTypeDescription
promptstringrequiredText description of the video to generate (1–2000 chars)
durationnumberoptionalDuration in seconds. Range: 1–10. Default: 3
resolutionstringoptional480p (832×480) or 720p (1280×720). Default: 480p
negative_promptstringoptionalWhat to avoid in the video (max 2000 chars)
seedintegeroptionalRandom seed for reproducible results

Credit Costs

Response

{
  "generation_id": "a1b2c3d4-...",
  "status": "queued",
  "model": "wan2.1",
  "credits_used": 50.0,
  "estimated_seconds": 60
}

Poll GET /v1/video/{generation_id} until status is "completed". The output_url will contain an MP4 file.

Get Video Status

GET /v1/video/{generation_id}
{
  "generation_id": "a1b2c3d4-...",
  "status": "completed",
  "output_url": "https://api.pixelapi.dev/outputs/video.mp4",
  "processing_ms": 65000
}

cURL Example

# Generate video
curl -X POST https://api.pixelapi.dev/v1/video/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A cinematic shot of a golden retriever running through a field of wildflowers at sunset",
    "duration": 3,
    "resolution": "480p"
  }'

# Poll for result
curl https://api.pixelapi.dev/v1/video/GENERATION_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

Python Example

import requests, time

API_KEY = "pk_live_your_key"
headers = {"Authorization": f"Bearer {API_KEY}", "User-Agent": "MyApp/1.0"}

# Generate video
resp = requests.post("https://api.pixelapi.dev/v1/video/generate",
    headers=headers,
    json={
        "prompt": "A cinematic drone shot over mountains at sunrise, volumetric fog",
        "duration": 3,
        "resolution": "480p"
    }
)
gen_id = resp.json()["generation_id"]
print(f"Job queued: {gen_id}")

# Poll for result
while True:
    result = requests.get(f"https://api.pixelapi.dev/v1/video/{gen_id}", headers=headers).json()
    if result["status"] == "completed":
        print(f"Video URL: {result['output_url']}")
        break
    elif result["status"] in ("failed", "blocked"):
        print(f"Error: {result.get('error_message')}")
        break
    time.sleep(5)

Example Prompts

💡 Tip: Be descriptive — include camera angle, lighting, mood, and motion. WAN 2.1 renders at 16fps with 30 diffusion steps, so 480p ~60s and 720p ~120s generation time.

💎 Account Balance

GET /v1/account/balance
{
  "credits_remaining": 9997.0,
  "plan": "starter",
  "email": "[email protected]"
}

📊 Usage History

GET /v1/account/usage?limit=20

Returns your recent job history with operations, models, status, and output URLs.

Python SDK Examples

Install

pip install pixelapi

Background Removal Workflow

from pixelapi import PixelAPI

client = PixelAPI("YOUR_API_KEY")

# Remove background from a product photo
result = client.remove_background("sneaker.jpg")
print(f"Transparent PNG: {result.url}")

# Replace background with AI lifestyle scene
result = client.replace_background(
    "sneaker.jpg",
    prompt="sneaker on concrete floor, urban alley, dramatic lighting, cinematic"
)
print(f"Lifestyle scene: {result.url}")

# Generate a product mockup from text
result = client.image.generate(
    prompt="Minimalist perfume bottle on marble, soft golden light, luxury",
    model="flux-schnell"
)
print(f"Generated: {result.url}")

# Upscale for print
result = client.upscale("product-low-res.jpg")
print(f"4x upscaled: {result.url}")

# Restore face in team photo
result = client.restore_face("team-photo.jpg")
print(f"Enhanced: {result.url}")

# Remove watermark
result = client.remove_object("photo.jpg", prompt="remove the watermark")
print(f"Cleaned: {result.url}")

Raw Python (no SDK)

import requests, time

API_KEY = "YOUR_API_KEY"
BASE = "https://api.pixelapi.dev"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "User-Agent": "MyApp/1.0"
}

# Remove background — file upload
with open("product.jpg", "rb") as f:
    resp = requests.post(
        f"{BASE}/v1/image/remove-background",
        headers=HEADERS,
        files={"image": f}
    )
gen_id = resp.json()["generation_id"]

# Poll for result
while True:
    time.sleep(2)
    result = requests.get(f"{BASE}/v1/image/{gen_id}", headers=HEADERS).json()
    if result["status"] == "completed":
        print(f"Done! {result['output_url']}")
        break
    elif result["status"] in ("failed", "blocked"):
        print(f"Error: {result['status']}")
        break

cURL Examples

# Remove background
curl -X POST https://api.pixelapi.dev/v1/image/remove-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

# Replace background
curl -X POST https://api.pixelapi.dev/v1/image/replace-background \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]" \
  -F "prompt=product floating in clouds, ethereal lighting"

# Generate image
curl -X POST https://api.pixelapi.dev/v1/image/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyApp/1.0" \
  -d '{"model": "flux-schnell", "prompt": "Product photo of headphones"}'

# Upscale
curl -X POST https://api.pixelapi.dev/v1/image/upscale \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

# Restore face
curl -X POST https://api.pixelapi.dev/v1/image/restore-face \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]"

# Remove object
curl -X POST https://api.pixelapi.dev/v1/image/remove-object \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0" \
  -F "[email protected]" \
  -F "prompt=remove the text watermark"

# Check status (same for all operations)
curl https://api.pixelapi.dev/v1/image/GENERATION_ID \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "User-Agent: MyApp/1.0"

Node.js Example

const fs = require('fs');
const API_KEY = 'YOUR_API_KEY';
const BASE = 'https://api.pixelapi.dev';

async function removeBackground(filePath) {
  const form = new FormData();
  form.append('image', new Blob([fs.readFileSync(filePath)]), 'image.jpg');

  const res = await fetch(`${BASE}/v1/image/remove-background`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'User-Agent': 'MyApp/1.0'
    },
    body: form
  });
  const { generation_id } = await res.json();

  // Poll for result
  while (true) {
    await new Promise(r => setTimeout(r, 2000));
    const status = await fetch(`${BASE}/v1/image/${generation_id}`, {
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'User-Agent': 'MyApp/1.0'
      }
    }).then(r => r.json());

    if (status.status === 'completed') return status.output_url;
    if (['failed', 'blocked'].includes(status.status)) throw new Error(status.status);
  }
}

removeBackground('product.jpg').then(url => console.log('Done:', url));

📋 Complete Sample Script

Save as pixelapi_demo.py and run. Zero dependencies — works with Python 3.6+.

💡 Replace YOUR_API_KEY with your actual key from the dashboard.
#!/usr/bin/env python3
"""
PixelAPI Demo — Remove a product background in seconds.
Usage: python pixelapi_demo.py product.jpg
"""
import json, os, sys, time, urllib.request, urllib.error

API_KEY = "YOUR_API_KEY"
BASE = "https://api.pixelapi.dev"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "User-Agent": "PixelAPI-Demo/1.0",
}

def api_post_file(path, file_path):
    """Upload a file via multipart/form-data"""
    import mimetypes
    boundary = "----PixelAPIBoundary"
    filename = os.path.basename(file_path)
    mime = mimetypes.guess_type(file_path)[0] or "application/octet-stream"
    with open(file_path, "rb") as f:
        file_data = f.read()
    body = (
        f"--{boundary}\r\n"
        f'Content-Disposition: form-data; name="image"; filename="{filename}"\r\n'
        f"Content-Type: {mime}\r\n\r\n"
    ).encode() + file_data + f"\r\n--{boundary}--\r\n".encode()
    headers = {**HEADERS, "Content-Type": f"multipart/form-data; boundary={boundary}"}
    req = urllib.request.Request(f"{BASE}{path}", data=body, headers=headers, method="POST")
    with urllib.request.urlopen(req, timeout=120) as r:
        return json.loads(r.read())

def api_get(path):
    req = urllib.request.Request(f"{BASE}{path}", headers=HEADERS)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.loads(r.read())

if len(sys.argv) < 2:
    print("Usage: python pixelapi_demo.py <image_file>")
    sys.exit(1)

image_file = sys.argv[1]
print(f"Removing background from {image_file}...")

# Submit
data = api_post_file("/v1/image/remove-background", image_file)
gen_id = data["generation_id"]
print(f"Job submitted: {gen_id[:12]}...")

# Poll
while True:
    time.sleep(2)
    result = api_get(f"/v1/image/{gen_id}")
    if result["status"] == "completed":
        print(f"\n✅ Done! Download your transparent PNG:")
        print(result["output_url"])
        break
    elif result["status"] in ("failed", "blocked"):
        print(f"\n❌ {result['status']}")
        sys.exit(1)
    print(".", end="", flush=True)

Error Handling

HTTP CodeMeaningAction
200Success
400Bad requestCheck request body, file format, parameters
401Invalid API keyCheck your key in the dashboard
402Insufficient creditsUpgrade plan or wait for monthly reset
403Blocked by CDNSet proper User-Agent header
413File too largeMax 10MB per upload
422Invalid parametersCheck request body format
429Rate limitedWait and retry; consider upgrading
500Server errorRetry after a few seconds

Error responses include a detail field:

{
  "detail": "Insufficient credits. Required: 2, available: 0. Upgrade at https://pixelapi.dev/app/#pricing"
}

Content Policy

PixelAPI uses automated content safety filters. Generated content is scanned for:

Blocked jobs return status: "blocked". No credits are charged for blocked jobs.

FAQ

How do I sign up?

Go to pixelapi.dev/app and click "Sign in with Google". You get 10 free credits instantly — no credit card required.

What's a credit?

Credits are our billing unit. Each operation costs a specific number of credits: background removal = 2, background replace = 5, image generation = 3, upscaling = 20, face restoration = 3, object removal = 5.

Do credits expire?

Monthly credits reset on your billing cycle. Unused credits don't roll over.

How long are output URLs valid?

Output URLs expire after 24 hours. Download images promptly or store them yourself.

What image formats are accepted?

JPEG, PNG, and WebP. Maximum file size is 10MB. Maximum resolution is 4096×4096 pixels.

Can I use processed images commercially?

Yes. All images processed through PixelAPI are yours to use commercially.

How is the quality compared to remove.bg?

We use state-of-the-art segmentation models. Quality is comparable — we handle complex edges, hair, transparent objects, and fine details. And we do it at 1/35th the price.

Is there a webhook / callback option?

Webhooks are available on Pro and Scale plans. Contact support for setup details.

Troubleshooting

Getting 403 Forbidden

Most common issue! Our CDN (Cloudflare) blocks requests without a proper User-Agent header.

Fix: Add User-Agent: MyApp/1.0 to every request.

# Python (requests)
headers = {
    "Authorization": "Bearer YOUR_KEY",
    "User-Agent": "MyApp/1.0"    # ← Required!
}

# Python (urllib) — MUST set manually
req = urllib.request.Request(url, headers={
    "Authorization": "Bearer YOUR_KEY",
    "User-Agent": "MyApp/1.0"
})

Getting 401 Unauthorized

Your API key is invalid or missing. Use Authorization: Bearer YOUR_KEY (not X-API-Key).

Getting 402 Insufficient Credits

You don't have enough credits for this operation. Check your balance with GET /v1/account/balance and upgrade your plan if needed.

Getting 429 Too Many Requests

You've hit the rate limit. Wait and retry. Check X-RateLimit-Reset header. Consider upgrading your plan for higher limits.

Upload fails with large files

Maximum file size is 10MB. Resize or compress your image before uploading. For upscaling, the input doesn't need to be high-res — that's the whole point!

Job stuck in "queued"

This can happen during high load. Wait up to 2 minutes. If still queued, retry. GPU queue is first-come-first-served, with priority plans getting faster processing.

Background removal quality issues

Tips for best results:


👗 Virtual Try-On

Virtually dress a person photo with any garment image using AI. Powered by CatVTON — works with standing, sitting, casual poses. No pose restrictions.

25 credits POST /v1/virtual-tryon

Request — JSON body

{
  "person_image": "<base64-encoded image>",     // required — JPG/PNG/WebP, base64 string (no data: prefix)
  "garment_image": "<base64-encoded image>",    // required — flat-lay or product photo
  "category": "upperbody"                       // required — see Category Values below
}

Category Values

ValueUse for
upperbodyShirts, jackets, tops, hoodies, blouses
lowerbodyPants, jeans, skirts, shorts
dressFull dresses, jumpsuits, full-body garments

Response

{
  "job_id": "a3f91b...",    // poll this to get the result
  "status": "queued",
  "credits_used": 25
}

Poll for result

GET /v1/virtual-tryon/jobs/{job_id}
{
  "status": "completed",          // queued | processing | completed | failed
  "result_image_b64": "<base64 PNG>",
  "inference_time_ms": 35000
}

Example — cURL

PERSON_B64=$(base64 -w0 person.jpg)
GARMENT_B64=$(base64 -w0 garment.jpg)

# Submit
JOB=$(curl -s -X POST https://api.pixelapi.dev/v1/virtual-tryon \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"person_image\": \"$PERSON_B64\",
    \"garment_image\": \"$GARMENT_B64\",
    \"category\": \"upperbody\"
  }")
JOB_ID=$(echo $JOB | python3 -c "import sys,json; print(json.load(sys.stdin)['job_id'])")

# Poll until done
curl -s "https://api.pixelapi.dev/v1/virtual-tryon/jobs/$JOB_ID" \
  -H "Authorization: Bearer YOUR_KEY"

Example — Python

import requests, base64, time

def b64(path):
    return base64.b64encode(open(path, "rb").read()).decode()

headers = {"Authorization": "Bearer YOUR_KEY", "Content-Type": "application/json"}

# Submit job
resp = requests.post("https://api.pixelapi.dev/v1/virtual-tryon", headers=headers, json={
    "person_image": b64("person.jpg"),
    "garment_image": b64("tshirt.jpg"),
    "category": "upperbody"
})
job_id = resp.json()["job_id"]

# Poll for result
while True:
    r = requests.get(f"https://api.pixelapi.dev/v1/virtual-tryon/jobs/{job_id}", headers=headers)
    d = r.json()
    if d["status"] == "completed":
        img_data = base64.b64decode(d["result_image_b64"])
        open("result.png", "wb").write(img_data)
        print("Saved result.png")
        break
    elif d["status"] == "failed":
        print("Failed:", d.get("error_message"))
        break
    time.sleep(5)

📸 Photo Guidelines for Best Results

✅ Person photo — DO ❌ Person photo — AVOID
Torso clearly visible (waist-up or full body) Face-only / selfie crops
Front-facing or slight 3/4 angle Extreme upward or downward angles
Good lighting (not backlit, not dark) Arms completely blocking the torso area
Standing, sitting, or casual poses all work Very dark, blurry, or low-resolution photos
Minimum 300×400px, portrait orientation Multiple people in the same frame

Garment image: Use a flat-lay or product photo on a white/light background for the cleanest result. The garment should be the main subject of the image.

Error Responses

StatuserrorMeaning & Fix
422image_too_small Person image is under 100px. Use at least 300×400px.
422wrong_aspect_ratio Image is wider than tall (landscape). Use a portrait photo.
422body_segmentation_failed AI couldn't identify the clothing region. Use a clearer front-facing torso photo.
422invalid_category category must be one of: upperbody, lowerbody, dress
400invalid_image Image data is corrupt or not a valid JPG/PNG/WebP. Check your base64 encoding.
503gpu_out_of_memory GPU busy. Retry in a few seconds. Use smaller images (max 1024×1024).

All error responses follow this structure:

{
  "detail": {
    "error": "image_too_small",
    "message": "Person image is too small (minimum 100px)...",
    "guidance": "Use a photo that is at least 300x400px...",
    "received_size": "48x32px"    // included when relevant
  }
}

Need help? [email protected] · Home · Dashboard · Swagger UI