Qwen-ImageReferência da API
Gere e edite imagens com os modelos Qwen-Image por código: um início rápido em três etapas, todos os campos, créditos por imagem, webhooks e idempotência.
O acesso à API para desenvolvedores é por solicitação.
A API de imagens está em beta, e os campos podem mudar. O estúdio não é afetado.
Início rápidoem três chamadas
Defina uma chave, envie a tarefa com um limite de preço e depois leia o resultado.
- 01
Defina sua chave
O acesso à API para desenvolvedores é por solicitação: peça no estúdio, em Chaves de API. A chave é exibida uma única vez, então guarde-a em uma variável de ambiente.
export API_KEY="sk_test_…" - 02
Envie a tarefa
Envie a imagem por POST com um Idempotency-Key e um limite max_credits. Os modelos de edição também recebem image_url. Você recebe 202 e uma tarefa na fila, e os créditos ficam reservados.
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 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "image", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "qwen-image-2512", "credits_quoted": 2, "credits_charged": null } - 03
Leia o resultado
Consulte a tarefa por GET até o status ser succeeded. outputs[].url é assinada e expira após 24 horas, então baixe o que quiser guardar.
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"
Parâmetrose limites
Lidos do documento OpenAPI, que é gerado a partir dos mesmos esquemas que a API usa na validação. Campos desconhecidos são recusados.
| Campo | Tipo | Valores aceitos | Observações |
|---|---|---|---|
modelObrigatório | string | qwen-image-2512-lightning · qwen-image-2512 · qwen-image-edit-2511-lightning · qwen-image-edit-2511 | O ID do modelo. |
promptObrigatório | string | 2–2.000 caracteres | O que gerar: o assunto, a câmera e a luz. |
sizePadrão: "1K" | string | 1K · 2K | 1K para rascunhos e primeiros quadros, 2K para detalhes. |
aspect_ratioPadrão: "1:1" | string | 16:9 · 9:16 · 1:1 | Formato do quadro. |
image_urlOpcional | string | URL https | Primeiro quadro do vídeo; a imagem de origem nos modelos de edição. Uma URL https pública ou a URL de um arquivo enviado. |
seedOpcional | integer | 0–2.147.483.647 | Repete um resultado com as mesmas entradas. |
quote_idOpcional | string | qt_… | Executa pelo preço de uma cotação de POST /v1/quotes, válida por 10 minutos. |
max_creditsOpcional | number | > 0 | O máximo que esta tarefa pode custar. Acima disso, a tarefa é recusada, nunca cobrada. |
webhook_urlOpcional | string | URL https | Uma URL https que recebe os eventos da tarefa. |
end_user_idOpcional | string | 1–128 caracteres | Para contas de desenvolvedor aprovadas (o acesso é por solicitação): o seu próprio ID de usuário para esta solicitação, exibido nos dados de uso. |
project_idOpcional | string | prj_… | |
shot_idOpcional | string | sht_… | |
routing_preferenceOpcional | string | stability · speed |
Envie exatamente um entre quote_id e max_credits. Este endpoint recusa model "auto": para vídeo, chame primeiro POST /v1/auto/plan e depois envie o modelo escolhido com max_credits.
- Modelos
qwen-image-2512-lightningGeração · Qwen-Image-2512 · Lightning 4-stepqwen-image-edit-2511-lightningEdição · Qwen-Image-Edit-2511 · Lightningqwen-image-2512Geração · Qwen-Image-2512qwen-image-edit-2511Edição · Qwen-Image-Edit-2511- Taxa de requisições e simultaneidade
- 60 requisições por minuto por chave e 3 tarefas ao mesmo tempo por conta, por padrão. Mais chaves não aumentam a simultaneidade.
- Para agentes de IA
- Texto simples para agentes de IA: entradas, valores aceitos, cada preço e um exemplo de requisição
qwen-image-2512-lightningqwen-image-2512qwen-image-edit-2511-lightningqwen-image-edit-2511
Limites
Lidos da mesma tabela que a API usa nas verificações. Cada linha diz quem verifica o limite e o que acontece quando ele é ultrapassado.
- Validado por nósVerificamos e respondemos 400 antes de qualquer cotação ou reserva.
- Validado pelo fornecedorO fornecedor verifica. Uma tarefa recusada por ele falha, e nada é cobrado.
- RecomendadoNinguém verifica. Ficar dentro do limite dá resultados melhores.
| Limite | Valor | Unidade | Quem verifica | Acima do limite |
|---|---|---|---|---|
| Requisição | ||||
Tamanho do promptprompt | 2 a 2.000 | caracteres | Validado por nós | 400 invalid_request no campo prompt, antes de qualquer cotação ou reserva. |
Tamanho da imagemsize | 1K, 2KPadrão: 1K | – | Validado por nós | 400 invalid_request no campo size. |
Proporçãoaspect_ratio | 16:9, 9:16, 1:1Padrão: 1:1 | – | Validado por nós | 400 invalid_request no campo aspect_ratio. |
| Imagens que você envia | ||||
Imagem de origemimage_url | Nenhuma | – | Validado por nós | Modelos de edição exigem image_url, e modelos de geração o recusam: 400 invalid_request no campo image_url. |
| Saída | ||||
| Pixels de saída | 1K16:91344×7689:16768×13441:11024×10242K16:92048×11529:161152×20481:12048×2048 | px | Validado por nós | Pedimos exatamente estes tamanhos. |
| Lado da saída | 256 a 2.048 | px por lado | Validado pelo fornecedor | Todos os tamanhos acima estão dentro do limite. O fornecedor recusa tamanhos maiores. |
| Formato de saída | JPEG | – | Validado por nós | Toda imagem é um JPEG. |
| Links | ||||
| Link do resultado | 24 | horas | Validado por nós | Depois disso, o link responde 403. Faça um novo GET da tarefa para obter um link novo. O arquivo em si é mantido por 12 meses (outputs_expire_at da tarefa indica a data), e por mais tempo se o resultado estiver salvo em Mídias ou for usado em um projeto. |
| Limite | Valor | Unidade | Quem verifica | Acima do limite |
|---|---|---|---|---|
| Requisição | ||||
Tamanho do promptprompt | 2 a 2.000 | caracteres | Validado por nós | 400 invalid_request no campo prompt, antes de qualquer cotação ou reserva. |
Tamanho da imagemsize | 1K, 2KPadrão: 1K | – | Validado por nós | 400 invalid_request no campo size. |
Proporçãoaspect_ratio | 16:9, 9:16, 1:1Padrão: 1:1 | – | Validado por nós | 400 invalid_request no campo aspect_ratio. |
| Imagens que você envia | ||||
Imagem de origemimage_url | Exatamente 1 | – | Validado por nós | Modelos de edição exigem image_url, e modelos de geração o recusam: 400 invalid_request no campo image_url. |
Tamanho do enviofile | até 10 | MB | Validado por nós | POST /v1/uploads responde 400 invalid_request no campo file. |
Formatos de enviofile | JPEG, PNG, WebP | – | Validado por nós | Identificado pelo próprio arquivo, não pelo nome dele. Qualquer outro: 400 invalid_request no campo file. |
| Saída | ||||
| Pixels de saída | 1K16:91344×7689:16768×13441:11024×10242K16:92048×11529:161152×20481:12048×2048 | px | Validado por nós | Pedimos exatamente estes tamanhos. |
| Lado da saída | 512 a 2.048 | px por lado | Validado pelo fornecedor | Todos os tamanhos acima estão dentro do limite. O fornecedor recusa tamanhos maiores. |
| Formato de saída | JPEG | – | Validado por nós | Toda imagem é um JPEG. |
| Links | ||||
| Link de envio | 7 | dias | Validado por nós | Depois disso, o link responde 403. Envie o arquivo de novo. |
| Link do resultado | 24 | horas | Validado por nós | Depois disso, o link responde 403. Faça um novo GET da tarefa para obter um link novo. O arquivo em si é mantido por 12 meses (outputs_expire_at da tarefa indica a data), e por mais tempo se o resultado estiver salvo em Mídias ou for usado em um projeto. |
Nunca buscamos imagens em outros sites, então, nesses links, quem verifica o tamanho é o fornecedor, e uma tarefa que ele recusa não é cobrada. Os mesmos limites também vêm em JSON: GET /v1/models retorna um objeto limits para cada modelo.
Preçoscalculados às claras
Um preço por imagem, por modelo e tamanho, em créditos (US$ 1 = 100 créditos). Geração e edição têm preços separados.
| Modelo | 1K | 2K |
|---|---|---|
qwen-image-2512-lightningGeração | 1 cr≈ US$ 0,01≈ 1.000 imagens por US$ 10 | 3 cr≈ US$ 0,03≈ 333 imagens por US$ 10 |
qwen-image-edit-2511-lightningEdição | 2 cr≈ US$ 0,02≈ 500 imagens por US$ 10 | 4 cr≈ US$ 0,04≈ 250 imagens por US$ 10 |
qwen-image-2512Geração | 2 cr≈ US$ 0,02≈ 500 imagens por US$ 10 | 6 cr≈ US$ 0,06≈ 166 imagens por US$ 10 |
qwen-image-edit-2511Edição | 3 cr≈ US$ 0,03≈ 333 imagens por US$ 10 | 10 cr≈ US$ 0,10≈ 100 imagens por US$ 10 |
Webhookse idempotência
Novas tentativas nunca geram cobrança dupla, e você não precisa consultar a tarefa periodicamente.
- Idempotência
- Todo POST de geração exige um Idempotency-Key (de 1 a 255 caracteres ASCII visíveis). A mesma chave dentro de 24 horas retorna a mesma tarefa com HTTP 200, então uma nova tentativa após um timeout nunca cria nem cobra uma segunda tarefa.
- Prompts recusados
- Um prompt recusado pela pré-verificação (422 content_rejected) não cria nada, então a mesma chave pode ser usada de novo com um novo prompt.
- Eventos
job.queuedjob.processingjob.succeededjob.failedjob.cancelled- Assinatura
- X-Signature traz t, o tempo Unix, e v1, um HMAC-SHA256 de t, um ponto e o corpo bruto, com o seu segredo whsec_ como chave. Recuse carimbos de data/hora com mais de cinco minutos e elimine duplicatas pelo X-Event-Id.
- Entrega
- Um 2xx em até 10 segundos conta como entregue. Entregas com falha são repetidas após 1 min, 5 min, 30 min, 2 h e 6 h. Redirecionamentos não são seguidos.
{
"id": "evt_01J9ZKB1QX",
"type": "job.succeeded",
"created_at": "2026-09-29T14:02:31Z",
"data": {
"job": {
"id": "job_01J9ZK4T8W",
"object": "job",
"kind": "image",
"status": "succeeded",
"money_status": "settled",
"requested_model": "qwen-image-2512",
"credits_charged": 2,
"outputs": [
{
"kind": "image",
"url": "https://…/job_01J9ZK4T8W.png?sig=…"
}
]
}
}
}import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.Errose o que fazer
Todo erro tem o mesmo formato: um objeto error com code, message, param e request_id. Os que você tem mais chance de encontrar:
| Código | HTTP | O que fazer |
|---|---|---|
invalid_request | 400 | Corrija o campo indicado em param. |
unauthorized | 401 | Verifique a chave e o cabeçalho Bearer. |
insufficient_credits | 402 | Recarregue e tente de novo com o mesmo Idempotency-Key. |
forbidden_model | 403 | Adicione o modelo ou a ferramenta à lista de permissões da chave no estúdio, ou use outra chave. Ferramentas como Aprimorar precisam de uma entrada própria. |
quote_expired | 409 | Peça uma nova cotação; as cotações valem por 10 minutos. |
price_changed | 409 | O preço subiu acima do seu limite. Faça uma nova cotação ou aumente max_credits. |
content_rejected | 422 | Nada foi cobrado. Altere o prompt ou as imagens. |
rate_limited | 429 | Aguarde o Retry-After e tente de novo. |
upstream_unavailable | 503 | O modelo está indisponível. Tente de novo mais tarde; uma tarefa que nunca começa não é cobrada. |