Fellowi

Une API de génération d'images NSFW pour les développeurs

Par L'équipe Fellowi · · 7 min de lecture

Composition en dégradé violet foncé vers indigo représentant une API de génération d'images pour développeurs.

La plupart des API de génération d'images refusent le contenu NSFW par principe, avant même d'atteindre une limite technique quelconque. C'est un choix raisonnable pour une plateforme généraliste, mais cela ne laisse presque rien pour un développeur qui a réellement besoin d'un accès programmatique à un générateur autorisant le contenu adulte. L'API publique de Fellowi existe pour ce cas précis. Elle autorise la génération explicite pour les comptes adultes inscrits, sous des limites strictes qui ne bougent jamais : aucun contenu impliquant des mineurs, aucun contenu représentant une absence de consentement. Ce ne sont pas des réglages qu'on peut basculer - ces demandes sont refusées, sans exception.

En dehors de cela, c'est une API REST classique : une clé, un POST qui met une tâche en file d'attente, un polling, un téléchargement. Si vous avez déjà utilisé une autre API de génération asynchrone, cela vous paraîtra familier.

Obtenir une clé

Créez un compte, puis créez une clé API sur l'API Console. La clé ressemble à fk_live_<chaîne aléatoire> et vous est montrée en entier une seule fois, à sa création. Ensuite, seuls un hash et un court aperçu sont conservés de notre côté - si vous la perdez, révoquez-la et créez-en une nouvelle, comme pour n'importe quelle autre clé API que vous avez déjà manipulée. Sauvegardez-la quelque part de fiable avant de fermer l'onglet.

Chaque requête s'authentifie avec un en-tête bearer standard :

Authorization: Bearer fk_live_your_key_here

Mettre une génération en file d'attente

POST /v1/api/images avec un prompt et vos options. L'appel renvoie immédiatement un HTTP 202 - il ne bloque pas pendant le rendu :

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"
}

La réponse contient un id de tâche, une estimation etaMs, et votre solde de coins restant après le débit. L'en-tête optionnel Idempotency-Key rend une nouvelle tentative sûre - envoyez la même clé lors d'une relance, et vous ne serez pas débité deux fois pour la même tentative.

La tâche elle-même se trouve sous image, avec le solde de votre portefeuille à côté :

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

Polling, puis téléchargement

Interrogez GET /v1/api/images/:id jusqu'à ce que status passe à "succeeded" ou "failed". En cas de succès, récupérez les octets réels via GET /v1/api/images/:id/content. En cas d'échec, les coins dépensés sont remboursés automatiquement, et failureCode vaut toujours l'une de ces quatre valeurs exactement : TIMEOUT, MODERATION_REJECTED, VENDOR_ERROR, ou UNKNOWN. Il n'y a pas de cinquième code à gérer, ni de débit partiel à réconcilier - nous expliquons pourquoi plus en détail dans notre article sur la tarification de l'API et la gestion des échecs.

curl, de bout en bout

API_KEY="fk_live_your_key_here"

# 1. mettre une tâche en file d'attente
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. interroger jusqu'à la fin
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. télécharger l'image
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)

Modèle, tarifs et limites

Chaque réponse indique le modèle comme fellowi-nsfw-image-1. C'est le seul nom que vous verrez - c'est le même générateur que celui derrière l'application web Fellowi Images, et il est facturé sur le même portefeuille Fellowi Coins, au même prix : 40 coins pour Standard (1,5K), 60 pour la haute qualité (2K). Il n'existe pas de grille tarifaire séparée pour l'API à réconcilier avec l'application web.

Les limites de débit sont une protection contre les abus, pas le vrai plafond : par défaut, 20 requêtes par minute pour les générations, 120 par minute pour les lectures. GET /v1/api/me renvoie votre solde de coins actuel, la limite de votre clé, et combien d'images il vous reste aujourd'hui sous le plafond quotidien - vérifiez-le avant de lancer un lot, pas après avoir buté sur un mur.

La documentation complète, les tarifs en direct et la gestion des clés se trouvent sur l'API Console.

Essayez par vous-même

Une compagne IA chaleureuse et privée : 7 jours gratuits et 30 messages, sans carte.

Tarifs et limites

Continuer la lecture