HiAPI
Блог

Руководство

Генерация фотографий товаров для электронной коммерции с помощью FLUX.1 [schnell] через API hiapi

Готовое к запуску руководство с curl + Python, охватывающее каталожные снимки на белом фоне, сцены и варианты — $0.005 за изображение.

Jun 28, 2026
Генерация фотографий товаров для электронной коммерции с помощью FLUX.1 [schnell] через API hiapi

Каталожная съёмка — самый медленный этап при публикации SKU в интернет-магазине. Заказывать студию, нанимать стилиста, ставить софтбоксы, приглашать ретушёра — для кружки за $24 это совершенно неоправданно. flux-schnell/text-to-image на hiapi позволяет получить пригодные каталожные снимки на чистом белом фоне, сценические главные изображения и снимки цветовых/материальных вариантов по цене $0.005 за изображение и примерно за 30 секунд от начала до конца — при таком масштабе вы перестаёте думать о стоимости одного снимка и начинаете думать о промптах и пакетах промптов.

Это руководство проведёт вас через точный рабочий процесс: четыре типа изображений, которые реально нужны странице товара; структура промпта, которая удерживает модель на чистом бесшовном фоне, а не заставляет её выдумывать деревянный стол; как пакетно генерировать 100 вариантов через /v1/tasks, не обрушив терминал; и несколько вещей, которые schnell не умеет делать, — их нужно планировать заранее.

Почему каталожная работа особенно хорошо подходит для flux-schnell

На hiapi есть и более точные модели (flux-2, flux-1.1-pro, nano-banana-pro), и если вам нужен тот самый главный снимок для брендовой кампании, используйте их. Но для каталога арифметика другая:

  • Обновление ассортимента из 200 SKU, каждому нужно примерно 4 изображения (белый фон, сцена, масштабный ориентир, вид сверху) = 800 изображений. По $0.005 это $4. По $0.05 это $40. По $0.17 это $136.
  • schnell завершает генерацию за 1–4 шага сэмплирования, поэтому от начала до конца (очередь + генерация + загрузка) в наших запусках занимает около 30 секунд. flux-2 и nano-banana-pro работают в несколько раз медленнее.
  • Каталожные изображения отображаются на странице товара шириной 600px, а в сетке — 200px. При таких размерах запас точности продвинутых моделей просто не виден; гораздо важнее соблюдение промпта и разумность соотношения сторон.

Компромисс реальный: schnell слаб в мелком читаемом тексте на этикетках, слаб в изображении реального человека, держащего товар (для этого используйте nano-banana-pro), и заметно слаб в сложных брендовых логотипах. Но для задачи «покажи мне товар на чистом фоне, в трёх цветах, сверху и в три четверти» — то есть для его прямой работы — он превосходен.

Перечень изображений, которые вам действительно нужно сгенерировать

Прежде чем писать какие-либо промпты, определите, что нужно вашему шаблону страницы товара. Полезный стартовый набор:

Тип изображения Соотношение сторон Для чего
Снимок товара на белом фоне 1:1 Главное изображение страницы товара, миниатюра в сетке
Студийный снимок в три четверти 4:3 Второе изображение в галерее страницы товара
Сценическое / ситуативное изображение 3:2 Галерея страницы товара, реклама в соцсетях
Снимок сверху в раскладке 1:1 Галерея страницы товара, масштабный ориентир
Сетка цветовых/материальных вариантов по 1:1 на каждый вариант Миниатюры выбора цвета

flux-schnell на hiapi поддерживает 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9, auto. Любое другое соотношение будет отклонено при создании задачи.

Однократный запуск: генерация одного изображения товара с помощью curl

Минимальный набор для проверки работоспособности токена. Мой последний запуск занял 31 секунду от начала до конца:

TOKEN="$HIAPI_API_KEY"

# 1. Создать задачу
TASK=$(curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-schnell/text-to-image",
    "input": {
      "prompt": "Product packshot: matte ceramic coffee mug, soft beige glaze, centered on seamless white cyclorama, soft diffused studio lighting, subtle contact shadow, 50mm photography, no props, ecommerce hero, clean negative space top and bottom",
      "aspect_ratio": "1:1"
    }
  }' | jq -r '.data.taskId')

echo "task: $TASK"

# 2. Опрашивать до завершения (success | fail)
while true; do
  STATE=$(curl -s "https://api.hiapi.ai/v1/tasks/$TASK" \
    -H "Authorization: Bearer $TOKEN")
  STATUS=$(echo "$STATE" | jq -r '.data.status')
  echo "  status=$STATUS"
  [ "$STATUS" = "success" ] && break
  [ "$STATUS" = "fail" ] && { echo "$STATE" | jq '.data.error'; exit 1; }
  sleep 4
done

# 3. Скачать (URL результата истекает; забирайте сразу)
URL=$(echo "$STATE" | jq -r '.data.output[0].url')
curl -s -o packshot.jpg "$URL"
echo "saved packshot.jpg"

Одна особенность, о которой нужно помнить именно для flux-schnell: входная схема этой модели принимает aspect_ratio, но отклоняет resolution. Другие модели изображений на hiapi (например, flux-2, nano-banana-pro) принимают оба параметра. Если вы отправите в flux-schnell {"aspect_ratio": "1:1", "resolution": "1K"}, вы получите:

{
  "code": 400,
  "message": "additional properties not allowed: resolution"
}

Уберите resolution. Он вам не нужен — schnell выводит изображение в размере модели по умолчанию для выбранного вами соотношения сторон.

Продакшен: пакетная генерация на Python

Настоящая каталожная работа включает отправку множества задач, загрузку результатов по мере готовности и повторные попытки для неудачных случаев. Вот скрипт, который мы использовали при прототипировании для линейки SKU:

"""Batch packshot generator for flux-schnell on hiapi.

Reads a CSV of (sku, prompt, aspect_ratio), submits all jobs, polls in parallel,
downloads finished outputs to ./out/{sku}.jpg. Total cost = $0.005 * len(csv).
"""
import csv
import json
import os
import subprocess
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path

API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]
OUT = Path("./out"); OUT.mkdir(exist_ok=True)


def _post(path, body):
    r = subprocess.run(
        ["curl", "-s", "-X", "POST", path,
         "-H", f"Authorization: Bearer {TOKEN}",
         "-H", "Content-Type: application/json",
         "-d", json.dumps(body)],
        capture_output=True, text=True, timeout=60,
    )
    return json.loads(r.stdout)


def _get(path):
    r = subprocess.run(
        ["curl", "-s", path, "-H", f"Authorization: Bearer {TOKEN}"],
        capture_output=True, text=True, timeout=30,
    )
    return json.loads(r.stdout)


def render(sku: str, prompt: str, ratio: str) -> tuple[str, str]:
    """Submit → poll → download. Returns (sku, status). status='ok' or 'fail:<reason>'."""
    body = {"model": "flux-schnell/text-to-image",
            "input": {"prompt": prompt, "aspect_ratio": ratio}}
    resp = _post(API, body)
    task_id = (resp.get("data") or {}).get("taskId")
    if not task_id:
        return sku, f"fail:submit:{resp.get('message')}"

    deadline = time.time() + 180
    while time.time() < deadline:
        state = _get(f"{API}/{task_id}")
        data = state.get("data") or {}
        status = data.get("status")
        if status == "success":
            url = (data.get("output") or [{}])[0].get("url")
            if not url:
                return sku, "fail:no-output-url"
            subprocess.run(["curl", "-s", "-o", str(OUT / f"{sku}.jpg"), url],
                           timeout=60, check=True)
            return sku, "ok"
        if status == "fail":
            return sku, f"fail:model:{data.get('error', {}).get('code')}"
        time.sleep(4)
    return sku, "fail:timeout"


def main():
    rows = list(csv.DictReader(open("skus.csv")))
    print(f"submitting {len(rows)} renders (cost ${0.005 * len(rows):.3f})")
    with ThreadPoolExecutor(max_workers=8) as ex:
        futures = {ex.submit(render, r["sku"], r["prompt"], r["aspect_ratio"]): r
                   for r in rows}
        for f in as_completed(futures):
            sku, status = f.result()
            print(f"  {sku}: {status}")


if __name__ == "__main__":
    main()

Одна строка skus.csv выглядит так:

sku,prompt,aspect_ratio
mug-beige-01,"Product packshot: matte ceramic mug, beige glaze, seamless white cyclorama, soft studio lighting, subtle contact shadow, 50mm photography, ecommerce hero, clean negative space",1:1
mug-charcoal-01,"Product packshot: matte ceramic mug, charcoal glaze, seamless white cyclorama, soft studio lighting, subtle contact shadow, 50mm photography, ecommerce hero, clean negative space",1:1

Замечания по продакшен-коду:

  • ThreadPoolExecutor(max_workers=8) — безопасная степень параллелизма для schnell. Больше только углубит очередь, но не ускорит завершение.
  • Тайм-аут 180 секунд на задачу — консервативная настройка; фактически каждая успешная задача завершается за 30–60 секунд. Срабатывание тайм-аута означает, что задача зависла — четыре причины см. в руководстве hiapi по зависаниям/тайм-аутам задач.
  • Мы скачиваем сразу после success. output[].url — это временная ссылка с меткой времени expireAt; не сохраняйте её в своей CMS.

Шаблоны промптов, дающие скучные, но полезные изображения товаров

Каталожные промпты — не творческие промпты. Вы хотите каждый раз одинаковое освещение, одинаковый фон, одинаковую камеру, меняя только товар. Один шаблон:

Product packshot: {MATERIAL} {PRODUCT}, {COLOR} {FINISH},
{COMPOSITION},
{BACKGROUND},
{LIGHTING},
{LENS_NOTE},
ecommerce hero, no props, clean negative space {AREA}

После заполнения:

Product packshot: matte ceramic coffee mug, soft beige glaze,
centered single subject filling about 60% of frame,
seamless white cyclorama background,
soft diffused studio lighting from the upper left, subtle contact shadow underneath,
shot on 50mm with shallow depth of field,
ecommerce hero, no props, clean negative space top and bottom

Порядок не так важен, как структура. Вот что стабильно улучшает результат:

  • «seamless white cyclorama» лучше, чем «white background» — первое подразумевает студийный бесшовный фон с освещением, второе иногда даёт вам кусок скатерти.
  • «subtle contact shadow underneath» предотвращает появление у товара эффекта парения.
  • «filling about 60% of frame» закрепляет композицию; без него schnell иногда отъезжает слишком далеко или сдвигает товар в угол.
  • «no props» предотвращает появление лишней тарелки, листа или канцелярии рядом с кружкой.

Для сценических вариантов замените блок фона + освещения:

... matte ceramic coffee mug, soft beige glaze, single subject filling about 40% of frame,
on a light oak countertop with morning sunlight from a kitchen window,
soft golden-hour rim lighting, gentle defocused background showing a blurred linen curtain,
shot on 35mm at f/2.8, lifestyle photography, no people, no other props

Для снимка сверху в раскладке:

... single subject centered, top-down 90-degree angle, ceramic coffee mug, soft beige glaze,
on a light grey paper surface, soft even overhead lighting, soft shadow directly under the rim,
shot on 50mm, flatlay product photography, no props, clean negative space all sides, 1:1

Запустите эти три промпта для одного SKU — и получите пригодную галерею страницы товара за $0.015.

Цветовые/материальные варианты без пересъёмки

Именно генерация вариантов — то, в чём schnell блистает в электронной коммерции. Как только промпт работает для одного цвета, вы можете массово произвести остальные цвета, заменив цветовой дескриптор строкой:

COLORS = [
    ("beige", "soft beige glaze"),
    ("charcoal", "deep charcoal matte glaze"),
    ("sage", "muted sage green glaze"),
    ("terracotta", "warm terracotta clay glaze"),
    ("cream", "off-white cream glaze with subtle speckle"),
]

TEMPLATE = (
    "Product packshot: matte ceramic coffee mug, {color_desc}, "
    "centered single subject filling about 60% of frame, "
    "seamless white cyclorama background, soft diffused studio lighting from the upper left, "
    "subtle contact shadow underneath, shot on 50mm, ecommerce hero, no props, "
    "clean negative space top and bottom"
)

rows = [{"sku": f"mug-{c}-01", "prompt": TEMPLATE.format(color_desc=desc),
         "aspect_ratio": "1:1"} for c, desc in COLORS]

Пять вариантов по $0.005 = $0.025 за весь селектор цвета. Загвоздка: schnell не сохраняет форму идеально от рендера к рендеру. Толщина ручки, кривая ободка, пропорции слегка дрейфуют между цветами. Для стилизованной страницы товара это нормально. Для попиксельно согласованных вариантов нужна обусловленность по референсному изображению, а значит flux-1.1-pro с референсным изображением или nano-banana-pro, а не schnell.

Подключение к витрине вашего магазина

На выходе получается скачанный JPG-файл. Путь оттуда до публикации на странице товара зависит от вашей платформы:

  • Shopify: POST /admin/api/2025-01/products/{id}/images.json с телом {"image": {"attachment": "<base64>"}}. Возвращает CDN-URL, размещённый Shopify.
  • WooCommerce: загрузка через медиатеку WP (POST /wp-json/wp/v2/media), затем PATCH товара с возвращённым media ID как images: [{id: ...}].
  • Headless / собственная CMS: загрузка в ваше собственное объектное хранилище (S3, R2, Cloudflare Images) и ссылка на сгенерированный URL в записи товара.

В любом случае загружайте на сервере, а не на клиенте, чтобы ваш ключ hiapi никогда не попадал в браузер.

Расчёт затрат для планирования

При $0.005 за изображение бюджет редко бывает ограничением — но полезно мыслить пакетами:

Пакет Кол-во изображений Стоимость
Один SKU, 4 изображения 4 $0.02
Обновление 50 SKU, по 4 изображения каждому 200 $1.00
Обновление каталога из 200 SKU 800 $4.00
Ежедневное тестирование вариантов, 100 изображений в день, 30 дней 3,000 $15.00

На hiapi стоимость токенов на стороне эндпоинта изображений (промпты) бесплатна — вы платите только за выходные изображения.

Что flux-schnell делает плохо

То, что нужно планировать до вложения средств:

  • Читаемый текст на этикетках. Если на вашем изображении товара должен быть чётко читаемым брендовый логотип, сначала сгенерируйте базовое изображение с помощью schnell, а затем наложите реальный PNG этикетки в графическом редакторе. Требование к schnell отрисовать «кружку с надписью 'OAK ROAST'» примерно в 80% случаев даст абракадабру.
  • Товар в руке. Анатомия человека — слабое место schnell. Для сценических изображений с людьми используйте nano-banana-pro или flux-1.1-pro.
  • Попиксельно идентичный товар между вариантами. В этом случае используйте модели, поддерживающие референсные изображения.
  • Субмиллиметровые детали (ювелирные изделия, часы с видимыми стрелками, травленый металл). Это область продвинутых моделей.

Для всего остального на странице товара — фон, освещение, цветовые варианты, ситуативные изображения, атмосфера — flux-schnell является правильным инструментом, по правильной цене, с правильным временем оборота. Весь цикл укладывается в скрипт while true: poll; download и CSV с SKU, а стоимость достаточно низка, чтобы вы могли итеративно улучшать промпты без совещания по бюджету.

Часто задаваемые вопросы

Вопрос: Могу ли я отправить референсное изображение в flux-schnell? Ответ: Нет. flux-schnell/text-to-image поддерживает только генерацию из текста — поле input принимает только prompt и aspect_ratio, и всё. Для вариантов с обусловленностью по референсу используйте flux-1.1-pro или nano-banana-pro, которые на hiapi принимают изображения на вход.

Вопрос: Какие соотношения сторон поддерживаются? Ответ: 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9 и auto. Любое другое соотношение (например, 5:7, 2:1) будет отклонено при создании задачи с ошибкой, указывающей на поддерживаемый набор.

Вопрос: Почему создание задачи возвращает 400, когда я включаю resolution? Ответ: input для flux-schnell принимает только aspect_ratio. Другие модели изображений на hiapi (например, flux-2, nano-banana-pro) принимают resolution (1K/2K/4K). Для schnell уберите его.

Вопрос: Как долго действителен URL результата? Ответ: Каждый output[].url имеет метку времени expireAt (обычно несколько десятков минут). Как только status становится success, сразу скачивайте байты изображения и сохраняйте в собственное хранилище — не ставьте горячую ссылку на временный URL в своей базе товаров.

Вопрос: Могу ли я запускать более 8 параллельных задач? Ответ: Да, но на практике быстрее не завершится — schnell и так быстр от начала до конца, и больше примерно 8 параллельных задач только углубляет очередь. Для действительно больших пакетов (тысячи) следует распараллеливать на нескольких рабочих машинах, а не использовать потоки в одном процессе.

Вопрос: Как получить попиксельно согласованные варианты одного товара? Ответ: Только с помощью schnell это невозможно. Сгенерируйте главное изображение один раз, затем запустите варианты с использованием модели, поддерживающей референсные изображения (flux-1.1-pro или nano-banana-pro), взяв главное изображение в качестве референса. Стоимость возрастёт, но согласованность формы значительно улучшится.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API