TunesAPI Documentation

Train custom LoRA models on your own images. Generate new images using those models. All via simple REST API.

Quick Start: Get your API key at pixelapi.dev/app/#apikeys, then follow the 3-step flow below: create → upload → infer.

Base URL

https://api.pixelapi.dev/v1/tunes

Authentication

All endpoints (except /config) require a Bearer token:

Authorization: Bearer YOUR_API_KEY

Pricing

ServiceCreditsUSDNotes
SDXL LoRA Training100$0.10~15-25 min, 1000 steps
FLUX LoRA Training200$0.20~25-40 min, 1000 steps
SDXL Inference2/img$0.002/img~5-15 sec per image
FLUX Inference5/img$0.005/img~10-30 sec per image
FLUX Pro Inference16/img$0.016/imgHighest quality

Workflow

3 Steps:
1. POST /train → Get a job ID + upload URL
2. POST /{job_id}/upload → Send your training images
3. POST /infer → Generate images with your trained model

Endpoints

GET /config

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
}

POST /train

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"
}

POST /{job_id}/upload?token=TOKEN

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."
}

GET /{job_id}

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_imagesqueuedtrainingcompleted | failed

POST /infer

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
}

GET /models

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 /{tune_id}

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"}

Tips for Best Results

Webhook Callbacks

Receive a POST request when training/inference completes:

{
  "job_id": "tune_abc123def456",
  "status": "completed",
  "timestamp": "2026-04-08T14:30:00Z"
}

Python SDK Example

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()}")
Need help? Email [email protected] or check the full API reference.