Перейти к основному контенту

Редактирование Qwen Image 2.1 правит от одного до десяти референсов по письменной инструкции и возвращает один кадр в 1k, 1.5k или 2k. Умеет и локальные правки по чёрно-белой маске, где белое перерисовывается.

От $0.036/изобр.

Рабочая область

Отправить запрос

Быстрый старт

Примеры используют публичные параметры выбранного эндпоинта. Замените API-ключ и примеры медиафайлов, затем отправьте запрос со своего сервера.

SDK и интеграции
POSThttps://api.spicyapi.ai/api/v1/jobs/createTask

Аутентификация API

Храните API-ключ в серверной переменной окружения SPICY_API_KEY. Используйте Bearer-аутентификацию и Content-Type: application/json для JSON-запросов.

Authorization: Bearer $SPICY_API_KEY
Qwen Image 2.1 · Image Editing · Пример результата
Пример результатаИспользовать пример
# Generate the idempotency key once; reuse it when retrying after a lost response.
export SPICY_IDEMPOTENCY_KEY="${SPICY_IDEMPOTENCY_KEY:-$(uuidgen)}"
curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
  -d '{
  "model": "alibaba/qwen-image-2.1/edit",
  "input": {
    "aspect_ratio": "1:1",
    "background": "opaque",
    "image_urls": [
      "https://example.com/reference.png"
    ],
    "output_format": "jpeg",
    "prompt": "A ceramic teapot on a linen cloth, soft window light, muted palette",
    "resolution": "1k"
  }
}'

# Copy data.taskId from the response into TASK_ID, then poll the status.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.spicyapi.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $SPICY_API_KEY"

Пример построен по входной схеме этой модели — той же, по которой API проверяет каждый запрос.

Входные параметры

Поместите эти поля в объект input тела запроса. Имена и типы соответствуют API. Не предполагайте значение по умолчанию, если оно не задано.

image_urlsarray<string>ОбязательноВлияет на цену

От одного до десяти референсов. Роли модель сама не назначает, поэтому назовите в prompt, что вносит каждый источник: где человек, где обстановка, где одежда. Любой добавленный референс поднимает смету, так что отправляйте только работающие.

По умолчанию
Не задано
Ограничения
minItems:1
maxItems:10
promptstringОбязательно

До 5000 символов. Негативного промпта в этом семействе нет, поэтому исключения тоже идут сюда: назовите, что в кадре, а затем прямо скажите, чего в нём быть не должно. Одно связное описание работает лучше груды ключевых слов.

По умолчанию
Не задано
Ограничения
minLength:1
maxLength:5000
seedintegerНеобязательно

Стабилизирует выборку, чтобы серия держалась в одном регистре. Гарантией воспроизведения он не является: мы дважды отправили один и тот же запрос с одним и тем же seed и получили два разных кадра. Когда нужен именно тот кадр, сохраняйте вернувшийся результат.

По умолчанию
Не задано
Ограничения
minimum:0
maximum:2147483647
output_formatstringНеобязательно

По умолчанию JPEG. PNG — когда кадр уходит в композитинг, WebP — когда он сразу отправляется на страницу. Контейнер не меняет ни цену, ни сам рендер.

По умолчанию
"jpeg"
Допустимые значения
"jpeg""png""webp"
backgroundstringНеобязательно

По умолчанию opaque. transparent возвращает только объект на настоящем альфа-канале: используйте его с выводом png или webp (у jpeg нет альфа-канала, и запрос отклоняется) и описывайте только объект — упоминание комнаты, поверхности или сцены может вернуть фон. Доступно на 1k и 2k, на 1.5k — нет. На цену не влияет. Не сочетается с mask_url.

По умолчанию
"opaque"
Допустимые значения
"opaque""transparent"
enable_prompt_expansionbooleanНеобязательно

По умолчанию включено: перед генерацией промпт переписывается в более подробное описание сцены. Выключите, чтобы ваша формулировка использовалась как есть. Выключить можно на 1k и 2k, на 1.5k — нельзя. На цену не влияет. При заданном mask_url не действует.

По умолчанию
true
resolutionstringНеобязательноВлияет на цену

Уровень, задающий размер вывода и цену: 1k — значение по умолчанию и самый дешёвый уровень, 1.5k находится посередине, на 2k держатся фактура кожи, волосы и плетение ткани. Итерируйте на 1k, удачный кадр поднимайте до 2k.

По умолчанию
"1k"
Допустимые значения
"1k""1.5k""2k"
aspect_ratiostringНеобязательно

Собирает кадр до генерации, а не обрезает после, поэтому берите форму, в которой будете публиковать. Пятнадцать вариантов: от полос 3:1 и 21:9 до колонок 1:3 и 9:21. Все пропорции стоят одинаково.

По умолчанию
"1:1"
Допустимые значения
"1:1""16:9""9:16""4:3""3:4""3:2""2:3""21:9""9:21""2:1""1:2""3:1""1:3""5:4""4:5"
mask_urlstringНеобязательно

Необязательное чёрно-белое изображение, которое переводит правку в локальный режим: белое — область, которая перерисовывается, чёрное остаётся как есть, а мягкий край в несколько пикселей помогает переходу. Используйте его ровно с одним референсным изображением тех же пропорций (маска другого размера масштабируется) и опишите в промпте, что должно появиться в белой области. Результат сохраняет форму референсного изображения, поэтому aspect_ratio игнорируется, и с прозрачным фоном маску не совместить. Доступно на 1k и 2k, на 1.5k — нет. На цену не влияет.

По умолчанию
Не задано
Ограничения
format:"uri"
contentMediaType:["image/jpeg","image/png","image/webp","image/gif"]

Отследить задачу

HTTP 202 означает принятие задачи, а не завершение генерации. Сохраните полученный taskId и проверяйте эту задачу. Не создавайте новую, пока ждёте результат.

Ответ при приёме задачи
HTTP/1.1 202 Accepted
Location: /api/v1/jobs/recordInfo?taskId=job_01k3m8x9q2z4v7n5p6r8s0t1w3

{
  "code": 200,
  "msg": "success",
  "request_id": "req_example_create",
  "data": {
    "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "state": "queued",
    "estimatedCost": "0.750000"
  }
}

В ответе о приёме есть оценка стоимости — приложение сможет показать ту же сумму в истории задач и в расчётах.

Получить задачу
curl --get "https://api.spicyapi.ai/api/v1/jobs/recordInfo" \
  --data-urlencode "taskId=$TASK_ID" \
  -H "Authorization: Bearer $SPICY_API_KEY"

Начните с интервала около 2 секунд и постепенно увеличивайте его. Прекратите опрос при конечном состоянии. После сбоя соединения используйте исходный taskId. Повторно создавать задачу можно только с исходным ключом идемпотентности и исходным телом запроса.

Или пусть вызов придёт сам
import { verifyWebhook } from "@spicyapi/sdk";

// express.raw keeps the bytes we signed; express.json never matches.
app.post("/hooks/spicy", express.raw({ type: "application/json" }), (req, res) => {
  const { payload } = verifyWebhook({
    rawBody: req.body,
    timestamp: req.header("X-Webhook-Timestamp"),
    signature: req.header("X-Webhook-Signature"),
    payloadVersion: Number(req.header("X-Webhook-Payload-Version")),
    secret: process.env.SPICY_WEBHOOK_SECRET,
  });
  res.status(200).end();
  void handleFinishedTask(payload);
});

Передайте callBackUrl при создании задачи — готовая запись придёт к вам POST-запросом, и никакого опроса не понадобится. В каждой доставке есть X-Webhook-Timestamp, X-Webhook-Signature и X-Webhook-Payload-Version. Подпись — это HMAC-SHA256 в base64 от taskId.timestamp.sha256(body), поэтому проверять её нужно по исходным байтам: если разобрать JSON и сериализовать заново, байты изменятся и проверка не пройдёт. Неудачные доставки повторяются, так что один и тот же taskId может прийти дважды — сделайте обработчик идемпотентным. Сначала ответьте 2xx, работу выполняйте после: медленный обработчик считается неудачной доставкой.

Прочитать результат

Обрабатывайте output только при state, равном succeeded. При ошибке проверьте errorCode, errorMessage и request_id. Стоимость и состояния в примерах не являются фактическим счётом.

Пример ответа после завершения
{
  "code": 200,
  "msg": "success",
  "request_id": "req_example_record",
  "data": {
    "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "model": "alibaba/qwen-image-2.1/edit",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "key": "tasks/2026/08/28/job_01k3m8x9q2z4v7n5p6r8s0t1w3/3f7a1c9e5b2d48f0a6c1e3d5b7f9a1c3.png",
          "mime": "image/png",
          "url": "https://example.r2.cloudflarestorage.com/results/job_01k3m8x9q2z4v7n5p6r8s0t1w3/result.png?X-Amz-Signature=SIGNATURE_FROM_RESPONSE",
          "expiresAt": "2026-08-28T12:20:08.000Z"
        }
      ]
    },
    "cost": "0.750000",
    "settled": true,
    "createdAt": "2026-08-28T12:00:00Z",
    "completedAt": "2026-08-28T12:00:30Z"
  }
}

Доступные файлы можно открыть или скачать по assets[].url без заголовка API Authorization. Подписанная ссылка действует до expiresAt. Чтобы обновить её, повторно запросите задачу в течение срока хранения файла. У ожидающих или недоступных файлов URL отсутствует. Не передавайте подписанные ссылки посторонним.

SDK и интеграции

Используйте SpicyAPI в приложении, терминале, ИИ-ассистенте или визуальном процессе. Выберите руководство по настройке.

Использование в ComfyUI

Установите узлы SpicyAPI через ComfyUI Manager или командой ниже и найдите на холсте Qwen Image 2.1 · Image Editing. У узла те же параметры, что и на этой странице, а цена показывается до запуска.

cd ComfyUI/custom_nodes
git clone https://github.com/spicyapi-ai/comfyui-spicyapi