Картинка не пришла: отказ по содержанию и что с ним делать
Что значит ответ без картинки: отказ по правилам содержания или текст вместо картинки. Как он выглядит в ответе API, что означают коды failure и как переписать безобидный промпт. Деньги за такой запрос возвращаются на баланс.
Редакция RendergridО редакции
Коротко
Картинки нет, когда модель отклонила запрос по правилам содержания или ответила текстом вместо картинки. В API это не HTTP-ошибка: запрос принят с кодом 202, а потом задание завершается со статусом failed и объектом failure. Тип declined значит, что причина в самом запросе: тот же запрос даст тот же результат, поэтому измените промпт или исходную картинку и отправьте новый запрос с новым ключом повтора. Неудачный запрос бесплатен: сумма сразу возвращается на баланс.
Почему вместо картинки приходит отказ?
Модель может отклонить промпт или исходную картинку по правилам содержания: тогда задание завершается как failed, а деньги возвращаются. Бывает и иначе: модель отвечает текстом вместо картинки, например описывает её словами или получает промпт, который ссылается на не приложенную картинку.
API называет оба случая отказом (declined): причина в самом запросе, а не в сервисе. В статистике личного кабинета отказы считаются отдельно от ошибок и подписаны причиной, например «Отказ по правилам содержания» или «Модель ответила без картинки».
Как отказ выглядит в ответе API?
Сначала запрос принимается: POST /images/generate отвечает 202, а сумма списывается сразу и приходит в поле cost. Отказ приходит позже: GET /creations/{id} отвечает 200, но со статусом failed. Это итог задания, а не ошибка запроса статуса.
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "queued",
"task_id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"cost": 0.02
}
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "failed",
"error": "The image or prompt was rejected by the safety filter. Try a different image or rephrase the prompt.",
"failure": {
"type": "declined",
"code": "content_policy",
"retryable": false
}
}
Объект failure есть только у failed, поэтому при разборе считайте его необязательным. Строка error — текст для людей на английском, и формулировка может меняться: логику стройте по failure.type и failure.code.
Список кодов пока закрыт, но новые могут появиться: незнакомый код обрабатывайте по его failure.type.
Тип declined — причина в самом запросе, повтор без изменений не поможет:
content_policy— правила содержания отклонили промпт или образец: измените промпт или возьмите другую картинку.no_image_output— модель ответила текстом вместо картинки: опишите нужную картинку или приложите фото, на которое ссылается промпт.source_image_rejected— исходная картинка отклонена: возьмите другое фото.reference_unavailableиinvalid_request— образец недоступен или запрос нельзя выполнить в таком виде: загрузите файл заново или исправьте запрос.
Тип error — сбой на стороне сервиса (timeout, unavailable, reference_fetch_failed, internal): такой запрос можно отправить снова, если retryable не равен false. Полный список — в документации.
Так разобрать ответ в коде:
curl https://api.rendergrid.io/ api/ public/ v1/ creations/ 5b0214ae-9e39-460a-820a-f6ae3e24400b \ -H "Authorization: Bearer $RENDERGRID_API_KEY"
import os import requests API = "https://api.rendergrid.io/ api/ public/ v1" creation_id = "5b0214ae-9e39-460a-820a-f6ae3e24400b" response = requests.get( f"{API}/creations/{creation_id}", headers={"Authorization": f"Bearer {os.environ['RENDERGRID_API_KEY']}"}, timeout=(5, 20), ) response.raise_for_status() creation = response.json() if creation["status"] == "failed": # объект failure считайте необязательным failure = creation.get("failure") or {} if failure.get("type") == "declined": # причина в запросе: меняйте промпт или исходную картинку print("declined:", failure.get("code")) elif failure.get("retryable") is not False: # сбой сервиса: отправьте новый запрос с новым ключом повтора print("error:", failure.get("code"))
// Node.js 22+, файл .mjs const API = "https://api.rendergrid.io/ api/ public/ v1"; const id = "5b0214ae-9e39-460a-820a-f6ae3e24400b"; const response = await fetch(`${API}/creations/${id}`, { headers: { Authorization: `Bearer ${process.env.RENDERGRID_API_KEY}` }, signal: AbortSignal.timeout(20_000), }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const creation = await response.json(); if (creation.status === "failed") { // объект failure считайте необязательным const failure = creation.failure ?? {}; if (failure.type === "declined") { // причина в запросе: меняйте промпт или исходную картинку console.log("declined:", failure.code); } else if (failure.retryable !== false) { // сбой сервиса: отправьте новый запрос с новым ключом повтора console.log("error:", failure.code); } }
Вернутся ли деньги за отказ?
Да. Сумма списывается при приёме запроса, а если картинки нет, сразу возвращается на баланс: так и при отказе, и при сбое сервиса. Ответ об ошибке возврат не подтверждает, поэтому проверьте баланс и журнал операций в кабинете. Отказы в долю успешных запросов не входят и показаны в статистике отдельно. Подробнее — в статье «Неудачный запрос бесплатен: как устроена оплата за картинку».
Как переписать промпт, который поняли не так?
Если вы уверены, что запрос безобидный, меняйте его текст: тот же запрос даст тот же результат. Новая попытка — это новый запрос с новым X-Idempotency-Key: прежний ключ задание не перезапустит. Она оплачивается как обычно и возвращается, если не удалась.
- Опишите сам кадр. Назовите предмет, его число, фон, свет и положение в кадре вместо отсылок вроде «как на прошлой картинке»: промпт, который ссылается на не приложенную картинку, может закончиться ответом без картинки (
no_image_output). - Приложите то, на что ссылаетесь. Если правите фото, передайте его образцом и всё равно опишите правку в промпте: промпт нужен всегда.
Три промпта ниже показывают такое описание: каждый называет предмет и его число, фон, свет, кадрирование и то, чего на картинке быть не должно. Это обычные безобидные запросы к Nano Banana 2.1, и на каждый пришла картинка с первой попытки. Отказов у них не было, и мы не проверяли, как фильтр отнесётся к другим формулировкам.
Промпт к картинке
Три апельсина в простой белой керамической миске на светлом столе. Один апельсин чуть выше двух других. Спокойный нейтральный фон, мягкий дневной свет слева, видна фактура кожуры. Миска целиком по центру, без дополнительных предметов, края кадра свободны. Без надписей, логотипов, людей и водяных знаков.
Nano Banana 2.1
nano-banana-2.1 · 1K · 1:1 · $0,02
Nano Banana 2.1, 1K, 1:1, одна попытка. Миска стоит по центру целиком, края кадра свободны, на кожуре видна фактура. Верхний апельсин лежит на двух нижних. Между нижними плодами виден ещё фрагмент кожуры, поэтому не исключено, что плодов четыре, а не три, как в промпте. Мягкая тень от миски лежит слева, хотя промпт просил свет слева. Надписей, логотипов и людей нет.
Промпт к картинке
Три ромашки в небольшой прозрачной стеклянной вазе на кремовом фоне. Стебли видны через воду, лепестки не сливаются друг с другом. Мягкий рассеянный свет, лёгкая тень справа. Ваза и все цветки полностью в квадратном кадре, вокруг достаточно воздуха. Без надписей, логотипов, людей и водяных знаков.
Nano Banana 2.1
nano-banana-2.1 · 1K · 1:1 · $0,02
Nano Banana 2.1, 1K, 1:1, одна попытка. Три цветка расходятся веером и целиком помещаются в кадр, лепестки соседних цветков не сливаются. Стебли видны сквозь воду и пересекаются внутри сосуда. Сосуд больше похож на банку, чем на вазу. Свет мягкий и рассеянный, слабая тень лежит справа от сосуда. Надписей, логотипов и людей нет.
Промпт к картинке
Две закрытые книги в однотонных тканевых переплётах лежат стопкой на светло-сером фоне, рядом деревянный шар. На обложках и корешках нет текста. Вид немного сверху, мягкий свет, различимы ткань и древесные волокна. Все предметы в центре, не обрезайте края. Без надписей, логотипов, людей и водяных знаков.
Nano Banana 2.1
nano-banana-2.1 · 1K · 1:1 · $0,02
Nano Banana 2.1, 1K, 1:1, одна попытка. Вид немного сверху: видны фактура ткани, светлые торцы страниц и волокна дерева на шаре. Книги и шар целиком в кадре, края ничем не обрезаны. Шар лежит справа от стопки, ниже её середины. Текста на обложках и корешках нет. Заметных дефектов не нашли.
Когда переписывание не поможет?
- Это не обход правил. Если запрос им не соответствует, мы не обещаем, что следующая попытка пройдёт, и не объясняем, как правила обойти.
- Три картинки — не проверка. По одной попытке на промпт: это форма промпта, а не доля принятых запросов.
- Причина не в тексте.
source_image_rejectedиreference_unavailableрешаются заменой или повторной загрузкой файла, а не переписыванием промпта. - Сбой сервиса — не отказ. Тип
errorне требует менять промпт: отправьте запрос снова, еслиretryableне равенfalse.
Неудачный запрос бесплатен
Запустите переписанный промпт
В песочнице модели промпт, форму кадра и разрешение задают без кода. Если запрос отклонят, сумма вернётся на баланс.
Попробовать модельВопросы и ответы
Что делать, если API не вернул картинку?
GET /creations/{id}. Если статус failed, прочитайте failure.type и failure.code: при declined измените промпт или исходную картинку, при error отправьте запрос снова, если retryable не равен false.Платят ли за картинку, которую модель отклонила?
Можно ли отправить тот же запрос ещё раз?
Приходит ли отказ как HTTP-ошибка?
ERR_CONTENT_POLICY зарезервирован: отказ по правилам содержания приходит как задание failed с failure.code: content_policy.Источники
- Документация Rendergrid: коды ошибокТипы
declinedиerror, коды причин и возврат суммы. - Документация Rendergrid: задачи и статусыСтатус
failedи как читать ответ о задании. - Документация Rendergrid: создание картинкиСписание суммы при приёме запроса и поле
cost. - Неудачный запрос бесплатен: как устроена оплата за картинкуВозврат суммы за запрос без картинки.
- Три картинки статьиNano Banana 2.1, 1K, формат 1:1, одна попытка на каждую; промпт стоит у картинки.





