# Qwen-Image-2512 (`qwen-image-2512`) > Image Fast text to image: Qwen-Image-2512, open weights Qwen/Qwen-Image-2512 (Apache-2.0). Beta: the image API may change before the image supplier confirms that images can be served through this platform. On Pershot, every job is quoted before it runs, credits are held and settled on delivery, and failed or refused jobs are not charged. Generated from the same catalog, OpenAPI document and price engine the API uses. Live status (available, degraded, paused) and suppliers: GET /v1/models or the MCP tool list_models. The same facts as JSON: the MCP tool `get_model` with model "qwen-image-2512". All models: https://pershot.app/llms.txt ## What it is - Model id: `qwen-image-2512` (image, Qwen-Image, Image Fast tier, generate; tag: recommended) - Weights: Qwen/Qwen-Image-2512 - Endpoint: POST https://api.pershot.app/v1/images/generations ## Inputs - text: `prompt` (required). 2 to 2,000 characters. - image: `image_url`. Not taken: this model generates from text. To edit an image, use qwen-image-edit-2511. ## Legal values and defaults - size: 1K, 2K (default 1K) - aspect_ratio: 16:9, 9:16, 1:1 (default 1:1) - source image: none - images per job: 1 - output: JPEG; 1K: 16:9 1344×768, 9:16 768×1344, 1:1 1024×1024; 2K: 16:9 2048×1152, 9:16 1152×2048, 1:1 2048×2048 ## Request fields JSON body; unknown fields are refused (400 invalid_request). Header `Idempotency-Key` is required. - model: string, required, qwen-image-2512-lightning · qwen-image-2512 · qwen-image-edit-2511-lightning · qwen-image-edit-2511. Send "qwen-image-2512" for this model. - prompt: string, required, 2–2000 characters. What to render. - size: string, optional, default "1K", 1K · 2K. 1K for drafts and first frames, 2K for detail. - aspect_ratio: string, optional, default "1:1", 16:9 · 9:16 · 1:1. Frame shape. It does not change the price. - image_url: string, optional, public https URL. Refused: generate models take text only. - seed: integer, optional, 0–2147483647. Repeat a result with the same inputs. - quote_id: string, optional, starts with qt_. Run at a quote from POST /v1/quotes (valid 10 minutes). Send exactly one of quote_id or max_credits. - max_credits: number, optional, > 0. The most this job may cost; above it the job is refused, never charged. Send exactly one of quote_id or max_credits. - webhook_url: string, optional, public https URL. An https URL that receives this job's events (see Async flow). - end_user_id: string, optional, 1–128 characters. For approved developer accounts (developer API access is by application): your own user id for this request, shown in usage. - project_id: string, optional, starts with prj_. Attribute the job to one of your projects; the project's budget applies. - shot_id: string, optional, starts with sht_. Make the job a new version of this project shot. - routing_preference: string, optional, stability · speed. How to order the model's suppliers: stability (default) or speed. The price is the same with every supplier. ## Prices - 1K: 2 credits (≈ $0.02) per image, any aspect ratio. - 2K: 6 credits (≈ $0.06) per image, any aspect ratio. - The creative and developer API price lists are the same today. One price per image by size; the aspect ratio does not change it. POST /v1/quotes (MCP quote) returns the exact price before a job runs. ## Example request Body: ```json { "model": "qwen-image-2512", "prompt": "A ceramic mug on a walnut table, soft window light, product photo", "size": "1K", "aspect_ratio": "1:1", "max_credits": 2 } ``` cURL: ```sh curl https://api.pershot.app/v1/images/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen-image-2512", "prompt": "A ceramic mug on a walnut table, soft window light, product photo", "size": "1K", "aspect_ratio": "1:1", "max_credits": 2 }' ``` Python: ```python import os, uuid, requests res = requests.post( "https://api.pershot.app/v1/images/generations", headers={ "Authorization": f"Bearer {os.environ['API_KEY']}", "Idempotency-Key": str(uuid.uuid4()), }, json={ "model": "qwen-image-2512", "prompt": "A ceramic mug on a walnut table, soft window light, product photo", "size": "1K", "aspect_ratio": "1:1", "max_credits": 2 }, ) job = res.json() # 202 → {"id": "job_…", "status": "queued"} ``` JavaScript (Node): ```js const res = await fetch("https://api.pershot.app/v1/images/generations", { method: "POST", headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ model: "qwen-image-2512", prompt: "A ceramic mug on a walnut table, soft window light, product photo", size: "1K", aspect_ratio: "1:1", max_credits: 2 }), }); const job = await res.json(); // 202 → { id: "job_…", status: "queued" } ``` ## Async flow 1. Create: POST https://api.pershot.app/v1/images/generations with the Authorization and Idempotency-Key headers. Answers 202 with a Job (id "job_…", status "queued", money_status "reserved"): the credits are held, not charged. 2. Poll: GET https://api.pershot.app/v1/jobs/{id} until status is succeeded, failed or cancelled. "unknown" means the outcome is being checked with the model: keep polling; the credits stay held and are never charged twice. Statuses: queued, processing, succeeded, failed, cancelled, unknown. 3. Or webhooks: pass `webhook_url` (https) for job.queued, job.processing, job.succeeded, job.failed, job.cancelled. X-Signature: t=,v1=.")>, keyed with your whsec_ secret; refuse timestamps older than five minutes and dedupe on X-Event-Id. A 2xx within 10 seconds counts as delivered; failed deliveries retry after 1 min, 5 min, 30 min, 2 h and 6 h. Redirects are not followed. 4. Results: outputs[].url is a signed link valid 24 hours; GET the job again for a fresh one. Files are kept 12 months (outputs_expire_at), longer when saved to the library or a project. - Idempotency: The same Idempotency-Key within 24 hours returns the same job with HTTP 200, so a retry after a timeout never creates or charges a second job. Use a new key for a new job. - Cancel: POST https://api.pershot.app/v1/jobs/{id}/cancel refunds the held credits unless the model has already accepted the job. - Charge: Succeeded: charged the quoted credits at most (credits_charged). Failed, refused or canceled before the model started: the held credits are refunded and nothing is charged. ## Errors Shape: {"error": {"code", "message", "param", "details", "request_id"}}. Retry: fix = change the request first; wait = the same request may work later; no = do not send it again as is. - 400 invalid_request (retry: fix): A field is missing or out of range; `param` names it. Fix it and send again. Nothing was quoted or held. - 401 unauthorized (retry: fix): Check the key and the `Authorization: Bearer` header. - 402 insufficient_credits (retry: fix): Not enough credits in the account this credential spends (`details.account`: creative or api). Top up, then retry with the same Idempotency-Key. - 403 forbidden_model (retry: fix): The key's allowlist leaves this model out, or the model is paused. Add it to the key in the studio or use another key. - 403 region_not_supported (retry: no): This model is not sold in the caller's region. GET /v1/models lists what is. - 403 developer_api_closed (retry: no): Developer API access is by application: request it on the API keys page in the studio. For the person's own work, sign in instead (MCP or device login): no key is needed. - 403 member_connections_paused (retry: no): Connecting a person's own AI agent is paused for now. Nothing was charged; the studio still works. - 404 not_found (retry: fix): The quote or job id is unknown to this account. Quotes belong to the account that made them. - 409 quote_expired (retry: fix): Quotes last 10 minutes. Get a new quote, or send max_credits instead. - 409 price_changed (retry: fix): The price is above your max_credits cap. Quote again or raise the cap; nothing was charged. - 422 content_rejected (retry: fix): The prompt or an image was refused. Nothing was charged. Change the prompt or the images. - 429 rate_limited (retry: wait): Too many requests. Wait for Retry-After, then send the same request again. - 429 concurrency_limited (retry: wait): Too many jobs running at once for this account. Wait for one to finish (Retry-After), then retry. - 500 internal_error (retry: wait): Our error. Retry with the same Idempotency-Key: a job that was created is returned, never created twice. - 503 upstream_unavailable (retry: wait): The model is not responding. Retry later; a job that never starts is not charged. ## Limits - enforced: we check it and answer 400 invalid_request (or refuse the upload) before anything is quoted or held. upstream: the supplier refuses past it; the job fails with invalid_request and nothing is charged. recommended: not checked. Links to other hosts are never fetched by us, so the supplier checks those images. Limits (qwen-image-2512): - prompt_length: 2 to 2,000 characters [enforced; past it: 400 invalid_request before any quote or hold (param prompt)] - size: 1K, 2K (default 1K) [enforced; past it: 400 invalid_request before any quote or hold (param size)] - aspect_ratio: 16:9, 9:16, 1:1 (default 1:1) [enforced; past it: 400 invalid_request before any quote or hold (param aspect_ratio)] - source_image: none [enforced; past it: 400 invalid_request before any quote or hold (param image_url)] - output_pixels: 1K: 16:9 1344×768, 9:16 768×1344, 1:1 1024×1024; 2K: 16:9 2048×1152, 9:16 1152×2048, 1:1 2048×2048 px [enforced; past it: fixed: every output has it] - output_side: 256 to 2,048 px per side [upstream; past it: the supplier refuses the job; it fails and nothing is charged] - output_format: JPEG [enforced; past it: fixed: every output has it] - output_link_ttl: 24 hours [enforced; past it: the link answers 403 after that] ## MCP - Server: https://mcp.pershot.app/mcp. Sign in through the client (OAuth), or send a connection code as a Bearer header. A developer API key (by application) also works as a Bearer header. - `get_model`: These facts as JSON (free, read only). - `list_models`: Every model with its live status and suppliers, as GET /v1/models. - `quote`: The exact price of one job and a quote_id valid 10 minutes, as POST /v1/quotes. - `create_upload`: Check a public https image link so it can be used as image_url. - `generate_image` (spends credits): Run the job, as POST /v1/images/generations; needs idempotency_key and quote_id or max_credits. - `wait_for_job`: Wait up to 60 seconds for the job, then return it. - `get_job`: The job's status, output links and charge, as GET /v1/jobs/{id}. - `cancel_job`: Cancel a job the model has not started; its credits are refunded. ## Links - page: https://pershot.app/models/qwen-image - api reference: https://pershot.app/models/qwen-image/api - llms txt: https://pershot.app/models/qwen-image-2512/llms.txt - all models: https://pershot.app/llms.txt - openapi: https://pershot.app/api/v1/openapi.json - docs: https://pershot.app/docs - migrate: https://pershot.app/docs/migrate - pricing method: https://pershot.app/pricing/method