راهنماها
تولید تصویر
تصاویر را بهصورت ناهمزمان تولید و ویرایش کنید: یک کار ارسال کنید، تا تکمیل بررسی کنید و URLهای امضاشده خروجی را دانلود کنید.
Felo image API با مدلهای کاتالوگ مدل Felo تصویر تولید و ویرایش میکند. این API ناهمگام است: درخواست ارسال بیدرنگ یک شناسه وظیفه برمیگرداند و شما تا رسیدن وظیفه به وضعیت پایانی، وضعیت آن را پیگیری میکنید.
این صفحه قرارداد مخصوص تصویر را پوشش میدهد. برای چرخه عمر مشترک وظیفه، وظایف ناهمگام را ببینید.
پیش از شروع
- یک کلید API. احراز هویت را ببینید.
- مدلی که
model_kindآنimage_generationاست. یافتن مدل تصویری را ببینید. - base URL برابر
https://openapi.felo.ai.
تفاوت آن با OpenAI Images API
مسیر شبیه OpenAI Images API است. پاسخ چنین نیست:
| OpenAI Images API | Felo Image API | |
|---|---|---|
| پاسخ ارسال | 200 با داده تصویر | 202 با task_id و status: "queued" |
| زمان وجود تصویر | در پاسخ ارسال | پس از رسیدن پیگیری وضعیت به succeeded |
| محموله تصویر | b64_json یا url | یک url امضاشده با محدودیت زمانی |
| خطاهای درخواست | خطای HTTP هنگام ارسال | معمولاً status: "failed" روی وظیفه |
openai.images.generate() را به این endpoint نفرستید. SDK آرایه همگام data را انتظار دارد و نمیتواند وظیفهای را پیگیری کند. endpoint را از طریق 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 یعنی پلتفرم وظیفه را پذیرفته است. معنایش این نیست که prompt، پارامترها یا تصاویر مرجع معتبرند. فراخوانی بالادستی پس از پاسخ اجرا میشود، پس بیشتر مشکلات درخواست بعداً بهصورت وظیفه ناموفق ظاهر میشوند. استثنا مسیریابی مدل است: مدل چت یا ویدیو هنگام ارسال رد میشود.
پیگیری وضعیت تا پایان وظیفه
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یک URL امضاشده است. بدون کلید API دانلود میشود، پس با آن مانند یک پیوند حامل رفتار کنید.- URL محدود به زمان است. پارامتر پرسوجوی
expزمان انقضای آن است. فایل را دانلود کنید و در سبد یا فایلسیستم خود ذخیره کنید؛ وظیفه فضای ذخیرهسازی دائمی نیست. - پیگیری دوباره پس از انقضای URL همان URL منقضی را برمیگرداند. URL تازه صادر نمیکند.
- پاسخ داده تصویر 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 بفرستید. مدل از آنها بهعنوان زمینه استفاده میکند؛ prompt همچنان تغییر را توصیف میکند.
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"}
}
]
}'هر مرجع یک URL با پروتکل HTTP(S) یا یک data URL با base64 است. ترتیب مرجع حفظ میشود؛ وقتی اهمیت دارد در prompt با موقعیت به تصاویر اشاره کنید. مدلهای جاری تا 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 (یافتن مدل تصویر)
endpoint فهرست جداگانه مدل تصویری وجود ندارد. کاتالوگ عمومی را پرسوجو کنید و بر اساس 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 وظیفهای نساخته است.
خطاها
خطاهای سطح endpoint از مسیر تصویر از پوشش خطای 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 | یک مدل چت به endpoint تصویر فرستاده شد |
| 400 | model_kind_mismatch | یک مدل ویدیو یا غیرتصویری دیگر فرستاده شد |
| 402 | insufficient_balance | اعتبار کافی نیست؛ وظیفهای ساخته نشد |
| 404 | generation_task_not_found | شناسه وظیفه ناشناخته است یا به حساب دیگری تعلق دارد |
| 429 | daily_spend_limit_exceeded | سقف هزینه روزانه حساب پر شد |
| 503 | generation_unavailable | تولید موقتاً در دسترس نیست؛ بعداً دوباره تلاش کنید |
خطاهای احراز هویت در خطاها، محدودیتها و تلاش دوباره توضیح داده شدهاند.