# Stable Diffusion with LoRAs API

> Text-to-image dengan model dasar Stable Diffusion apa pun, ditambah LoRA, embedding, ControlNet, dan adaptor IP

Menghasilkan gambar dari prompt teks menggunakan model dasar yang ditentukan oleh URL atau ID HuggingFace dalam `model_name`. Beberapa `loras` dapat digabungkan, dan embedding, ControlNet, adaptor IP, serta input IC Light didukung. Opsi sampler mencakup banyak scheduler dan jumlah langkah dari 1 hingga 150. Menghasilkan 1 hingga 8 gambar dalam format png atau jpeg.

- Model id: `lora`
- Made by: Open model
- Category: Text to Image
- Output: image
- Estimated price per run: $0.057 / image (cheapest run $0.057 (57 API credits))
- Run: `POST https://api.doitong.com/v1/run/lora`
- Quote: `POST https://api.doitong.com/v1/quote/lora`
- Docs page: https://doitong.com/id/developers/models/lora

## Pricing

Price: **$0.057 / image**. Estimated from the typical cost of one run, per output (`num_images`). The quote is exactly what the run charges.

The full example input below costs $0.057 = 57 API credits (1 image × 57 API credits).

Prices are the upstream price in USD, paid from the API balance in API credits (1000 API credits = 1 USD). `POST https://api.doitong.com/v1/quote/lora` with the same JSON body returns the exact price for that input; the quote is exactly what a run charges. Invalid input is never charged and failed or canceled requests are refunded automatically.

## Input parameters

Send either the canonical name or the native field name (not both). Canonical names are the same across models.

| Parameter | Canonical name | Type | Required | Default | Allowed values / range | Description |
|---|---|---|---|---|---|---|
| `model_name` |  | string | yes |  |  | Model dasar untuk menghasilkan gambar, diidentifikasi melalui URL atau ID HuggingFace. |
| `unet_name` |  | string \| null | no |  |  | Pemilihan U-Net kustom untuk membuat gambar; berikan HuggingFace ID atau URL-nya. |
| `variant` |  | string \| null | no |  |  | Pemilihan varian model HuggingFace; 'fp16' adalah salah satu contohnya. |
| `prompt` |  | string | yes |  |  | Jelaskan gambar yang ingin dibuat sedetail mungkin untuk memperoleh hasil terbaik. |
| `negative_prompt` |  | string | no | `` |  | Negative prompt yang menentukan detail gambar yang tidak diinginkan. Prompt ini dapat mengecualikan warna, objek, pemandangan, atau fitur dan kualitas yang lebih halus, seperti kumis, buram, atau resolusi rendah. |
| `prompt_weighting` |  | boolean | no | `false` |  | Sakelar pembobotan prompt: true menghapus batas 77 token melalui perataan embedding dan mengaktifkan sintaks pembobotan. |
| `loras` |  | array of object {path, scale} | no | `[]` |  | LoRA yang efek gabungannya menghasilkan gambar yang dibuat, tanpa batas jumlah yang dapat diberikan. |
| `loras[].path` |  | string | yes |  |  | Lokasi bobot LoRA, yang ditentukan sebagai URL atau path. |
| `loras[].scale` |  | number | no | `1` | 0 – 4 | Pengali yang diterapkan pada bobot LoRA sebelum digabungkan ke model dasar. |
| `embeddings` |  | array of object {path, tokens} | no | `[]` |  | Embedding yang diterapkan selama pembuatan gambar untuk memetakan token prompt ke bobot embedding. Saat ini, hanya satu embedding yang didukung. |
| `embeddings[].path` |  | string | yes |  |  | Bobot embedding yang ditentukan melalui URL atau path file. |
| `embeddings[].tokens` |  | array of string \| null | no |  |  | Token prompt yang dipetakan ke bobot embedding. Jika dihilangkan, satu token dibuat untuk setiap vektor file embedding, dengan nama <s0>, <s1>, ...; gunakan token yang dipetakan dalam prompt Anda. |
| `controlnets` |  | array of object {path, config_url, variant, image_url, mask_url, conditioning_scale, start_percentage, end_percentage, ip_adapter_index} | no | `[]` |  | Control net yang dijadwalkan untuk diterapkan pada gambar pada timestep tertentu selama pembuatan, tanpa batas jumlah yang dapat Anda berikan. |
| `controlnets[].path` |  | string | yes |  |  | Lokasi bobot ControlNet, ditentukan sebagai URL atau path. |
| `controlnets[].config_url` |  | string \| null | no |  |  | URL opsional yang mengarah ke file config.json milik ControlNet. |
| `controlnets[].variant` |  | string \| null | no |  |  | Varian opsional untuk digunakan dengan kunci repositori Hugging Face. |
| `controlnets[].image_url` |  | string (image URL) | yes |  |  | URL gambar yang diberikan sebagai input ControlNet. |
| `controlnets[].mask_url` |  | string (image URL) \| null | no |  |  | Masker ControlNet, yang harus memiliki ukuran sama dengan gambar kontrol jika diberikan; lebar dan tinggi masing-masing harus habis dibagi 32. |
| `controlnets[].conditioning_scale` |  | number | no | `1` | 0 – 2 | Penskalaan yang diterapkan pada bobot ControlNet sebelum digabungkan ke model dasar. |
| `controlnets[].start_percentage` |  | number | no | `0` | 0 – 1 | Persentase dari total timestep saat ControlNet mulai memengaruhi pembuatan gambar. |
| `controlnets[].end_percentage` |  | number | no | `1` | 0 – 1 | Persentase dari total timestep saat ControlNet berhenti memengaruhi pembuatan gambar. |
| `controlnets[].ip_adapter_index` |  | integer \| null | no |  |  | Pemilihan IP adapter berdasarkan indeks untuk ControlNet InstantID; ControlNet lain tidak memerlukan pengaturan ini. |
| `controlnet_guess_mode` |  | boolean | no | `false` |  | Membatasi penerapan ControlNet pada prediksi kondisional jika bernilai true. |
| `ip_adapter` |  | array of object {ip_adapter_image_url, ip_adapter_mask_url, path, model_subfolder, weight_name, insight_face_model_path, scale, scale_json, unconditional_noising_factor, image_projection_shortcut} | no | `[]` |  | IP adapter yang digunakan untuk membuat gambar. Memberikan entri apa pun memerlukan image_encoder_path. |
| `ip_adapter[].ip_adapter_image_url` |  | string (image URL) \| array of image URL | yes |  |  | URL gambar yang diberikan sebagai input IP adapter. |
| `ip_adapter[].ip_adapter_mask_url` |  | string (image URL) \| null | no |  |  | Masker IP adapter, yang memiliki batasan ukuran jika diberikan: dimensinya harus sama dengan gambar adapter. |
| `ip_adapter[].path` |  | string | yes |  |  | Lokasi bobot IP adapter, yang ditentukan sebagai URL atau path. |
| `ip_adapter[].model_subfolder` |  | string \| null | no |  |  | Lokasi bobot IP adapter, yang ditentukan sebagai subfolder di dalam direktori model. |
| `ip_adapter[].weight_name` |  | string \| null | no |  |  | Nama file bobot. |
| `ip_adapter[].insight_face_model_path` |  | string \| null | no |  |  | Lokasi bobot model InsightFace, yang ditentukan sebagai URL atau path. |
| `ip_adapter[].scale` |  | number | no | `1` | ≥ 0 | Faktor skala untuk bobot IP adapter, yang diterapkan sebelum digabungkan ke dalam model dasar. |
| `ip_adapter[].scale_json` |  | object \| null | no |  |  | Faktor skala untuk bobot IP adapter, yang diterapkan sebelum digabungkan ke dalam model dasar. |
| `ip_adapter[].unconditional_noising_factor` |  | number | no | `0` | 0 – 1 | Faktor yang mengontrol penambahan noise tanpa syarat untuk IP adapter. |
| `ip_adapter[].image_projection_shortcut` |  | boolean | no | `true` |  | Pengaturan pintasan proyeksi gambar, dengan True sebagai bawaan. Gunakan False untuk model FaceID plus V1 dan True untuk model FaceID plus V2. |
| `image_encoder_path` |  | string \| null | no |  |  | Encoder gambar yang ditentukan oleh URL HTTPS atau ID Hugging Face, dengan kompatibilitas yang ditentukan oleh bobot IP-Adapter: SD1.5 menggunakan image_encoder_subfolder='models/image_encoder', sedangkan h94/IP-Adapter SDXL menggunakan h94/IP-Adapter dan image_encoder_subfolder='sdxl_models/image_encoder'. Encoder diperlukan setiap kali ip_adapter berisi nilai. |
| `image_encoder_subfolder` |  | string \| null | no |  |  | Subdirektori di dalam image_encoder_path yang menyimpan bobot encoder gambar. |
| `image_encoder_weight_name` |  | string \| null | no | `pytorch_model.bin` |  | Pilih bobot encoder gambar berdasarkan nama untuk digunakan dalam pembuatan gambar. |
| `ic_light_model_url` |  | string \| null | no |  |  | URL model IC Light yang digunakan saat membuat gambar. |
| `ic_light_model_background_image_url` |  | string (image URL) \| null | no |  |  | Latar belakang yang kompatibel dengan model untuk pembuatan gambar IC Light, yang diberikan sebagai URL gambar. |
| `ic_light_image_url` |  | string (image URL) \| null | no |  |  | URL gambar input untuk pembuatan dengan model IC Light. |
| `seed` |  | integer \| null | no |  |  | Seed untuk mereproduksi gambar dalam Stable Diffusion. Gambar dapat direproduksi secara persis pada setiap proses dengan mempertahankan versi model, prompt, dan seed. |
| `image_size` |  | object {width, height} \| enum (string) \| null | no | `square_hd` | `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9` | Dimensi gambar output, dipilih dari preset atau ditentukan sebagai lebar dan tinggi kustom. Kedua dimensi kustom harus habis dibagi 8. |
| `num_inference_steps` |  | integer | no | `30` | 1 – 150 | Mengontrol jumlah langkah pembuatan yang dilakukan Stable Diffusion; langkah tambahan dapat menghasilkan gambar akhir yang lebih detail. |
| `guidance_scale` |  | number | no | `7.5` | 0 – 20 | Kekuatan kepatuhan terhadap prompt untuk pemilihan gambar, dinyatakan sebagai CFG (Classifier Free Guidance). |
| `clip_skip` |  | integer | no | `0` | 0 – 2 | Melewati sebagian pembuatan gambar agar rendering lebih cepat, dengan hasil yang sedikit berbeda. |
| `scheduler` |  | enum (string) \| null | no |  | `DPM++ 2M`, `DPM++ 2M Karras`, `DPM++ 2M SDE`, `DPM++ 2M SDE Karras`, `Euler`, `Euler A`, `Euler (trailing timesteps)`, `LCM`, `LCM (trailing timesteps)`, `DDIM`, `TCD` | Scheduler atau sampler yang digunakan untuk melakukan denoising pada gambar. |
| `timesteps` |  | object {method, array} | no | `{"array":[],"method":"default"}` |  | Penggantian jadwal timestep denoising, tidak dapat digunakan bersamaan dengan sigmas. Tanpa penggantian—yaitu bawaan—scheduler menghitung timestep dari num_inference_steps; memberikan jadwal khusus membuat num_inference_steps tidak relevan. Penggantian memerlukan dukungan scheduler untuk argumen timesteps pada set_timesteps. |
| `timesteps.method` |  | enum (string) | no | `default` | `default`, `array` | Pilih cara menentukan timestep: 'default', pengaturan bawaan, memungkinkan scheduler menggunakan `num_inference_steps`. Untuk memberikan jadwal timestep sendiri, pilih 'array' dan letakkan jadwal tersebut di field `array`. |
| `timesteps.array` |  | array of integer | no | `[]` |  | Jadwal timestep yang diterapkan saat metode yang dipilih adalah 'custom'. |
| `sigmas` |  | object {method, array} | no | `{"array":[],"method":"default"}` |  | Penggantian jadwal sigma denoising, tidak dapat digunakan bersamaan dengan timesteps. Tanpa penggantian—yaitu bawaan—scheduler menghitung sigma dari num_inference_steps; memberikan jadwal khusus membuat num_inference_steps tidak relevan. Penggantian memerlukan dukungan scheduler untuk argumen sigmas pada set_sigmas. |
| `sigmas.method` |  | enum (string) | no | `default` | `default`, `array` | Pilih cara menentukan sigma: 'default', pengaturan bawaan, menggunakan nilai sigma milik scheduler. Untuk memberikan jadwal sigma sendiri, pilih 'custom' dan letakkan jadwal tersebut di field `array`. |
| `sigmas.array` |  | array of number | no | `[]` |  | Jadwal sigma yang diterapkan saat metode yang dipilih adalah 'custom'. |
| `prediction_type` |  | enum (string) | no | `epsilon` | `v_prediction`, `epsilon` | Pilih jenis prediksi untuk membuat gambar; jika tidak memilih opsi lain, `epsilon` digunakan. |
| `rescale_betas_snr_zero` |  | boolean | no | `false` |  | Mengontrol apakah sampler mengaktifkan rescale_betas_snr_zero. |
| `image_format` |  | enum (string) | no | `png` | `jpeg`, `png` | Format file untuk gambar hasil. |
| `num_images` | `num_outputs` | integer | no | `1` | 1 – 8 | Atur jumlah gambar yang dihasilkan oleh satu permintaan, sehingga waktu pembuatan dapat ditambah untuk batch yang lebih besar. |
| `enable_safety_checker` |  | boolean | no | `false` |  | Aktivasi pemeriksa keamanan; true mengaktifkan pemeriksaan. |
| `tile_width` |  | integer | no | `4096` | 128 – 4,096 | Atur ukuran setiap tile selama pembuatan gambar. |
| `tile_height` |  | integer | no | `4096` | 128 – 4,096 | Atur ukuran setiap tile selama pembuatan gambar. |
| `tile_stride_width` |  | integer | no | `2048` | 64 – 2,048 | Atur jarak antara posisi tile yang berurutan selama pembuatan gambar. |
| `tile_stride_height` |  | integer | no | `2048` | 64 – 2,048 | Atur jarak antara posisi tile yang berurutan selama pembuatan gambar. |
| `eta` |  | number | no | `0` | 0 – 1 | Pengaturan Eta yang digunakan saat membuat gambar. |
| `debug_latents` |  | boolean | no | `false` |  | Menyimpan latent untuk debugging jika bernilai true. |
| `debug_per_pass_latents` |  | boolean | no | `false` |  | Aktifkan debugging per pass dengan mengaturnya ke true, yang menyimpan latent dari setiap pass. |

File parameters (`ic_light_model_background_image_url`, `ic_light_image_url`) take a public `https://` URL, a `data:` URI up to 10 MB, or the `file_url` of an upload from `POST /files`.

## Example input

Required parameters only:

```json
{
  "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
}
```

A fuller example:

```json
{
  "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
}
```

## Run it

Set `DOITONG_API_KEY` to a key from https://doitong.com/developers/dashboard#keys. `?wait=20` returns the finished request in the same call when it is ready within 20 seconds; otherwise poll `GET /requests/{id}` (it also accepts `?wait=`), or pass `webhook_url`.

### curl

```bash
# Run the model; wait up to 20 s for the finished result in the same call
curl -X POST "https://api.doitong.com/v1/run/lora?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  }'

# Still "queued" or "running"? Poll with the id from the response:
curl "https://api.doitong.com/v1/requests/REQUEST_ID?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

### JavaScript

```javascript
const API = "https://api.doitong.com/v1";
const headers = {
  "Authorization": "Bearer " + process.env.DOITONG_API_KEY,
  "Content-Type": "application/json",
};

// Run the model; wait up to 20 s for the finished result in the same call
let res = await fetch(API + "/run/lora?wait=20", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  }),
});
let request = await res.json();
if (!res.ok) throw new Error(request.error.code + ": " + request.error.message);

// Not finished yet: long-poll until it is
while (request.status === "queued" || request.status === "running") {
  res = await fetch(API + "/requests/" + request.id + "?wait=20", { headers });
  request = await res.json();
}
if (request.status !== "succeeded") throw new Error(JSON.stringify(request.error));
console.log(request.outputs.map((o) => o.url), request.cost.credits + " API credits ($" + request.cost.usd + ")");
```

### Python

```python
import os
import requests

API = "https://api.doitong.com/v1"
headers = {"Authorization": "Bearer " + os.environ["DOITONG_API_KEY"]}

payload = {
    "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
}

# Run the model; wait up to 20 s for the finished result in the same call
r = requests.post(API + "/run/lora", params={"wait": 20}, json=payload, headers=headers)
request = r.json()
if not r.ok:
    raise RuntimeError(request["error"]["code"] + ": " + request["error"]["message"])

# Not finished yet: long-poll until it is
while request["status"] in ("queued", "running"):
    request = requests.get(API + "/requests/" + request["id"], params={"wait": 20}, headers=headers).json()
if request["status"] != "succeeded":
    raise RuntimeError(request["error"])
print([o["url"] for o in request["outputs"]], request["cost"]["credits"], "API credits", "$" + request["cost"]["usd"])
```

### MCP

The MCP server at `https://api.doitong.com/v1/mcp` exposes the tools `search_models`, `get_model`, `quote`, `run`, `get_request`, `cancel_request`, `list_requests`, `create_upload` and `get_account`. A `run` call for this model:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "run",
    "arguments": {
      "model_id": "lora",
      "input": {
        "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
        "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
      },
      "wait_seconds": 20
    }
  }
}
```

## Response

Every call returns a request object. `status` is one of `queued`, `running`, `succeeded`, `failed`, `canceled`. `outputs` lists the generated files with URLs on our storage (kept forever, or 7 days with `?storage=temporary`; `storage` says which); `output` is the model's own result object with the same URLs.

```json
{
  "id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
  "object": "request",
  "model": "lora",
  "status": "succeeded",
  "created_at": "2026-10-20T12:00:00Z",
  "started_at": "2026-10-20T12:00:02Z",
  "completed_at": "2026-10-20T12:00:09Z",
  "queue_position": null,
  "cost": {
    "credits": 57,
    "usd": "0.057",
    "charged": 57,
    "refunded": 0
  },
  "input": {
    "model_name": "stabilityai/stable-diffusion-xl-base-1.0",
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  },
  "output": {
    "images": [
      {
        "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
        "content_type": "image/jpeg",
        "file_name": "0-output.jpeg",
        "file_size": 1843200,
        "width": 1024,
        "height": 768
      }
    ],
    "seed": 42,
    "has_nsfw_concepts": [
      false
    ],
    "debug_latents": {
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_name": "0-output.jpeg",
      "file_size": 1843200
    },
    "debug_per_pass_latents": {
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_name": "0-output.jpeg",
      "file_size": 1843200
    }
  },
  "outputs": [
    {
      "type": "image",
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_size": 1843200,
      "width": 1024,
      "height": 768,
      "stored": true
    }
  ],
  "error": null,
  "metrics": {
    "inference_seconds": 6.8
  },
  "urls": {
    "self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
  }
}
```

### Output fields (`output`)

| Field | Type | Description |
|---|---|---|
| `images` | array of object {url, content_type, file_name, file_size, width, height} | Informasi file untuk gambar yang dihasilkan. |
| `seed` | integer | Seed pembuatan gambar, termasuk nilai yang dipilih secara acak jika input tidak menyertakan seed; jika tidak, nilai yang diberikan akan diulang. |
| `has_nsfw_concepts` | array of boolean | Menunjukkan apakah konsep NSFW muncul dalam gambar yang dihasilkan. |
| `debug_latents` | object {url, content_type, file_name, file_size} \| null | Data latent yang disimpan untuk debugging. |
| `debug_per_pass_latents` | object {url, content_type, file_name, file_size} \| null | Data latent per pass yang disimpan untuk debugging. |

## Related models

- [Stable Diffusion with LoRAs · Image to Image](https://doitong.com/developers/models/lora/image-to-image.md) (`lora/image-to-image`): $0.264 / image
- [Stable Diffusion with LoRAs · Inpaint](https://doitong.com/developers/models/lora/inpaint.md) (`lora/inpaint`): $0.184 / image
- [FLUX.1 \[dev\]](https://doitong.com/developers/models/flux/dev.md) (`flux/dev`): $0.025 / megapixel
- [FLUX.1 \[schnell\]](https://doitong.com/developers/models/flux/schnell.md) (`flux/schnell`): $0.003 / megapixel
- [FLUX.2 \[dev\]](https://doitong.com/developers/models/flux-2.md) (`flux-2`): $0.012 / megapixel
- [FLUX.2 \[pro\]](https://doitong.com/developers/models/flux-2-pro.md) (`flux-2-pro`): $0.015 / megapixel of output image
- [GPT Image 2.5 Text to Image](https://doitong.com/developers/models/openai/gpt-image-2.5/flare/text-to-image.md) (`openai/gpt-image-2.5/flare/text-to-image`): from $0.008 / image
- [Ideogram V4.5](https://doitong.com/developers/models/ideogram/v4.5.md) (`ideogram/v4.5`): from $0.03 / image

## Links

- HTML page: https://doitong.com/developers/models/lora
- All models and guides for AI agents: https://doitong.com/developers/llms.txt
- OpenAPI 3.1 with this model's typed request body: https://doitong.com/developers/openapi.json?model=lora
- Errors: https://doitong.com/developers/docs/errors
- Model details as JSON: https://api.doitong.com/v1/models/lora
