Image generation and editing with Qwen-Image-2.1. JSON in, JSON out. No API key required.
Base URL http://ownv2.neuraa.in
| Method | Path | Purpose |
|---|---|---|
| POST | /tryon | Generate / edit an image |
| GET | /tryon/{jobId} | Status or result of an async job |
| GET | /jobs/{jobId} | Saved job: prompt, params, input and output images |
| GET | /health | Service and model readiness |
| GET | /openapi.json | OpenAPI 3 spec |
| GET | /swagger | Interactive Swagger UI (needs internet for its assets) |
Send a prompt, optional negative prompt, optional images and parameters. Waits for the result and returns the image as base64 PNG.
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | yes | What to generate or change (max 8000 chars). Refer to inputs as image 1, image 2 ... |
negative_prompt | string | no | What to avoid. Needs true_cfg_scale above 1. |
images | array of string | no | 0-10 images: https URL, data URL or raw base64 (max 25 MB each). |
params | object | no | Settings below. May also be sent at the top level. |
async | boolean | no | true = return a jobId at once (202), then poll GET /tryon/{jobId}. |
| Param | Range | Default | Description |
|---|---|---|---|
seed | integer | random | Same seed + inputs = same image. |
steps | 1 - 100 | 30 | More steps = slower, finer. |
true_cfg_scale | 1 - 20 | 1 | Guidance (alias guidance_scale). Use 3-5 so the negative prompt works. |
width / height | 256 - 2752 | auto | Send both together. Rounded down to a multiple of 16. |
output_resolution | 512 - 2048 | 1024 | Used when width/height are not set. |
num_images | 1 - 4 | 1 | Number of variations returned. |
rgba | true/false | false | Transparent background. |
curl -X POST http://ownv2.neuraa.in/tryon \
-H "Content-Type: application/json" \
-d '{"prompt": "Change the background to a sunset beach", "negative_prompt": "blurry, low quality", "images": ["https://example.com/photo.jpg", "data:image/png;base64,iVBORw0KGgo..."], "params": {"seed": 42, "steps": 30, "true_cfg_scale": 4.0, "width": 1024, "height": 1024, "num_images": 1}}'{
"prompt": "Change the background to a sunset beach",
"negative_prompt": "blurry, low quality",
"images": [
"https://example.com/photo.jpg",
"data:image/png;base64,iVBORw0KGgo..."
],
"params": {
"seed": 42,
"steps": 30,
"true_cfg_scale": 4.0,
"width": 1024,
"height": 1024,
"num_images": 1
}
}
{
"code": 200,
"message": "ok",
"data": {
"jobId": "c463b6c90eac",
"mimeType": "image/png",
"seed": 42,
"genSeconds": 8.2,
"images": [
"<base64 PNG>"
]
}
}{
"code": 202,
"message": "queued",
"data": {
"jobId": "864da964a5c4",
"state": "queued"
}
}{
"code": 400,
"message": "prompt required"
}{
"code": 503,
"message": "model busy",
"retryable": true
}{
"code": 504,
"message": "generation timed out",
"jobId": "864da964a5c4",
"retryable": true
}data.images[0] from base64 and save it as .png to get the picture.Poll every 1-3 s after sending "async": true. data.state is queued, running or done.
{
"code": 200,
"message": "running",
"data": {
"jobId": "864da964a5c4",
"state": "running",
"step": 12,
"steps": 30,
"position": 0,
"etaSeconds": 6.1
}
}{
"code": 200,
"message": "ok",
"data": {
"jobId": "864da964a5c4",
"state": "done",
"mimeType": "image/png",
"seed": 1,
"genSeconds": 4.4,
"images": [
"<base64 PNG>"
]
}
}{
"code": 404,
"message": "job not found"
}{
"code": 502,
"message": "generation error",
"data": {
"jobId": "864da964a5c4",
"state": "error",
"detail": "..."
}
}{
"status": "ok",
"model": "ready"
}{
"status": "degraded",
"model": "loading model..."
}Every job is saved with its job ID, prompt, negative prompt, parameters, input images and output images. The job ID is returned by POST /tryon (data.jobId, plus data.jobUrl).
| Method | Path | Purpose |
|---|---|---|
| GET | /jobs/{jobId} | Full record of one job (open, by ID) |
| GET | /jobs/{jobId}/input/{n} | Input image n (PNG), n starts at 0 |
| GET | /jobs/{jobId}/output/{n} | Output image n (PNG), n starts at 0 |
| GET | /jobs?limit=50&offset=0&status=done&q=text | List all jobs, newest first. Needs the history key: Authorization: Bearer <key> |
{
"code": 200,
"message": "ok",
"data": {
"jobId": "303b04234bef",
"status": "done",
"prompt": "In image 1, change the top to a red t-shirt",
"negativePrompt": "blurry",
"createdAt": "2026-10-20T15:41:39+00:00",
"genSeconds": 16.2,
"totalSeconds": 16.6,
"seed": 2126666741,
"width": 1024,
"height": 1024,
"error": null,
"params": {
"steps": 20,
"true_cfg_scale": 1.0,
"num_images": 1
},
"inputImages": [
{
"index": 0,
"url": "http://ownv2.neuraa.in/jobs/303b04234bef/input/0"
}
],
"outputImages": [
{
"index": 0,
"url": "http://ownv2.neuraa.in/jobs/303b04234bef/output/0"
}
]
}
}{
"code": 404,
"message": "job not found"
}{
"code": 401,
"message": "listing jobs needs the history key"
}Every error is JSON: {"code": <http status>, "message": "..."}
| HTTP | Meaning |
|---|---|
| 400 | Bad input (message names the problem: prompt required, parameter out of range, bad image/URL ...) |
| 404 | Unknown path or jobId |
| 405 | Wrong HTTP method |
| 409 | Job was cancelled |
| 413 | Request body too large (max 256 MB) |
| 502 | Generation / model server error |
| 503 | Model busy or still loading (retryable) |
| 504 | Timed out after 600 s (use async) |
Each item in images is an https URL, a data URL (data:image/png;base64,...) or raw base64. Max 10 images, 25 MB each. URLs must be https and public (private/localhost addresses are rejected). If a site blocks downloads, send the image as base64.