チュートリアル
hiapi API で flux-2-klein-9b/image-to-image を使用する方法:curl、Python、実行可能なリクエスト
このチュートリアルでは、hiapi の統合タスク API を通じて flux-2-klein-9b の image-to-image モードを呼び出す方法を示します:正確なリクエスト構造、実行可能な curl コマンド、バックエンドにそのまま組み込める Python スクリプト、そしてプラットフォーム上の他のモデルから移行してきた場合に遭遇するスキーマの癖について解説します。
読み終える頃には、単一の参照画像 URL と編集プロンプトを受け取り、ダウンロード可能な生成画像 URL を返すスクリプトが完成しているでしょう。
準備するもの
- hiapi アカウントと API キー。hiapi コンソールから取得できます。
- パブリック HTTPS URL でホストされたちょうど 1 枚の参照画像。複数の参照画像を受け付けるプラットフォーム上の一部の image-to-image モデルとは異なり、flux-2-klein-9b の
image_urls配列は最大 1 項目です——詳細は後述します。 - 編集または変換を記述したテキストプロンプト。
すべてのリクエストは統合タスクエンドポイントに送信し、キーは Authorization ヘッダーに含めます:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
リクエスト構造(およびつまずきやすいフィールド)
モデル id は flux-2-klein-9b/image-to-image です——/v1/models に記載されているとおりに、そのまま渡してください。その input スキーマは厳格です:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
prompt |
string | はい | 編集指示。 |
image_urls |
string[] | はい | ちょうど 1 つの参照画像 URL——minItems と maxItems はどちらも 1 です。 |
aspect_ratio |
string | いいえ | 次のいずれか:1:1、4:3、3:4、16:9、9:16。 |
seed |
integer | いいえ | 固定すると結果を再現できます。 |
output_format |
string | いいえ | 次のいずれか:jpeg、png、webp。 |
コードを書く前に知っておくべき点が 2 つあります:
image_urlsは 1 つの URL のみを受け付け、範囲ではありません。1〜14 枚の参照画像を受け付けるモデルを前提に共通の送信コードを組んでいる場合、ここで 2 つの URL を送ると拒否されます——maxItems: got 2, want 1。このモデルは単一画像の編集を行い、複数参照画像の融合は行いません。- 余分なフィールドは無視されず、拒否されます。
resolution、size、n、strength、image_size、num_images——これらはプラットフォーム上の他の画像モデルでは一般的ですが、ここではすべて400 INVALID_REQUEST: additional properties '<field>' not allowedを返します。このモデルのスキーマを確認せずに別モデルの payload を再利用しないでください。
最小の実行可能な例:curl
タスクを作成します:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-2-klein-9b/image-to-image",
"input": {
"prompt": "Change the jacket to charcoal grey leather, keep the pose and background unchanged",
"image_urls": ["https://your-cdn.example.com/subject.png"],
"aspect_ratio": "3:4",
"output_format": "png"
}
}'
送信に成功すると data 内にタスク id が返されます:
{"code": 200, "data": {"taskId": "tk-hiapi-..."}}
結果をポーリングします:
curl https://api.hiapi.ai/v1/tasks/tk-hiapi-... \
-H "Authorization: Bearer sk-<your-key>"
実行中、data.status は queued → handling → archiving と遷移します。完了すると "success" に変わり、画像は data.output に現れます:
{
"code": 200,
"data": {
"status": "success",
"output": [{"url": "https://.../result.png", "expireAt": "..."}]
}
}
出力 URL は短時間で失効します(expireAt に注意)。直ちにバイトをダウンロードして自分で保存してください——ホットリンクや元の URL の永続化は絶対に避けてください。
本番向け Python:送信、ポーリング、ダウンロード
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def edit_image(prompt: str, image_url: str,
aspect_ratio: str = "1:1", output_format: str = "png") -> bytes:
# 1. タスクを作成——このモデルの image_urls はちょうど 1 つの URL のみ受け付けます
resp = requests.post(API_BASE, headers=HEADERS, json={
"model": "flux-2-klein-9b/image-to-image",
"input": {
"prompt": prompt,
"image_urls": [image_url],
"aspect_ratio": aspect_ratio,
"output_format": output_format,
},
}, timeout=60)
body = resp.json()
if resp.status_code != 200 or not (body.get("data") or {}).get("taskId"):
raise RuntimeError(f"create failed [{resp.status_code}]: {body}")
task_id = body["data"]["taskId"]
# 2. 終了状態までポーリング
deadline = time.time() + 600
while time.time() < deadline:
task = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS,
timeout=30).json().get("data") or {}
if task.get("status") == "success":
outputs = task.get("output") or []
if not outputs or not outputs[0].get("url"):
raise RuntimeError(f"task {task_id} succeeded but returned no output URL")
# 3. 直ちにダウンロード——URL は失効します
img = requests.get(outputs[0]["url"], timeout=120)
img.raise_for_status()
return img.content
if task.get("status") == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(5)
raise TimeoutError(f"task {task_id} still running after 600s")
if __name__ == "__main__":
png = edit_image(
"Change the jacket to charcoal grey leather, keep the pose and background unchanged",
"https://your-cdn.example.com/subject.png",
aspect_ratio="3:4",
)
with open("edited.png", "wb") as f:
f.write(png)
print(f"saved edited.png ({len(png)} bytes)")
seed による再現可能な編集
整数の seed を渡すと、モデルはその生成でそれを再利用します。これは他のすべてを変えずにプロンプトの文言を A/B テストしたい場合に役立ちます:
{
"model": "flux-2-klein-9b/image-to-image",
"input": {
"prompt": "Change the jacket to charcoal grey leather, keep the pose and background unchanged",
"image_urls": ["https://your-cdn.example.com/subject.png"],
"seed": 42
}
}
省略すると、モデルは呼び出しごとに seed をランダムに選択します。これは通常の本番トラフィックで望ましい動作です——異なる見た目の出力が必要なときは、seed ではなくプロンプトを変えてください。
ポーリングの代わりにコールバックを使う
スクリプトやワーカーキューではポーリングで十分です。Web バックエンドでは、タスク作成時にコールバックを登録し、hiapi に終了状態をプッシュさせます——callback オブジェクトはリクエストの最上位にあり、model と同じ階層です:
{
"model": "flux-2-klein-9b/image-to-image",
"input": { "...": "..." },
"callback": {
"url": "https://your-app.example.com/hooks/hiapi",
"when": "final"
}
}
"when": "final" を使用すると、タスクが成功または失敗の状態に達したときに、正確に 1 回の POST を受け取ります。ハンドラーには 2 つのルールがあります:
- 冪等にしてください。処理ロジックをタスク id をキーにすることで、再配信された webhook が重複処理されません。送信時にタスク id を保存し、コールバックは「取得して確定する」トリガーとして扱い、唯一の信頼できる情報源とはしないでください。
- 照合パスを残してください。コールバックが発火したときにエンドポイントが利用できない場合、未解決の id を定期的にスキャンして
/v1/tasks/<id>を GET すれば、漏れたものを捕捉できます。
コールバックがまったく届かないように見える場合は、hiapi タスクのコールバックが発火しない理由を一つずつ確認してください——一般的な障害パターンを可能性の高い順に網羅しています。
エラー処理:3 つの重要な失敗シナリオ
作成時に 401 permission_denied——キーがこのモデルを使用できません。レスポンスボディは次のとおりです:
{"error": {"code": "permission_denied", "message": "...", "request_id": "...", "type": "hiapi_error"}}
この問題が発生した場合は、API キーが無効かどうかを確認するか、コンソールでキーのモデル権限を確認してください。
作成時に 400 INVALID_REQUEST——input がこのモデルのスキーマと一致していません。メッセージは違反しているフィールドを直接指摘します(例:<root>: additional properties 'resolution' not allowed、または image_urls: maxItems: got 2, want 1)。これらは恒久的なエラーです——同じ payload を再試行しても永遠に失敗します。フィールドを修正して再送信してください。
タスクが status: "fail" を返す——作成は成功しましたが生成に失敗しました(バックエンドが取得できない参照 URL、コンテンツポリシー、上流の容量)。タスクの error.code と error.message がどれに該当するかを示します。400 とは異なり、一部は一時的なものであり、バックオフ付きで 1 回再試行する価値があります。
また知っておくべきこと:存在しない、または期限切れのタスク id に対して GET を実行すると 404 task not found が返されます——照合スキャンではこれを「まだ待機中」ではなく終了状態として扱ってください。
次に読むべきもの
- flux-2-klein-9b/image-to-image モデルページ——プレイグラウンドと画像ごとの料金。
- hiapi の料金——すべての画像モデルの現在のレート。
- seedream-5.0-lite image-to-image チュートリアル——同じタスク API で、スキーマは 1 枚ではなく最大 14 枚の参照画像を受け付けます。payload がモデル間で移行できない理由をよく示しています。
- hiapi 非同期タスク API ドキュメント——作成/ポーリング/コールバックの完全なリファレンス。
- hiapi 認証ドキュメント——API キーの設定とリクエストヘッダーの形式。
よくある質問
flux-2-klein-9b image-to-image に複数の参照画像を渡せますか?
いいえ。image_urls の minItems と maxItems はどちらも 1 に設定されています——ちょうど 1 つの URL で、それ以上でもそれ以下でもありません。複数参照画像の融合が必要な場合は、より広い範囲を記録したスキーマを持つモデル、例えば seedream-5.0-lite を確認してください。
なぜ「additional properties 'resolution' not allowed」が返されるのですか?
タスク API の input スキーマはモデルごとに異なります。flux-2-klein-9b/image-to-image は resolution や size フィールドをまったく受け付けません——出力サイズは入力画像と aspect_ratio に従います。他のモデルの payload から持ち込んだサイズ関連のフィールドは削除してください。
参照画像を URL ではなく base64 で送信できますか?
このモデルのスキーマは image_urls——URL の配列——を受け付けます。画像をアクセス可能な HTTPS URL(任意の CDN、オブジェクトストレージバケット、または事前署名済み URL で構いません)でホストし、その URL を渡してください。
seed は実際に何を制御しますか?
同じ seed、同じ prompt、参照画像を使用すると同じ生成結果が再現されます。これは制御されたプロンプトの A/B テストに役立ちます。通常のトラフィックでは省略し、各呼び出しに独自のランダム seed を割り当ててください。
同じコードは flux-2-klein-9b text-to-image にも使えますか?
エンドポイントとフローは同じですが、text-to-image には独自の input スキーマがあります(image_urls はありません)。モデル id を flux-2-klein-9b/text-to-image に置き換え、参照画像を削除してください——必須フィールドはモードによって異なるため、テスト呼び出しで検証してください。
画像 1 枚あたりのコストはいくらですか? 料金は生成ごとの使用量に基づいて課金されます。最新のレートは料金ページで確認してください。
関連記事
すべての記事を見る →-
チュートリアル
HiAPI API で hailuo-2.3-fast/image-to-video を呼び出す方法:curl と Python の実践
高速・低コストな画像から動画へのティアにおける最初の実行可能なリクエスト — モデル ID から MP4 のダウンロードまで
-
チュートリアル
HiAPI APIでhailuo-2.3/text-to-videoを呼び出す方法:curl、Python、実行可能なリクエスト例
-
チュートリアル
HiAPI で Kandinsky 6.0 Pro のテキストto動画を使用する:curl と Python チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする