Génère des images par programmation. L'API réutilise tes crédits et les mêmes tarifs que l'app — pas de facturation séparée.
nb_live_… s'affiche une seule fois — copie-la et garde-la secrète.Ne publie jamais ta clé côté navigateur / dépôt public. Traite-la comme un mot de passe. Tu peux la révoquer à tout moment.
Base : https://snyyhebdftcpxzdazgjt.supabase.co/functions/v1
Chaque requête passe l'en-tête : Authorization: Bearer nb_live_xxx
| Méthode | Endpoint | Rôle |
|---|---|---|
| POST | /api-generate | {action:"generate"} → lance une génération |
| POST | /api-generate | {action:"poll"} → état + URL de l'image |
| POST | /api-generate | {action:"credits"} → solde de crédits |
| POST | /api-generate | {action:"models"} → tarifs par modèle |
La génération est asynchrone : generate débite les crédits et renvoie un taskId, puis on interroge poll jusqu'à status:"done".
# 1) lancer
curl -X POST "$BASE/api-generate" \
-H "Authorization: Bearer nb_live_xxx" \
-H "Content-Type: application/json" \
-d '{"action":"generate","model":"standard","prompt":"a cat astronaut, cinematic"}'
# → {"ok":true,"taskId":"abc","charged":4,"credits_left":120}
# 2) interroger
curl -X POST "$BASE/api-generate" \
-H "Authorization: Bearer nb_live_xxx" \
-H "Content-Type: application/json" \
-d '{"action":"poll","taskId":"abc"}'
# → {"ok":true,"status":"done","imageUrl":"https://…"}
const BASE = "https://snyyhebdftcpxzdazgjt.supabase.co/functions/v1";
const KEY = process.env.NANO_KEY; // nb_live_xxx
const H = { "Authorization": `Bearer ${KEY}`, "Content-Type": "application/json" };
async function generate(prompt, model = "standard") {
let r = await fetch(`${BASE}/api-generate`, { method:"POST", headers:H,
body: JSON.stringify({ action:"generate", model, prompt }) });
const { taskId } = await r.json();
for (let i = 0; i < 80; i++) {
await new Promise(s => setTimeout(s, 3000));
r = await fetch(`${BASE}/api-generate`, { method:"POST", headers:H,
body: JSON.stringify({ action:"poll", taskId }) });
const d = await r.json();
if (d.status === "done") return d.imageUrl;
if (d.status === "failed") throw new Error(d.error);
}
throw new Error("timeout");
}
generate("a cat astronaut, cinematic").then(console.log);
import os, time, requests
BASE = "https://snyyhebdftcpxzdazgjt.supabase.co/functions/v1"
H = {"Authorization": f"Bearer {os.environ['NANO_KEY']}", "Content-Type": "application/json"}
def generate(prompt, model="standard"):
t = requests.post(f"{BASE}/api-generate",
json={"action": "generate", "model": model, "prompt": prompt}, headers=H).json()
task = t["taskId"]
for _ in range(80):
time.sleep(3)
d = requests.post(f"{BASE}/api-generate",
json={"action": "poll", "taskId": task}, headers=H).json()
if d.get("status") == "done": return d["imageUrl"]
if d.get("status") == "failed": raise RuntimeError(d.get("error"))
raise TimeoutError()
print(generate("a cat astronaut, cinematic"))
Les prix sont en crédits (1 crédit = 0,10 €) et calculés pour garantir la marge. Récupère les valeurs à jour via {action:"models"}.
| Modèle | Clé | Crédits / image |
|---|---|---|
| Nano Banana | standard | 4 |
| Nano Banana 2 | v2 | 5 |
| Nano Banana Pro | pro | 6 |
| HTTP | Signification |
|---|---|
| 401 | Clé absente, invalide ou révoquée |
| 402 | Crédits insuffisants (champs need / have) |
| 503 | Service momentanément indisponible (recharge plateforme) |
Besoin d'un volume élevé ou d'un endpoint synchrone ? Contacte le support depuis l'app.