Fellowi

API генерации откровенных изображений для разработчиков

Автор: Команда Fellowi · · 7 мин чтения

Тёмная градиентная композиция от фиолетового к индиго, символизирующая API для генерации изображений.

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

Всё остальное - обычный REST API: ключ, POST, который ставит задачу в очередь, опрос, скачивание. Если вы работали с любым другим асинхронным API генерации, это покажется знакомым.

Получите ключ

Зарегистрируйтесь, затем создайте API-ключ на странице API Console. Ключ выглядит как fk_live_<случайная строка> и показывается полностью только один раз, при создании. После этого на нашей стороне хранится только хеш и короткий превью - если вы его потеряете, отзовите и создайте новый, как с любым другим API-ключом, с которым вы работали раньше. Сохраните его в надёжном месте до того, как закроете вкладку.

Каждый запрос авторизуется стандартным bearer-заголовком:

Authorization: Bearer fk_live_your_key_here

Поставьте генерацию в очередь

POST /v1/api/images с промптом и вашими параметрами. Запрос возвращается сразу с кодом HTTP 202 - он не блокируется на время рендера:

POST /v1/api/images
Content-Type: application/json
Authorization: Bearer fk_live_your_key_here
Idempotency-Key: a-key-you-generate-per-attempt

{
  "prompt": "a neon-lit rooftop at night, wide shot, cinematic lighting",
  "quality": "standard",
  "format": "png",
  "aspectRatio": "16:9"
}

В ответе - id задачи, оценка времени etaMs и остаток монет на вашем счёте после списания. Необязательный заголовок Idempotency-Key делает повторный запрос безопасным - отправьте тот же ключ при повторе, и повторного списания за ту же попытку не произойдёт.

Сама задача лежит внутри image, а рядом с ней - баланс кошелька:

{
  "image": { "id": "0f9c...", "status": "queued", "etaMs": 42000, "coinsCharged": 40 },
  "coins": 360
}

Опрос, затем скачивание

Опрашивайте GET /v1/api/images/:id, пока status не станет "succeeded" или "failed". При успехе скачайте сами байты через GET /v1/api/images/:id/content. Если генерация не удалась, потраченные монеты автоматически возвращаются, а failureCode всегда равен одному из ровно четырёх значений: TIMEOUT, MODERATION_REJECTED, VENDOR_ERROR или UNKNOWN. Пятого кода обрабатывать не нужно, и частичного списания сверять тоже не нужно - подробнее о том, почему именно так, в статье о ценообразовании API и о том, что происходит при сбое генерации.

curl, от начала до конца

API_KEY="fk_live_your_key_here"

# 1. поставить задачу в очередь
JOB=$(curl -s https://fellowi.com/api/v1/api/images \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"a neon-lit rooftop at night","quality":"standard","format":"png","aspectRatio":"16:9"}')
ID=$(echo "$JOB" | jq -r .image.id)

# 2. опрашивать до завершения
while true; do
  STATUS=$(curl -s https://fellowi.com/api/v1/api/images/$ID \
    -H "Authorization: Bearer $API_KEY" | jq -r .image.status)
  [ "$STATUS" = "succeeded" ] && break
  [ "$STATUS" = "failed" ] && { echo "generation failed"; exit 1; }
  sleep 3
done

# 3. скачать изображение
curl -s https://fellowi.com/api/v1/api/images/$ID/content \
  -H "Authorization: Bearer $API_KEY" -o output.png

Node

const API_KEY = process.env.FELLOWI_API_KEY;
const base = "https://fellowi.com/api/v1/api";
const headers = { Authorization: `Bearer ${API_KEY}` };

const create = await fetch(`${base}/images`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ prompt: "a neon-lit rooftop at night", quality: "standard", format: "png", aspectRatio: "16:9" }),
});
const { image } = await create.json();
const id = image.id;

let job;
do {
  await new Promise((r) => setTimeout(r, 3000));
  job = await fetch(`${base}/images/${id}`, { headers }).then((r) => r.json());
} while (job.image.status !== "succeeded" && job.image.status !== "failed");

if (job.image.status === "failed") throw new Error(job.image.failureCode);

const bytes = await fetch(`${base}/images/${id}/content`, { headers }).then((r) => r.arrayBuffer());
await Bun.write("output.png", bytes);

Python

import os, time, requests

API_KEY = os.environ["FELLOWI_API_KEY"]
base = "https://fellowi.com/api/v1/api"
headers = {"Authorization": f"Bearer {API_KEY}"}

job = requests.post(f"{base}/images", headers=headers, json={
    "prompt": "a neon-lit rooftop at night",
    "quality": "standard",
    "format": "png",
    "aspectRatio": "16:9",
}).json()

while True:
    time.sleep(3)
    status = requests.get(f"{base}/images/{job['image']['id']}", headers=headers).json()
    if status["image"]["status"] in ("succeeded", "failed"):
        break

if status["image"]["status"] == "failed":
    raise RuntimeError(status["image"]["failureCode"])

content = requests.get(f"{base}/images/{job['image']['id']}/content", headers=headers)
open("output.png", "wb").write(content.content)

Модель, цена и лимиты

Каждый ответ указывает модель как fellowi-nsfw-image-1. Это единственное название, которое вы увидите, - это тот же генератор, что стоит за веб-приложением Fellowi Images, и списания идут с того же кошелька Fellowi Coins по той же цене: 40 монет за Standard (1,5K), 60 - за High quality (2K). Отдельного прайс-листа для API, который нужно было бы сверять с веб-приложением, не существует.

Лимиты запросов - это защита от злоупотреблений, а не реальный потолок: по умолчанию 20 запросов в минуту на генерацию, 120 в минуту на чтение. GET /v1/api/me возвращает текущий баланс монет, лимит вашего ключа и сколько изображений у вас осталось на сегодня по дневному ограничению - проверяйте его перед постановкой пакета задач, а не после того, как упрётесь в предел.

Полная документация, актуальные цены и управление ключами - всё на странице API Console.

Попробуйте сами

Тёплый приватный ии-компаньон: 7 дней бесплатно и 30 сообщений, без карты.

Цены и лимиты

Читать дальше