Train custom LoRA models on your own images. Generate new images using those models. All via simple REST API.
https://api.pixelapi.dev/v1/tunes
All endpoints (except /config) require a Bearer token:
Authorization: Bearer YOUR_API_KEY
| Service | Credits | USD | Notes |
|---|---|---|---|
| SDXL LoRA Training | 100 | $0.10 | ~15-25 min, 1000 steps |
| FLUX LoRA Training | 200 | $0.20 | ~25-40 min, 1000 steps |
| SDXL Inference | 2/img | $0.002/img | ~5-15 sec per image |
| FLUX Inference | 5/img | $0.005/img | ~10-30 sec per image |
| FLUX Pro Inference | 16/img | $0.016/img | Highest quality |
POST /train → Get a job ID + upload URLPOST /{job_id}/upload → Send your training imagesPOST /infer → Generate images with your trained model
Public. Returns current pricing and supported models. No authentication required.
curl https://api.pixelapi.dev/v1/tunes/config
Response:
{
"service": "tunesapi",
"pricing": {
"train_sdxl": { "credits": 100, "usd": 0.10 },
"train_flux": { "credits": 200, "usd": 0.20 },
"infer_sdxl": { "credits": 2, "usd": 0.002, "per": "image" },
"infer_flux": { "credits": 5, "usd": 0.005, "per": "image" }
},
"models": ["sdxl", "flux"],
"max_training_images": 100,
"min_training_images": 5
}
Create a new LoRA training job. Credits are deducted immediately.
Request Body:
{
"model": "sdxl", // "sdxl" or "flux"
"trigger_word": "MYSTYLE", // Unique word to use in prompts
"steps": 1000, // Training steps (100-5000)
"rank": 16, // LoRA rank (4-128)
"learning_rate": 0.0001, // Optional, default 1e-4
"webhook_url": "https://your-server.com/callback" // Optional
}
Example:
curl -X POST https://api.pixelapi.dev/v1/tunes/train \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sdxl",
"trigger_word": "MYBRAND",
"steps": 1000,
"rank": 16
}'
Response:
{
"job_id": "tune_abc123def456",
"status": "awaiting_images",
"model": "sdxl",
"estimated_time_seconds": 1500,
"credits_cost": 100,
"credits_remaining": 49900.0,
"upload_url": "/v1/tunes/tune_abc123def456/upload?token=xyz789"
}
Upload training images. Use the upload_url from the train response.
Requirements:
Example:
curl -X POST "https://api.pixelapi.dev/v1/tunes/tune_abc123def456/upload?token=xyz789" \
-F "[email protected]" \
-F "[email protected]" \
-F "[email protected]" \
-F "[email protected]" \
-F "[email protected]"
Response:
{
"status": "queued",
"job_id": "tune_abc123def456",
"images_uploaded": 5,
"message": "Images uploaded. Training will start when a GPU worker is available."
}
Check the status of a training or inference job.
curl https://api.pixelapi.dev/v1/tunes/tune_abc123def456 \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"job_id": "tune_abc123def456",
"status": "training", // queued → training → completed
"progress": 45.2, // 0-100 (during training)
"created_at": "2026-04-08T13:24:44Z",
"completed_at": null
}
Status values: awaiting_images → queued → training → completed | failed
Generate images using a trained LoRA model. Include the trigger word in your prompt.
curl -X POST https://api.pixelapi.dev/v1/tunes/infer \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tune_id": "lora_xyz789",
"prompt": "a photo of MYBRAND product on a marble table, studio lighting",
"negative_prompt": "blurry, low quality",
"width": 1024,
"height": 1024,
"num_images": 2,
"guidance_scale": 7.5,
"steps": 30
}'
Response:
{
"job_id": "inf_def456abc123",
"status": "queued",
"credits_cost": 4,
"credits_remaining": 49896.0
}
List all your trained LoRA models.
curl https://api.pixelapi.dev/v1/tunes/models \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
[
{
"tune_id": "lora_xyz789",
"trigger_word": "MYBRAND",
"base_model": "sdxl",
"status": "ready",
"created_at": "2026-04-08T14:00:00Z",
"file_size_mb": 72.4
}
]
Delete a trained model and its files.
curl -X DELETE https://api.pixelapi.dev/v1/tunes/lora_xyz789 \
-H "Authorization: Bearer YOUR_API_KEY"
Response: {"status": "deleted", "tune_id": "lora_xyz789"}
Receive a POST request when training/inference completes:
{
"job_id": "tune_abc123def456",
"status": "completed",
"timestamp": "2026-04-08T14:30:00Z"
}
import requests
API_KEY = "your_api_key"
BASE = "https://api.pixelapi.dev/v1/tunes"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Create training job
resp = requests.post(f"{BASE}/train", headers=HEADERS, json={
"model": "sdxl",
"trigger_word": "MYBRAND",
"steps": 1000,
"rank": 16,
})
job = resp.json()
print(f"Job: {job['job_id']}, Cost: {job['credits_cost']} credits")
# 2. Upload images
upload_url = f"https://api.pixelapi.dev{job['upload_url']}"
files = [("images", open(f"img{i}.jpg", "rb")) for i in range(1, 6)]
requests.post(upload_url, files=files)
# 3. Poll until complete
import time
while True:
status = requests.get(f"{BASE}/{job['job_id']}", headers=HEADERS).json()
print(f"Status: {status['status']} ({status.get('progress', 0)}%)")
if status["status"] in ("completed", "failed"):
break
time.sleep(10)
# 4. Generate images
result = requests.post(f"{BASE}/infer", headers=HEADERS, json={
"tune_id": status.get("tune_id", "lora_xyz"),
"prompt": "a photo of MYBRAND product, professional lighting",
"num_images": 4,
})
print(f"Inference: {result.json()}")