Hướng dẫn
Tạo hình ảnh
Tạo và chỉnh sửa hình ảnh bất đồng bộ: gửi tác vụ, thăm dò đến khi hoàn tất và tải URL đầu ra đã ký.
API hình ảnh của Felo tạo và chỉnh sửa hình ảnh bằng các mô hình từ danh mục mô hình Felo. API này hoạt động bất đồng bộ: yêu cầu gửi đi trả về task ID ngay lập tức, và bạn thăm dò tác vụ cho đến khi nó đạt trạng thái kết thúc.
Trang này trình bày hợp đồng riêng cho hình ảnh. Về vòng đời tác vụ dùng chung, xem Tác vụ bất đồng bộ.
Trước khi bắt đầu
- Một khóa API. Xem Xác thực.
- Một mô hình có
model_kindlàimage_generation. Xem Tìm mô hình ảnh. - Base URL
https://openapi.felo.ai.
Khác biệt so với OpenAI Images API
Đường dẫn tương tự OpenAI Images API. Phản hồi thì không:
| OpenAI Images API | Felo Image API | |
|---|---|---|
| Phản hồi khi gửi | 200 kèm dữ liệu hình ảnh | 202 với task_id, status: "queued" |
| Khi hình ảnh tồn tại | Trong phản hồi gửi | Sau khi thăm dò đạt succeeded |
| Dữ liệu hình ảnh | b64_json hoặc url | Một url đã ký, có giới hạn thời gian |
| Lỗi yêu cầu | Lỗi HTTP khi gửi | Thường là status: "failed" trên tác vụ |
Không gửi openai.images.generate() đến endpoint này. SDK mong đợi một mảng data đồng bộ và không thể thăm dò tác vụ. Hãy gọi endpoint qua HTTP và thăm dò tác vụ, hoặc viết một lớp bọc nhỏ cho cả hai bước.
Gửi một tác vụ
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"
}'Một lần gửi thành công trả về HTTP 202:
{
"task_id": "6d1f0c9a-...",
"status": "queued",
"kind": "image",
"outputs": []
}202 nghĩa là nền tảng đã chấp nhận tác vụ. Điều đó không có nghĩa là câu lệnh, tham số hoặc hình ảnh tham chiếu hợp lệ. Lệnh gọi thượng nguồn chạy sau khi phản hồi, nên hầu hết vấn đề về yêu cầu xuất hiện sau đó dưới dạng tác vụ thất bại. Ngoại lệ là định tuyến mô hình: mô hình chat hoặc video bị từ chối ngay khi gửi.
Thăm dò cho đến khi tác vụ kết thúc
curl "https://openapi.felo.ai/api/v1/images/generations/${TASK_ID}" \
-H "Authorization: Bearer ${FELO_API_KEY}"| Trạng thái | Ý nghĩa | Cần làm gì |
|---|---|---|
queued | Đã chấp nhận; đang chờ bắt đầu | Tiếp tục thăm dò |
running | Mô hình đang tạo sinh | Tiếp tục thăm dò |
succeeded | Kết thúc; outputs đã có dữ liệu | Tải các đầu ra |
failed | Kết thúc; đọc error.message | Sửa yêu cầu; không thử lại nguyên trạng |
interrupted | Kết thúc; không thể khôi phục kết quả | Gửi lại tác vụ |
Tác vụ thất bại vẫn giữ trạng thái HTTP là 200. Hãy kiểm tra status trong nội dung, không chỉ trạng thái HTTP.
Bắt đầu với khoảng thời gian 2–5 giây và giãn dần. Hầu hết hình ảnh hoàn tất trong vòng một phút; đầu ra 4K và các chỉnh sửa có nhiều hình ảnh tham chiếu mất lâu hơn. Luôn đặt thời hạn của riêng bạn.
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")Đọc và lưu các đầu ra
Khi tác vụ thành công, outputs chứa một mục cho mỗi hình ảnh được tạo:
{
"task_id": "6d1f0c9a-...",
"status": "succeeded",
"kind": "image",
"outputs": [
{
"media_type": "image/png",
"url": "https://openapi.felo.ai/api/v1/media/...?exp=...&sig=..."
}
]
}outputstrống cho đến khi tác vụ thành công.urllà URL đã ký. Có thể tải xuống mà không cần khóa API, nên hãy coi nó như một liên kết bearer.- URL có giới hạn thời gian. Tham số truy vấn
explà thời điểm hết hạn. Hãy tải tệp về và lưu vào bucket hoặc hệ thống tệp của riêng bạn; tác vụ không phải nơi lưu trữ vĩnh viễn. - Thăm dò lại sau khi URL hết hạn sẽ trả về cùng URL đã hết hạn đó. Nó không cấp URL mới.
- Phản hồi không bao gồm dữ liệu hình ảnh 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)Chỉnh sửa hình ảnh
Truyền hình ảnh tham chiếu trong input_references. Mô hình dùng chúng làm ngữ cảnh; câu lệnh vẫn mô tả thay đổi.
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"}
}
]
}'Mỗi tham chiếu là một URL HTTP(S) hoặc một data URL base64. Thứ tự tham chiếu được giữ nguyên; hãy tham chiếu hình ảnh theo vị trí trong câu lệnh khi điều đó quan trọng. Các mô hình hiện tại chấp nhận tối đa 14 tham chiếu.
Các trường yêu cầu
| Trường | Bắt buộc | Mô tả |
|---|---|---|
model | Có | Model ID trong danh mục, ví dụ gemini-3-pro-image. Không dùng ID google/... của thượng nguồn |
prompt | Có | Chỉ dẫn văn bản. Với thao tác chỉnh sửa, mô tả thay đổi và những gì phải giữ nguyên |
resolution | Không | Bậc đầu ra. Các mô hình hiện tại chấp nhận 1K, 2K hoặc 4K |
aspect_ratio | Không | Tỷ lệ đầu ra. Giá trị được chấp nhận phụ thuộc vào mô hình |
n | Không | Số lượng hình ảnh. Các mô hình hiện tại chấp nhận 1 |
input_references | Không | Hình ảnh tham chiếu để chỉnh sửa hoặc ghép |
Các mô hình hình ảnh hiện tại:
| Model ID | Độ phân giải | Tỷ lệ khung hình | Hình ảnh mỗi tác vụ | Tham chiếu |
|---|---|---|---|---|
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 | Tối đa 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 | Tối đa 14 |
Để ghim một nhà cung cấp, hãy gửi header X-Felo-Channel với một mã kênh từ danh sách channels của mô hình. Xem Kênh và định tuyến nhà cung cấp.
Tìm mô hình ảnh
Không có endpoint liệt kê mô hình hình ảnh riêng. Hãy truy vấn danh mục chung và lọc theo 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} trả về các kênh và mức giá được công bố của mô hình.
supported_parameters trong danh mục chung là danh sách ở cấp giao thức. Với các mô hình hình ảnh, nó không liệt kê đáng tin cậy các trường hình ảnh ở trên, nên đừng xây dựng yêu cầu của bạn từ đó. Hãy dùng bảng trường trong hướng dẫn này và xác nhận model ID từ danh mục.
Giá
Việc tạo hình ảnh được tính phí theo mức giá được công bố của mô hình. Danh mục công bố input_image và output_image cùng với mức giá văn bản prompt và completion. Mức giá hình ảnh là mức giá token: resolution thay đổi số token hình ảnh đầu ra mà một hình ảnh tiêu thụ, nên một hình ảnh 4K tốn nhiều hơn một hình ảnh 1K. Hình ảnh tham chiếu làm tăng token hình ảnh đầu vào.
Phản hồi tác vụ không bao gồm đối tượng usage. Hãy kiểm tra Console Billing để xem khoản phí.
Một tác vụ kết thúc failed hoặc interrupted không tạo đầu ra và không bị tính phí. Một lần gửi bị từ chối với 402 đã không tạo tác vụ.
Lỗi
Lỗi ở cấp endpoint từ tuyến hình ảnh dùng cấu trúc lỗi của OpenAI:
{
"error": {
"message": "Model kind does not match this generation endpoint",
"type": "invalid_request_error",
"param": null,
"code": "model_kind_mismatch"
}
}Request ID nằm trong header phản hồi X-Request-Id. Hãy ghi nó cùng với task ID.
| HTTP | error.code | Ý nghĩa |
|---|---|---|
| 400 | invalid_request_error | Thiếu model, hoặc nội dung không phải đối tượng JSON |
| 400 | model_not_configured | Model ID không có trong danh mục đang bật |
| 400 | chat_model_not_allowed | Một mô hình chat đã được gửi đến endpoint hình ảnh |
| 400 | model_kind_mismatch | Một mô hình video hoặc mô hình không phải hình ảnh đã được gửi |
| 402 | insufficient_balance | Không đủ tín dụng; không có tác vụ nào được tạo |
| 404 | generation_task_not_found | Task ID không xác định hoặc thuộc tài khoản khác |
| 429 | daily_spend_limit_exceeded | Đã đạt giới hạn chi tiêu hàng ngày của tài khoản |
| 503 | generation_unavailable | Tạo sinh tạm thời không khả dụng; thử lại sau |
Lỗi xác thực được mô tả trong Lỗi, giới hạn và thử lại.