מדריכים
יצירת תמונות
צרו וערכו תמונות באופן אסינכרוני: שלחו משימה, בדקו עד להשלמה והורידו כתובות URL חתומות לפלט.
ה-API לתמונות של Felo יוצר ועורך תמונות עם מודלים מקטלוג המודלים של Felo. הוא אסינכרוני: בקשת השליחה מחזירה מזהה משימה באופן מיידי, ואתם בודקים את המשימה שוב ושוב עד שהיא מגיעה למצב סופי.
העמוד הזה מכסה את החוזה הייחודי לתמונות. למחזור החיים המשותף של משימות, ראו משימות אסינכרוניות.
לפני שמתחילים
- מפתח API. ראו אימות.
- מודל שה-
model_kindשלו הואimage_generation. ראו Find an image model. - כתובת הבסיס
https://openapi.felo.ai.
איך זה שונה מ-OpenAI Images API
הנתיב דומה ל-Images API של OpenAI. התגובה אינה דומה:
| OpenAI Images API | Felo Image API | |
|---|---|---|
| תגובת שליחה | 200 עם נתוני התמונה | 202 עם task_id, status: "queued" |
| מתי התמונה קיימת | בתגובת השליחה | לאחר שהבדיקה החוזרת מגיעה ל-succeeded |
| מטען התמונה | b64_json או url | url חתום ומוגבל בזמן |
| שגיאות בקשה | שגיאת HTTP בעת השליחה | בדרך כלל status: "failed" במשימה |
אל תשלחו openai.images.generate() לנקודת הקצה הזו. ה-SDK מצפה למערך data סינכרוני ואינו יכול לבדוק משימה. קראו לנקודת הקצה דרך HTTP ובדקו את המשימה, או כתבו עטיפה קטנה לשני השלבים.
שליחת משימה
curl -X POST "https://openapi.felo.ai/api/v1/images/generations" \
-H "Authorization: Bearer ${FELO_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-pro-image",
"prompt": "A studio product photo of a ceramic coffee cup on warm linen, soft morning light",
"resolution": "2K",
"aspect_ratio": "4:3"
}'שליחה מוצלחת מחזירה HTTP 202:
{
"task_id": "6d1f0c9a-...",
"status": "queued",
"kind": "image",
"outputs": []
}202 פירושו שהפלטפורמה קיבלה את המשימה. זה לא אומר שהפרומפט, הפרמטרים או תמונות הייחוס חוקיים. הקריאה החיצונית רצה לאחר התגובה, ולכן רוב בעיות הבקשה מופיעות מאוחר יותר כמשימה שנכשלה. היוצא מן הכלל הוא ניתוב מודלים: מודל שיחה או וידאו נדחה בעת השליחה.
בדיקה חוזרת עד שהמשימה סופית
curl "https://openapi.felo.ai/api/v1/images/generations/${TASK_ID}" \
-H "Authorization: Bearer ${FELO_API_KEY}"| סטטוס | משמעות | מה לעשות |
|---|---|---|
queued | התקבל; ממתין להתחלה | המשיכו לבדוק |
running | המודל יוצר | המשיכו לבדוק |
succeeded | סופי; outputs מאוכלס | הורידו את הפלטים |
failed | סופי; קראו error.message | תקנו את הבקשה; אל תנסו שוב ללא שינוי |
interrupted | סופי; לא ניתן היה לשחזר את התוצאה | שלחו את המשימה מחדש |
כשלים במשימה משאירים את סטטוס ה-HTTP על 200. בדקו את status בגוף, לא רק את סטטוס ה-HTTP.
התחילו במרווח של 2–5 שניות והגדילו אותו. רוב התמונות מסתיימות בתוך דקה; פלט 4K ועריכות עם תמונות ייחוס רבות לוקחות יותר זמן. תמיד הגדירו פסק זמן משלכם.
import os
import time
import requests
BASE = "https://openapi.felo.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['FELO_API_KEY']}"}
def generate_image(prompt: str, **params) -> list[dict]:
response = requests.post(
f"{BASE}/api/v1/images/generations",
headers=HEADERS,
json={"model": "gemini-3-pro-image", "prompt": prompt, **params},
timeout=30,
)
response.raise_for_status()
task = response.json()
deadline = time.monotonic() + 300
delay = 2.0
while time.monotonic() < deadline:
time.sleep(delay)
delay = min(delay * 1.5, 10.0)
poll = requests.get(
f"{BASE}/api/v1/images/generations/{task['task_id']}",
headers=HEADERS,
timeout=30,
)
poll.raise_for_status()
task = poll.json()
if task["status"] == "succeeded":
return task["outputs"]
if task["status"] in {"failed", "interrupted"}:
message = task.get("error", {}).get("message", task["status"])
raise RuntimeError(message)
raise TimeoutError(f"image task {task['task_id']} did not finish")קריאה ואחסון של הפלטים
כשהמשימה מצליחה, outputs מכיל פריט אחד לכל תמונה שנוצרה:
{
"task_id": "6d1f0c9a-...",
"status": "succeeded",
"kind": "image",
"outputs": [
{
"media_type": "image/png",
"url": "https://openapi.felo.ai/api/v1/media/...?exp=...&sig=..."
}
]
}outputsריק עד שהמשימה מצליחה.urlהוא כתובת חתומה. היא ניתנת להורדה בלי מפתח API, לכן התייחסו אליה כאל קישור נושא.- הכתובת מוגבלת בזמן. פרמטר השאילתה
expהוא זמן התפוגה שלה. הורידו את הקובץ ואחסנו אותו ב-bucket או במערכת הקבצים שלכם; המשימה אינה אחסון קבוע. - בדיקה חוזרת לאחר שהכתובת פגה מחזירה את אותה כתובת שפגה. היא אינה מנפיקה כתובת חדשה.
- התגובה אינה כוללת נתוני תמונה ב-base64.
for index, output in enumerate(outputs):
image = requests.get(output["url"], timeout=60)
image.raise_for_status()
with open(f"image-{index}.png", "wb") as file:
file.write(image.content)עריכת תמונה
העבירו תמונות ייחוס ב-input_references. המודל משתמש בהן כהקשר; הפרומפט עדיין מתאר את השינוי.
curl -X POST "https://openapi.felo.ai/api/v1/images/generations" \
-H "Authorization: Bearer ${FELO_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-pro-image",
"prompt": "Keep the product and framing. Replace the background with a sunlit marble countertop.",
"resolution": "2K",
"aspect_ratio": "4:3",
"input_references": [
{
"type": "image_url",
"image_url": {"url": "https://example.com/product.png"}
}
]
}'כל ייחוס הוא כתובת HTTP(S) או כתובת data מסוג base64. סדר הייחוסים נשמר; התייחסו לתמונות לפי מיקומן בפרומפט כשזה חשוב. המודלים הנוכחיים מקבלים עד 14 ייחוסים.
שדות הבקשה
| שדה | חובה | תיאור |
|---|---|---|
model | כן | מזהה מודל מהקטלוג, למשל gemini-3-pro-image. אל תשתמשו במזהה ה-google/... של הספק החיצוני |
prompt | כן | הוראת טקסט. לעריכה, תארו את השינוי ומה חייב להישאר זהה |
resolution | לא | דרגת פלט. המודלים הנוכחיים מקבלים 1K, 2K או 4K |
aspect_ratio | לא | יחס פלט. הערכים המקובלים תלויים במודל |
n | לא | מספר תמונות. המודלים הנוכחיים מקבלים 1 |
input_references | לא | תמונות ייחוס לעריכה או להרכבה |
מודלי התמונות הנוכחיים:
| מזהה מודל | רזולוציות | יחסי גובה-רוחב | תמונות למשימה | תמונות ייחוס |
|---|---|---|---|---|
gemini-3-pro-image | 1K, 2K, 4K | 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 | 1 | עד 14 |
gemini-nano-banana-2.1 | 1K, 2K, 4K | 1:1, 1:4, 1:8, 2:3, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 9:16, 16:9, 21:9 | 1 | עד 14 |
כדי לנעוץ ספק, שלחו את הכותרת X-Felo-Channel עם קוד ערוץ מתוך רשימת ה-channels של המודל. ראו ערוצים וניתוב ספקים.
Find an image model (איך למצוא מודל תמונה)
אין נקודת קצה נפרדת לרשימת מודלי תמונה. שאלו את הקטלוג הכללי וסננו לפי model_kind:
curl "https://openapi.felo.ai/api/v1/models" \
-H "Authorization: Bearer ${FELO_API_KEY}" \
| jq '.data[] | select(.model_kind == "image_generation") | {id, name}'GET /api/v1/models/{model_id} מחזיר את הערוצים והתעריפים המפורסמים של המודל.
supported_parameters בקטלוג הכללי הוא רשימה ברמת הפרוטוקול. עבור מודלי תמונה הוא אינו מפרט באופן אמין את שדות התמונה שלמעלה, לכן אל תבנו את הבקשה שלכם ממנו. השתמשו בטבלת השדות במדריך הזה ואשרו את מזהה המודל מהקטלוג.
תמחור
יצירת תמונות מחויבת לפי התעריפים המפורסמים של המודל. הקטלוג חושף input_image ו-output_image לצד תעריפי הטקסט prompt ו-completion. תעריפי התמונה הם תעריפי טוקנים: resolution משנה כמה טוקני תמונת פלט תמונה צורכת, לכן תמונת 4K עולה יותר מתמונת 1K. תמונות ייחוס מוסיפות טוקני תמונת קלט.
תגובת המשימה אינה כוללת אובייקט usage. בדקו את החיוב ב-Console Billing.
משימה שמסתיימת ב-failed או interrupted אינה מפיקה פלט ואינה מחויבת. שליחה שנדחתה עם 402 לא יצרה משימה.
שגיאות
שגיאות ברמת נקודת הקצה מנתיב התמונות משתמשות במעטפת השגיאה של OpenAI:
{
"error": {
"message": "Model kind does not match this generation endpoint",
"type": "invalid_request_error",
"param": null,
"code": "model_kind_mismatch"
}
}מזהה הבקשה נמצא בכותרת התגובה X-Request-Id. תעדו אותו בלוג יחד עם מזהה המשימה.
| HTTP | error.code | משמעות |
|---|---|---|
| 400 | invalid_request_error | model חסר, או שהגוף אינו אובייקט JSON |
| 400 | model_not_configured | מזהה המודל אינו בקטלוג המופעל |
| 400 | chat_model_not_allowed | נשלח מודל שיחה לנקודת הקצה של התמונות |
| 400 | model_kind_mismatch | נשלח מודל וידאו או מודל אחר שאינו תמונה |
| 402 | insufficient_balance | אין מספיק קרדיטים; לא נוצרה משימה |
| 404 | generation_task_not_found | מזהה המשימה אינו מוכר או שייך לחשבון אחר |
| 429 | daily_spend_limit_exceeded | מגבלת ההוצאה היומית של החשבון הגיעה |
| 503 | generation_unavailable | היצירה אינה זמינה זמנית; נסו שוב מאוחר יותר |
שגיאות אימות מתוארות בשגיאות, מגבלות וניסיונות חוזרים.