Tutoriel
Optimisation des coûts de l'API Seedream : comment réduire le coût de génération d'images sur hiapi
Seedream est proposé sur hiapi en quatre niveaux distincts — seedream-5.0-flash, seedream-5.0-lite, seedream-5.0-pro et l'ancien seedream-4.5 — et chacun est facturé différemment. Choisir le mauvais niveau ou la mauvaise résolution peut vous coûter 2 à 4 fois plus cher par image sans aucune amélioration visible de la qualité. Ce guide présente la structure tarifaire réelle de chaque niveau et fournit un modèle de code exécutable pour appeler le modèle le moins coûteux qui réponde à vos exigences.
Ce que vous allez construire, et les prérequis
Vous allez construire un petit client Python qui crée des tâches d'image Seedream via l'API de tâches unifiée de hiapi, attend le résultat, et choisit délibérément une combinaison résolution/modèle au lieu de copier-coller les valeurs par défaut des tutoriels. D'abord, récupérez une clé API depuis votre console hiapi — chaque requête ci-dessous l'envoie sous la forme Authorization: Bearer sk-....
La structure tarifaire que vous allez optimiser
Tarifs actuels par image (vérifiez toujours la page de tarification en temps réel avant la mise en production, car les tarifs changent) :
seedream-5.0-flash—— forfait de 0,025 $/image, même prix pour la génération texte-vers-image et image-vers-image. Le niveau le moins cher de la plateforme ; idéal pour les brouillons, les vignettes et tout ce que vous régénérez plusieurs fois avant de choisir le résultat final.seedream-5.0-lite—— forfait de 0,035 $/image, et surtout, le prix est identique que vous rendiez en2Kou en4K. À ce niveau, il n'y a jamais de raison de demander du2Kd'un point de vue coût — le4Kest une mise à niveau gratuite.seedream-4.5(ancien) —— forfait de 0,045 $/image sur les deux points de terminaison.seedream-5.0-pro—— tarification par paliers de résolution plutôt que forfaitaire : texte-vers-image à 0,05 $ en1K, 0,10 $ en2K; image-vers-image à 0,06 $ en1K, 0,10 $ en2K. À ce niveau, la résolution est là où votre budget part réellement — un brouillon en1Kcoûte environ la moitié d'un rendu final en2K.
Cette asymétrie est tout l'intérêt de l'optimisation : lite récompense les requêtes à résolution plus élevée (gratuit), pro pénalise les résolutions plus élevées (coût environ doublé). Traitez-les différemment dans votre code d'appel, au lieu de coder en dur la même résolution partout.
Exemple minimal exécutable
Chaque appel Seedream passe par le même point de terminaison asynchrone de tâche : créez avec POST /v1/tasks, puis interrogez GET /v1/tasks/{taskId} ou recevez un rappel webhook. Les identifiants de modèle sont bruts — sans préfixe models/ ni préfixe de fournisseur.
import os
import time
import requests
API_KEY = os.environ["HIAPI_API_KEY"] # starts with sk-
BASE_URL = "https://api.hiapi.ai/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(model: str, input_payload: dict) -> str:
resp = requests.post(f"{BASE_URL}/tasks", headers=HEADERS,
json={"model": model, "input": input_payload}, timeout=30)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_task(task_id: str, interval: float = 3.0, timeout: float = 180.0) -> dict:
deadline = time.time() + timeout
while time.time() < deadline:
resp = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
data = resp.json()["data"]
if data["status"] == "success":
return data
if data["status"] == "fail":
raise RuntimeError(data["error"])
time.sleep(interval)
raise TimeoutError(f"task {task_id} did not finish within {timeout}s")
# seedream-5.0-lite: 4K costs the same $0.035 as 2K, so always ask for 4K here.
task_id = create_task(
"seedream-5.0-lite/text-to-image",
{"prompt": "a minimalist product photo of a ceramic mug on a wooden table", "resolution": "4K"},
)
result = wait_task(task_id)
image_url = result["output"][0]["url"]
print(image_url)
Sur seedream-5.0-lite, resolution n'accepte que 2K ou 4K (pas de 1K). seedream-5.0-pro accepte 1K/2K et exige en plus aspect_ratio (l'une des valeurs 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9) — le schéma d'entrée de chaque niveau Seedream diffère légèrement, donc ne partez pas du principe qu'un champ accepté par un modèle s'applique à un autre.
Modèle de production
Choisissez le niveau par programmation, pas par habitude. Maintenez une petite table de coûts à côté du point d'appel, routez selon les besoins de budget/qualité au lieu de coder en dur le même modèle partout — traitez les chiffres comme un cache de la page de tarification, pas comme la source de vérité :
SEEDREAM_COST_USD = {
("seedream-5.0-flash", None): 0.025,
("seedream-5.0-lite", "2K"): 0.035,
("seedream-5.0-lite", "4K"): 0.035, # same price — always prefer 4K
("seedream-5.0-pro", "1K"): 0.05, # text-to-image; i2i 1K is $0.06
("seedream-5.0-pro", "2K"): 0.10,
}
def pick_model_for_draft_vs_final(is_final: bool) -> tuple[str, dict]:
if not is_final:
return "seedream-5.0-flash", {} # $0.025, iterate freely
return "seedream-5.0-pro", {"resolution": "2K"} # $0.10, one shot at the end
Privilégiez les rappels au polling serré. Dans les pipelines à haut débit, au lieu d'appeler wait_task en boucle toutes les quelques secondes, ajoutez callback à la requête de création :
task_id_resp = requests.post(
f"{BASE_URL}/tasks", headers=HEADERS,
json={
"model": "seedream-5.0-lite/text-to-image",
"input": {"prompt": "...", "resolution": "4K"},
"callback": {"url": "https://yourapp.example.com/webhooks/hiapi", "when": "final"},
},
timeout=30,
)
Lorsque la tâche atteint un état terminal (success ou fail), votre gestionnaire de webhook reçoit un POST, au lieu de laisser votre worker consommer des requêtes dans une boucle de polling. Si vous ne pouvez pas exposer de point de terminaison HTTPS public (développement local, outils internes), le polling reste le choix le plus simple — passez aux rappels dès que vous tournez à une échelle réelle.
Dédupliquez avant de créer la tâche, pas après. L'API de tâches facture à la création, donc une requête réessayée (timeout, crash du worker, redéploiement d'un consommateur de file) qui soumet à nouveau la même tâche est facturée deux fois. Avant d'appeler create_task, vérifiez dans votre propre stockage s'il existe déjà une tâche existante indexée par (model, input_hash), et si cette tâche est déjà en cours d'exécution ou a réussi, ignorez la création — le point de terminaison de tâche hiapi n'a pas de déduplication intégrée, donc cela doit être fait dans votre code.
Gérez explicitement les échecs d'authentification. Une clé invalide ou révoquée renvoie un HTTP 401 avec un corps de réponse structuré, et non une page d'erreur générique :
{"error": {"code": "permission_denied", "type": "hiapi_error", "request_id": "..."}}
Vérifiez spécifiquement error.code == "permission_denied", afin qu'une mauvaise clé échoue rapidement au lieu de réessayer jusqu'au timeout.
Ressources hiapi associées
- Tarification —— tarifs actuels de chaque modèle ; considérez tout chiffre dans cet article comme un instantané, pas comme une garantie.
- Console des clés API —— création et rotation des clés.
- Pages modèle Seedream 5.0 Lite — texte-vers-image et image-vers-image.
- Pages modèle Seedream 5.0 Pro — texte-vers-image et image-vers-image.
- Page modèle Seedream 5.0 Flash.
- Référence de l'API de tâches asynchrones —— contrat complet de création/polling/rappel.
- Documentation d'authentification —— format de clé et exigences d'en-tête.
Questions fréquentes
Quel modèle Seedream est le moins cher pour des brouillons rapides ou des icônes ?
seedream-5.0-flash, forfait de 0,025 $/image — le niveau le moins cher de la plateforme, même prix pour texte-vers-image et image-vers-image.
Demander du 4K plutôt que du 2K sur Seedream 5.0 Lite coûte-t-il plus cher ?
Non. seedream-5.0-lite est à forfait de 0,035 $/image, que resolution vaille 2K ou 4K, donc à ce niveau, demandez 4K par défaut.
Combien coûte Seedream 5.0 Pro par image ?
Tarification par paliers de résolution : texte-vers-image à 0,05 $ en 1K, 0,10 $ en 2K ; image-vers-image à 0,06 $ en 1K, 0,10 $ en 2K. Contrairement à lite, la résolution change réellement votre facture ici.
Si ma tâche est réessayée, comment éviter d'être facturé deux fois ?
L'API de tâches n'a pas de clé d'idempotence côté serveur, donc dédupliquez côté client : stockez une clé pour (model, input_hash) avant d'appeler create_task, et si cette clé est déjà en cours d'exécution ou a réussi, ignorez la création.
Dois-je utiliser le polling ou un rappel webhook ?
Si vous ne pouvez pas exposer de point de terminaison HTTPS public (développement local, scripts), interrogez GET /v1/tasks/{taskId}. Dès que vous tournez à une échelle réelle, passez à callback.url + when: "final" — cela remplace la boucle de polling par une notification push par tâche.
Que renvoie une clé API invalide ?
HTTP 401 et {"error": {"code": "permission_denied", "type": "hiapi_error", "request_id": "..."}}. Vérifiez explicitement ce code d'erreur au lieu de réessayer avec une mauvaise clé jusqu'au timeout.
Puis-je utiliser ces tarifs sans clé API au préalable ?
Non — chaque appel /v1/tasks nécessite un en-tête Authorization: Bearer sk-... valide avec une vraie clé créée dans votre console ; la génération en production n'a pas de voie sans clé ni d'essai sans inscription.
Articles similaires
Voir tous les articles →-
Tutoriel
Comment appeler hailuo-2.3-fast/image-to-video via l'API HiAPI : curl et Python en pratique
La première requête exploitable du palier image-vers-vidéo rapide et économique — de l'ID du modèle au téléchargement du MP4
-
Tutoriel
Comment appeler hailuo-2.3/text-to-video via l'API HiAPI : curl, Python et exemples de requêtes exécutables
-
Tutoriel
Utiliser Kandinsky 6.0 Pro texte-vers-vidéo sur HiAPI : tutoriel curl et Python
Démonstration pratique axée sur la requête : construire l'appel du prompt au clip vidéo, soumettre la requête, interroger l'état d'achèvement et télécharger le résultat