HiAPI
Блог

Руководство

Как использовать ideogram-v4.5 через HiAPI API: curl, Python и работающий запрос

Oct 31, 2026
封面图:浅灰蓝底上多层半透明玻璃片交叠,折射出克制的蓝色条带,安静而具建筑感。

Что даёт вам ideogram-v4.5 на HiAPI

Когда текст на изображении действительно важен, ideogram-v4.5 — та модель, которую стоит выбрать. Макеты постеров, графические знаки, рендеры упаковки, карточки для соцсетей — любой сценарий, где одна опечатка в заголовке или размытая подпись испортит материал, — именно в этом ценность этой модели. Если же вы генерируете абстрактные текстуры или фотографические пейзажи, где ничего не нужно читать, универсальные модели изображений обычно дешевле и быстрее.

Это статья-интеграционное руководство, а не обзор модели. Прочитав её, вы получите работающий запрос, Python-клиент, выполняющий то же самое, и переиспользуемую вспомогательную функцию, которая берёт на себя то, на чём обычно спотыкаются: параметры соотношения сторон, опрос асинхронных задач и получение результата.

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

Прежде чем отправить запрос

Перед первым вызовом нужно подготовить четыре вещи.

1. API-ключ

Создайте его в консоли вашего аккаунта HiAPI и держите подальше от системы контроля версий. Экспортируйте его как переменную окружения, а не вставляйте в скрипт:

export HIAPI_API_KEY="your_key_here"

2. Базовый URL

Все запросы отправляются на базовый URL HiAPI API с добавлением конкретного пути эндпоинта генерации. Документация платформы перечисляет текущие пути; если документация говорит иное, не хардкодьте путь, который вы увидели в статье в блоге (включая эту).

3. Идентификатор модели

Строка модели, которую вы передаёте в теле запроса, идентифицирует ideogram-v4.5. Используйте точный регистр, указанный в списке моделей платформы — идентификаторы моделей сопоставляются буквально, и малейшее отклонение вернёт ошибку валидации, а не полезную подсказку.

4. Справочник параметров

Страница модели ideogram-v4.5 — авторитетный источник того, какие поля принимает тело запроса: ограничения длины промпта, поддерживаемые соотношения сторон, формат вывода, а также любые параметры seed или стиля. Прочитайте её перед написанием кода. Параметры, не перечисленные там, могут молча игнорироваться или отклоняться, а угадывание значений — самый частый способ потратить время на отладку.

С этими четырьмя вещами можно отправлять первый запрос.

Работающий запрос curl

Ниже минимальный пример отправки. Если в вашем аккаунте другие значения, подставьте путь эндпоинта и идентификатор модели из документации платформы.

curl -X POST "$HIAPI_BASE_URL/<generation-path>" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ideogram-v4.5",
    "input": {
      "prompt": "A vintage travel poster for the Amalfi Coast, bold serif headline reading \"AMALFI\", warm sunset palette, grainy print texture"
    }
  }'

Что делает каждая часть:

  • Authorization — аутентификация по bearer-токену. Отсутствующий или неверно отформатированный заголовок — самая частая причина 401.
  • Content-Type — должен быть application/json. Некоторые HTTP-клиенты не устанавливают его автоматически при POST, что приводит к непонятным ошибкам парсинга на сервере.
  • model — буквальный идентификатор модели. Размещайте его на верхнем уровне тела запроса, как показано в документации.
  • input.prompt — ваша инструкция для генерации. Как показано выше, заключайте в кавычки текст, который хотите видеть отрендеренным на изображении, чтобы модель обрабатывала его как буквальный текст, а не как описание.
  • input.* — все остальные параметры генерации (соотношение сторон, формат, seed и т. д.) принадлежат этому вложенному объекту, рядом с prompt.

Успешная отправка возвращает JSON-объект, содержащий идентификатор задачи и поле статуса. Изображения в этом ответе нет — это ожидаемое поведение. Сохраните идентификатор; он понадобится на шаге опроса.

Тот же вызов на Python

Python-версия — это перевод один к одному. Мы используем requests и разделяем то же тело запроса, чтобы вы могли сравнить их бок о бок.

import os
import json
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
GEN_PATH = "/<generation-path>"  # confirm in platform docs

payload = {
    "model": "ideogram-v4.5",
    "input": {
        "prompt": (
            "A vintage travel poster for the Amalfi Coast, bold serif "
            'headline reading "AMALFI", warm sunset palette, grainy print texture'
        )
    },
}

response = requests.post(
    BASE_URL + GEN_PATH,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    data=json.dumps(payload),
    timeout=30,
)
response.raise_for_status()

job = response.json()
print(job)

Два намеренных решения:

  • json.dumps вместо json= делает формат передачи наглядно идентичным примеру с curl. Работают оба; явная запись облегчает проверку того, что вы фактически отправляете, при отладке.
  • timeout=30 только для отправки. Отправка быстрая, генерация — нет. Никогда не допускайте, чтобы вызов отправки наследовал короткий таймаут, заданный для опроса, иначе вы будете сообщать о нормально работающей задаче как о сбое.

Выведенный словарь job содержит идентификатор задачи и текущий статус. Сохраните идентификатор куда-нибудь — цикл опроса зависит от него.

Управление соотношением сторон и форматом вывода

Соотношение сторон и формат вывода — это параметры тела запроса, а не отдельные эндпоинты. Они находятся в том же объекте input, что и промпт:

{
  "model": "ideogram-v4.5",
  "input": {
    "prompt": "...",
    "aspect_ratio": "<ratio from docs>",
    "output_format": "<format from docs>"
  }
}

Важная здесь дисциплина — не угадывать значения. Каждая модель генерации предоставляет фиксированные перечисления соотношений и форматов, и разные модели принимают разные варианты написания — 16:9 против 16x9, png против PNG и т. д. Передача значения, не поддерживаемого моделью, обычно приводит к ошибке валидации или, что хуже, к молчаливому откату к выводу по умолчанию, что выглядит как баг в вашем промпте.

Итак, рабочий процесс:

  1. Откройте страницу модели ideogram-v4.5 на платформе и дословно скопируйте список поддерживаемых соотношений сторон и форматов вывода.
  2. Поместите эти значения в небольшой белый список в коде, чтобы недопустимый ввод отвергался в месте вызова, а не на стороне API.
  3. По умолчанию используйте соотношение, соответствующее вашей нижестоящей вёрстке. Если изображение должно поместиться в слот социальной карточки 1200×630, выберите значение, близкое к этому соотношению, а не генерируйте квадрат и не обрезайте содержимое.

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

Обработка асинхронных задач и загрузка результатов

Жизненный цикл одной генерации состоит из трёх шагов: отправка → опрос → получение.

Отправка

Этот шаг вы уже освоили в предыдущем разделе. Ответ даёт вам идентификатор задачи и статус, например queued или processing.

Опрос

Опрашивайте эндпоинт статуса задачи с этим идентификатором, пока статус не сообщит о завершении. Две правила делают этот процесс корректным:

  • Спите между опросами. Начните примерно с одной секунды и постепенно увеличивайте задержку. Долбёжка эндпоинта статуса не ускорит задачу и рискует вызвать ограничение частоты запросов.
  • Ограничьте время ожидания. Задайте максимальное число попыток или дедлайн, и по его превышении явно выдавайте ошибку, а не зацикливайтесь бесконечно.
import time

def wait_for_job(job_id, headers, base_url, status_path,
                 max_attempts=60, initial_delay=1.0, factor=1.5):
    delay = initial_delay
    for _ in range(max_attempts):
        r = requests.get(
            f"{base_url}{status_path}/{job_id}",
            headers=headers,
            timeout=30,
        )
        r.raise_for_status()
        data = r.json()
        status = data.get("status")
        if status in ("succeeded", "completed", "success"):
            return data
        if status in ("failed", "error", "cancelled"):
            raise RuntimeError(f"job {job_id} ended with status {status}: {data}")
        time.sleep(delay)
        delay *= factor
    raise TimeoutError(f"job {job_id} did not finish in time")

Сверьтесь с документацией платформы, чтобы узнать точные строки статусов и путь статуса для вашего аккаунта — сопоставляйте по значениям из документации, а любой нераспознанный статус считайте всё ещё выполняющимся, а не успешным.

Получение

Когда задача сообщает о завершении, ответ содержит расположение вывода (обычно URL). Загрузите его обычным GET и запишите байты на диск. URL вывода может быть ограничен по времени, поэтому скачивайте сразу, а не сохраняйте URL на потом. Всё, что нужно знать для написания этого цикла, следует из структуры ответа на отправку — отдельного API «получения изображения» изучать не нужно.

Упаковка в переиспользуемую вспомогательную функцию

Три отдельных скрипта, каждый из которых заново реализует опрос, — это проблема сопровождения. Соберите это один раз.

import os, json, time, requests

class IdeogramClient:
    def __init__(self, base_url, api_key, gen_path, status_path,
                 poll_attempts=60, poll_factor=1.5):
        self.base_url = base_url.rstrip("/")
        self.gen_path = gen_path
        self.status_path = status_path
        self.poll_attempts = poll_attempts
        self.poll_factor = poll_factor
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }

    def generate(self, prompt, **params):
        body = {"model": "ideogram-v4.5", "input": {"prompt": prompt, **params}}
        r = requests.post(self.base_url + self.gen_path,
                          headers=self.headers,
                          data=json.dumps(body), timeout=30)
        r.raise_for_status()
        job = r.json()
        done = self._wait(job["id"])
        url = done["output"]["url"]  # confirm shape in docs
        return self._download(url)

    def _wait(self, job_id):
        delay = 1.0
        for _ in range(self.poll_attempts):
            r = requests.get(f"{self.base_url}{self.status_path}/{job_id}",
                             headers=self.headers, timeout=30)
            r.raise_for_status()
            data = r.json()
            if data.get("status") in ("succeeded", "completed", "success"):
                return data
            if data.get("status") in ("failed", "error", "cancelled"):
                raise RuntimeError(data)
            time.sleep(delay)
            delay *= self.poll_factor
        raise TimeoutError(job_id)

    def _download(self, url):
        r = requests.get(url, timeout=60)
        r.raise_for_status()
        return r.content

Использование — один вызов: img_bytes = IdeogramClient(...).generate("...", aspect_ratio="<from docs>"). Подстройте доступ к done["output"]["url"] и строки статусов под структуру ответа из документации — эти два места, скорее всего, потребуют тонкой настройки под аккаунт.

Частые ошибки и приёмы отладки

Большинство неудач первой недели попадает в пять категорий.

401 / 403 — аутентификация. Ключ отсутствует, содержит пробелы из-за копипаста или у него нет префикса Bearer . Выведите по четыре символа с начала и конца фактически отправляемого ключа; завершающий перевод строки из env-файла — классический виновник.

400 — некорректный JSON или неизвестное поле. Если тело запроса собрано конкатенацией строк, неэкранированные кавычки в промпте ломают JSON. Стройте тело как словарь и сериализуйте через json.dumps. Если JSON парсится, следующий подозреваемый — имя параметра, которое модель не принимает; сверьте ваши ключи со страницей модели посимвольно.

404 / модель не найдена. Обычно это опечатка или неверный регистр идентификатора модели, либо устаревший путь эндпоинта. Копируйте оба из документации платформы, а не по памяти и не из старых руководств.

429 — ограничение частоты. Почти всегда из-за слишком агрессивного опроса. Увеличьте начальную задержку опроса и фактор нарастания. На стороне отправки добавьте повтор с джиттером для ответов 429 и 5xx, но не повторяйте 4xx-ошибки валидации — они будут сбоить одинаково каждый раз.

Задача успешна, но изображение не открывается. Проверьте, что вы скачали байты, а не JSON-страницу ошибки; вызов raise_for_status() на GET-запросе скачивания ловит большинство таких проблем. Также убедитесь, что вы считаете URL скачивания краткосрочным и не кешируете его между сессиями.

Если сомневаетесь, логируйте полное тело ответа и код статуса для каждого вызова в цепочке — отправки, каждого опроса и скачивания. API обычно прямо сообщает, что пошло не так; баг обычно в том, что мы просто не посмотрели.

С работающей отправкой, циклом опроса и разумной обработкой ошибок ideogram-v4.5 можно подключить к реальному пайплайну так же, как любой другой вызов модели HiAPI.

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

Все статьи →

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

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

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