チュートリアル
HiAPI API で recraft/creative-upscale を使う方法:curl と Python リクエストガイド
開発者ワークフローにおける recraft/creative-upscale の役割
recraft/creative-upscale は image-to-image エンドポイントです。既存の画像を送信すると、モデルによって再構築された、より大きなバージョンが返されます。ここでのキーワードはクリエイティブ(creative)です。従来のアップサンプリング処理(双線形、Lanczos、または汎用超解像モデル)は、入力をできるだけ忠実に保持します。クリエイティブ・アップサンプリングでは、元のピクセルには存在しなかったディテールを再生成できます。エッジは再合成され、テクスチャは推論され、小さくぼやけた領域は単なる補間ではなく、もっともらしいコンテンツとしてシャープ化されます。
これにより、単純な拡大ツールとは異なり、パイプライン内でも別の位置を占めることになります。
いつ使うべきか
- アセットのアップグレード。 サムネイルや旧バージョンの製品画像をより大きな表示サイズで提示する必要があり、通常の拡大ではネイティブ解像度の隣人と比べてぼやけて見える場合。
- リファレンス画像やモックアップの作業。 コンセプトアート、ストーリーボード、プレースホルダー画像を、低解像度の出自を露呈させずに大きなサイズで提示する必要がある場合。
- 生成ループ内でのアップサンプリング。 小さな作業サイズで画像を生成し、より大きなキャンバスで生成プロセス全体を再実行せずに最終アセットを得たい場合。
使うべきでないとき
要件がバイト単位の正確な忠実性である場合——アーカイブスキャン、ドキュメント、ピクセル値そのものがデータであるテクスチャアトラス——クリエイティブモデルは使わないでください。再生成されたディテールはもっともらしい推測であり、再構築ではありません。測定やアーカイブの目的では、その推測は欠陥になります。そのような場合は決定的なリサンプラーを使い、クリエイティブモデルは知覚的な出力に残しておいてください。
呼び出しの形
このエンドポイントは、他の HiAPI 画像エンドポイントと同じリクエストパターンに従います。モデルパスに対して認証付き JSON POST リクエストを送信し、入力画像とパラメータオブジェクトを含めます。プラットフォーム上の他の画像モデルをすでに統合している場合、このメンタルモデルはそのまま移行できます。これは、統一インターフェースを介してこれらの呼び出しをルーティングすることの意義そのものです。動作する curl 呼び出しは、その後触れるすべての画像エンドポイントのテンプレートになります。
このステップを理解するのに役立つ見方があります。すでに信頼している画像(構図、内容、色が確定済み)を消費し、より大きく詳細なバリアントを返します。コンテンツの決定は上流に属し、recraft/creative-upscale は仕上げの段階です。
前提条件とエンドポイントの設定
最初のリクエストを書く前に、4 つのものを用意してください。いずれも特別な SDK は不要です。統合全体は JSON リクエストボディを伴う純粋な HTTPS 通信です。
1. API キー
画像モデルにアクセスできる HiAPI API キーが必要です。秘密情報として扱ってください。スクリプトに貼り付けるのではなく環境変数から読み込み、バージョン管理にコミットしないでください。
export HIAPI_API_KEY="your-key-here"
キーはリクエストヘッダーで渡され、URL にも JSON リクエストボディにも含まれません。クエリ文字列から排除することで、シェル履歴やプロキシログからも排除できます。
2. ベース URL
ベース URL は、あなたの HiAPI API ホストです。すべてのモデル呼び出しはその下の相対パスであるため、変数に設定して各スクリプトで再利用できます。
export HIAPI_BASE_URL="https://api.hiapi.ai"
プラットフォームの API リファレンスドキュメントで、アカウントの正規のベース URL とパスプレフィックスを確認し、この単一の変数として保存してください。そうすれば、ホストやバージョンの変更は 1 行の編集で済みます。
3. モデル識別子
モデル ID はパスセグメントであり、公開されている綴りに正確に従う必要があります: recraft/creative-upscale。スラッシュを含んでおり、これが一部のツールで重要になります。デバッグのセクションで詳しく説明します。大文字小文字とハイフンはすべて重要です。1 文字間違えるとモデルが見つからないエラーが発生し、メッセージをざっと読むと認証の問題に見えます。
4. テスト画像
ディスク上に画像を用意し、正確なパスと MIME タイプを把握しておいてください。最初の実行では小さなファイルを使用し、失敗がリクエストの問題であることが明確になるようにします。ペイロードのサイズやタイムアウトの問題ではありません。後で同じ画像を比較実行に再利用するため、平坦なグラデーションではなく、目に見えるディテールのあるもの(布地、植生、テキストのない看板など)を選んでください。
リクエストヘッダーのチェックリスト
ここから先のすべてのリクエストは同じヘッダーを持ちます。
Authorization: Bearer $HIAPI_API_KEYContent-Type: application/json
JSON リクエストボディで画像を base64 または data URI として送信する場合、これらの 2 つのヘッダーで十分です。代わりにファイルを先にアップロードして URL を取得する場合は、そのアップロードを別の呼び出しとして扱い、生成された URL をモデルリクエストとは別に保存してください。
キー、ベース URL、モデル ID、テスト画像があれば、1 分もかからずに実際の呼び出しを開始できます。
curl を使った動作するリクエスト
以下はすぐに実行できる呼び出しです。画像の値は自分の入力に置き換えてください。モデルの入力モードが受け入れるものに応じて、公開アクセス可能な URL または base64 エンコードされた data URI のいずれかです。
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"image": "https://example.com/test-input.png"
},
"parameters": {
"upscale": 2
}
}' \
-o response.json
-o を使ってレスポンスをターミナルにストリーミングするのではなくファイルに書き込むことで、JSON をそのまま解析でき、呼び出しをスクリプト化できます。
各部分の役割
-X POST—— このエンドポイントは POST です。GET はメソッドエラーを返し、権限の問題と誤読されやすくなります。- URL —— ベース URL に続いて、完全なモデル ID を含むモデルパスです。ID 自体にスラッシュが含まれるため、パスはモデルコレクションの後に 2 つのセグメントを持ちます。ドキュメントがその動作を意図していると説明していない限り、クライアントライブラリに
recraft%2Fcreative-upscaleへ再エンコードさせず、1 つの文字列として保ってください。 Authorization—— bearer トークンです。この正確なコマンドで 401 が出る場合、キーまたはヘッダー形式が間違っています。リクエストボディの他の内容はまだ検証されていません。Content-Type: application/json—— 必須です。これがないと、一部のゲートウェイはリクエストボディをフォームデータとして扱い、リクエストがモデルに到達しなくなります。input.image—— ソース画像です。反復作業中は URL を優先してください。コマンドを短く保ち、差分が明確になります。parameters.upscale—— アップサンプリングの制御です。控えめな倍率から始め、レスポンスを確認してから上げてください。
2 つの実用的なバリアント
URL の代わりにローカルファイルを base64 として送信するには:
B64=$(base64 -w0 ./test-input.png)
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"input\": { \"image\": \"data:image/png;base64,${B64}\" },
\"parameters\": { \"upscale\": 2 }
}" \
-o response.json
デバッグ時に HTTP ステータスコードとレスポンスボディの両方を確認するには、-w '\nHTTP %{http_code}\n' を追加し、-o を削除してください。
この 1 つのコマンドをテンプレートとして扱ってください。画像が返されたら、その後の変更——異なる倍率、異なるソース画像——は新しい統合ではなく、2 つのフィールドの編集にすぎません。
Python での同じリクエスト
Python バージョンは curl のリクエストボディをコピー&ペーストしたものではなく、小さな再利用可能な関数であるべきです。そうすれば、後続の比較実行は毎回 1 回の呼び出しで済みます。標準ライブラリのみを使用し、SDK は不要です。
import base64
import json
import os
import pathlib
import urllib.request
HIAPI_BASE_URL = os.environ["HIAPI_BASE_URL"].rstrip("/")
HIAPI_API_KEY = os.environ["HIAPI_API_KEY"]
MODEL = "recraft/creative-upscale"
def creative_upscale(image: str, upscale: int = 2, timeout: int = 120) -> dict:
"""画像を recraft/creative-upscale に送信し、解析済みの JSON を返します。"""
payload = {
"input": {"image": image},
"parameters": {"upscale": upscale},
}
request = urllib.request.Request(
url=f"{HIAPI_BASE_URL}/v1/models/{MODEL}",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {HIAPI_API_KEY}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request, timeout=timeout) as response:
return json.loads(response.read().decode("utf-8"))
def as_data_uri(path: str) -> str:
data = pathlib.Path(path).read_bytes()
mime = "image/png" if path.lower().endswith(".png") else "image/jpeg"
return f"data:{mime};base64,{base64.b64encode(data).decode('ascii')}"
if __name__ == "__main__":
result = creative_upscale(as_data_uri("test-input.png"), upscale=2)
print(json.dumps(result, indent=2)[:2000])
なぜこの形なのか
- 設定は環境変数から取得。 ベース URL とキーはインポート時に 1 回読み込まれるため、ファイル内に機密情報が現れることはなく、環境の切り替えは 1 回の export で済みます。
- 1 つの関数、1 つの責務。
creative_upscaleは画像参照と倍率を受け取り、解析済みの JSON を返します。パラメータに関するすべての情報は呼び出し側で見えるままです。 - 明示的なタイムアウト。 画像モデルはテキストエンドポイントよりも時間がかかります。短すぎるデフォルト値を継承するのではなく、意図的にタイムアウトを設定し、遅いが成功する呼び出しが不必要にリトライされないよう十分長く保ってください。
- ローカルファイル用のヘルパー。
as_data_uriがあれば、リクエストロジックを変更せずに URL またはローカルパスを渡せます。
セッションベースのクライアントを好む場合
httpx を使った同じ呼び出しは 2 行の置き換えだけで済みます。クライアントを構築し、デフォルトの Authorization ヘッダーを設定し、JSON ボディを post します。重要な不変条件は変わりません。モデル ID は単一の非エンコードパスセグメントのままで、キーはヘッダーに残り、ボディは input / parameters の分割を保ちます。この 3 点を守れば、クライアントはプラットフォーム上の他のどのクライアントとも互換性があります。
パイプラインに組み込むときは、解析済みの辞書を返し、画像をどのように永続化するかは呼び出し側に決めさせてください。この分離により、次のセクションのレスポンス処理が再利用可能になります。
アップサンプリングとクリエイティブパラメータ
送信する値よりも、どこに送信するかが重要です。まず位置を正しく確認し、それから値をチューニングしてください。
2 つのバケツ、1 つの契約
各リクエストは次のように分かれます。
input—— 画像そのもの。操作対象です。モデルの動作に関する内容はここには置きません。parameters—— 制御項目です。アップサンプリング倍率とクリエイティブ設定はこのオブジェクトに属し、互いに兄弟です。
この分割が契約です。最初の実行では、モデルがあなたの配置を受け入れること——つまり呼び出しが少なくとも画像を返すこと——を確認してから、値の最適化を始めてください。パラメータが間違ったバケツに入っていると、通常はデフォルト値で生成された画像、または不明なフィールドを示す検証エラーが返ります。どちらの場合も配置の誤りであり、品質の誤りではないため、品質設定を追いかけても修正されません。
アップサンプリング倍率
倍率は、入力に対する出力のサイズを制御します。それについての推論:
- 乗数であるため、コストとレイテンシもそれに伴って増加します。 控えめな倍率から最大値への引き上げは、レンダリング時間において線形なステップではありません。各ステップの引き上げは、スライダーの微調整ではなく新しい実験として扱ってください。
- 入力解像度は依然として重要です。 ある程度の構造があると、クリエイティブモデルはより多くの余地を持ちます。極端に小さい入力はモデルに発明の自由を多く与え、それが目標であることもあれば、予期せぬ結果であることもあります。
- 最大値ではなく、目標サイズに基づいて倍率を選んでください。 画像が配置場所に収まるために 2× が必要なら、2× をリクエストしてください。最大値をリクエストしてから縮小すると、利益を捨ててそのコストを払うことになります。
クリエイティブ制御
クリエイティブは、モデルが拡大するのではなく置き換えできる量を決めるノブです。低い設定は忠実なアップサンプリングに近い動作をし、高い設定はモデルに積極的な再合成をさせます。これによりぼやけた、またはブロック状のソースを救える一方、望まないディテールを導入する可能性も同様にあります。
このパラメータは忠実度のレバーとして扱い、両端には具体的な解釈があります。
- 保持 —— ロゴ、顔、製品カタログ画像、閲覧者が元画像と比較する可能性のあるあらゆるもの。
- 再生成 —— コンセプトアート、背景、テクスチャ、装飾画像、もっともらしさが正確さに勝るもの。
進め方
一度に 1 つのパラメータを変更し、入力を固定し、値と出力を一緒に記録してください。小さなマトリックス——同じ画像を 2 つの倍率で、各倍率を 2 つのクリエイティブ設定で——があれば、自分のコンテンツ上でこのエンドポイントの特性を把握するのに十分です。他人の「ベスト」値を使い回さないでください。クリエイティブモデルは入力と強く相互作用し、写真に合う設定がフラットなイラストに合うことはまれです。
ある値が悪い結果を生むのではなく直接拒否される場合、それは契約がパラメータのドメインを伝えているのです。推測するのではなく、エンドポイントのパラメータリファレンスで許容範囲を確認してください。
レスポンスの読み取りと画像の保存
レスポンスは防御的に解析してください。ペイロードの種類は契約の一部ですが、URL とインライン base64 ブロックの間で異なる場合があり、クライアントはどちらを受け取ってもクラッシュすべきではありません。
まず、生の JSON を確認する
パーサーを書く前に、-o response.json で curl 呼び出しを 1 回実行し、ファイルを読んでください。画像を運ぶフィールドを特定します。通常は次のいずれかです。
- 生成ファイルを指す URL、または
- インライン文字列、通常は base64 または data URI。
また、記録する価値のあるメタデータも探してください。サイズ、エコーバックされたモデル ID、サポートリクエストに使える任意の識別子です。
耐障害性のある保存関数
import base64
import pathlib
import urllib.request
def extract_image(result: dict) -> str:
"""返された形態に関係なく、画像ペイロードを見つけます。"""
for container in (result, result.get("data"), result.get("output")):
if isinstance(container, list) and container:
container = container[0]
if isinstance(container, dict):
for key in ("image", "url", "b64_json", "image_url"):
value = container.get(key)
if isinstance(value, str) and value:
return value
raise ValueError(f"no image field in response: {sorted(result)}")
def save_image(payload: str, out_path: str = "upscaled.png") -> pathlib.Path:
path = pathlib.Path(out_path)
if payload.startswith("data:"):
payload = payload.split(",", 1)[1]
path.write_bytes(base64.b64decode(payload))
elif payload.startswith("http://") or payload.startswith("https://"):
with urllib.request.urlopen(payload) as response:
path.write_bytes(response.read())
else:
path.write_bytes(base64.b64decode(payload))
return path
重要なのは、これが唯一正しいパーサーだということではなく、この関数が前提(data:、http(s)://、純粋な base64)を述べ、どれにも一致しない場合に明確なエラーを投げるということです。レスポンスの形が変わったとき、更新するのは 1 つの関数だけで、画像を消費するすべてのスクリプトではありません。
curl フローでの安全な保存
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @request.json -o response.json
python - <<'PY'
import json
from save_image import extract_image, save_image
result = json.load(open("response.json"))
print(save_image(extract_image(result), "out.png"))
PY
維持する価値のある 2 つの習慣:実行ごとに新しいファイル名を書き込むことで、失敗や部分書き込みが良い結果を上書きしないようにする。保存後に出力サイズを検証する——HTTP 200 の成功でもサイズが予期しないものであれば、パラメータが効いていないことを意味し、これはパイプラインの 3 段階後よりもここで見つける方が簡単です。
よくある障害のデバッグ
初回実行の障害のほとんどは退屈なものです。このリストを順番に処理してください。大多数のケースをカバーします。
401 / 403 —— 認証
- キーはコマンドを実行している同じシェルに読み込まれていますか?
echo $HIAPI_API_KEYが空でない値を出力するはずです。 - ヘッダーは正確に
Authorization: Bearer <key>ですか——スペースとBearerという単語を含めて? - キーがヘッダーではなく URL や JSON ボディに入っていませんか?元に戻してください。
- キーは画像モデルに限定されていますか?ある製品領域で有効なキーがこのエンドポイントには適用されない場合があります。
404 —— モデルまたはルートが見つからない
これはほぼ常にモデル ID の問題です。公開されている識別子 recraft/creative-upscale と 1 文字ずつ比較してください。スラッシュ、小文字、creative-upscale 内のハイフンがすべて重要です。関連する落とし穴はクライアントによる URL エスケープです。リクエストラインに recraft%2Fcreative-upscale が表示され、呼び出しが 404 になる場合、HTTP レイヤーがスラッシュをエンコードしています。パスセグメントに触れないように設定してください。
また、パスプレフィックスを重複させていないことも確認してください(例えば、ベース URL がすでにバージョンセグメントで終わっているのに、パスでそれを繰り返している場合)。ベース URL に 1 つの変数を使えば、これは簡単に発見できます。
400 —— リクエストは理解されたが拒否された
推測せずにメッセージを読んでください。一般的な原因:
- 画像入力の形式エラー。 切り詰められた base64(シェル変数が切り詰められた場合、またはモードが完全な data URI を期待しているのに
data:image/png;base64,プレフィックスが欠けている場合がよくあります)、または公開取得できない URL。 - パラメータが範囲外または誤った位置。 モデルが受け入れない倍率、または
upscaleがparameters内ではなくトップレベルに送信されている。 - Content-Type の欠如。
Content-Typeがtext/plainまたは完全に欠けていると、JSON ボディが解析不能なドキュメントになります。
413 / 422 / タイムアウト —— サイズと時間
非常に大きなソース画像は、モデルが実行される前に検証で失敗する可能性があります。入力を適度に縮小して再試行し、フル解像度ファイルを送信する前にリクエストの形が妥当であることを確認してください。タイムアウトについては、遅いと失敗を区別してください。クライアントのタイムアウトを 1 回増やし、その後に呼び出しが成功するなら、修正はペイロードではなくクライアント設定にあります。
迅速なトリアージのルール
エラーが認証、モデル、または入力形式に言及している場合、アップサンプリングロジックにはまったく到達していません。クリエイティブや倍率の値はまだ関係ありません。ラッパーを修正し、可能な限り最小のリクエスト(小さなテスト画像、デフォルトパラメータ)で再試行してから、設定の変更を始めてください。この順序でデバッグすることで、壊れたヘッダーをパラメータの調整で補おうとする典型的な間違いを防げます。
再現可能な比較テストの構築
クリエイティブ・アップサンプリングは判断に大きく依存するため、記憶ではなく固定装置を使ってください。目標は、「この設定は本当に役立つのか?」という問いに、古いファイルを目視で再確認することなく答えられる小さなテストハーネスです。
入力の固定
- 1 枚のテスト画像をバージョン管理にチェックイン。 復元可能なディテールのあるもの——布地、植生、建物のエッジ——を選んでください。スクリプトの隣にコミットし、すべての実行とチームメンバーが同じソースを使うようにします。
- パラメータの固定。 倍率とクリエイティブ値は、頭の中やチャットメッセージではなく、スクリプト内のリストに存在させます。
- モデル ID の固定。 リクエストヘッダーのチェックリストと同じ理由で、
recraft/creative-upscaleを 1 回だけ 1 つの定数に綴ります。
最小限のマトリックスランナー
import itertools, json, pathlib
FACTORS = [2, 4]
CREATIVITY = ["preserve", "regenerate"] # ドキュメントで正確に受け入れられている値を使用
src = as_data_uri("fixtures/test-input.png")
out_dir = pathlib.Path("runs"); out_dir.mkdir(exist_ok=True)
for factor, mode in itertools.product(FACTORS, CREATIVITY):
result = creative_upscale(src, upscale=factor, creativity=mode)
name = f"f{factor}-{mode}"
save_image(extract_image(result), out_dir / f"{name}.png")
(out_dir / f"{name}.json").write_text(json.dumps(result, indent=2))
print(name, "ok")
コードよりも重要な 2 つの詳細。第一に、生の JSON レスポンスを各画像の隣に保存する——結果がおかしいとき、レスポンスはパラメータが適用されたか黙って無視されたかを教えてくれます。第二に、パラメータ値からファイルに名前を付ける——そうすればディレクトリ一覧がマトリックスになり、どのファイルがどの設定から来たかを疑う必要がなくなります。
固定された方法で比較する
- 出力は想定される表示サイズで見てください。ズームして見るのではありません。400% で印象的なクリエイティブのディテールは、ユーザーが実際に見るサイズでは不自然に見える可能性があります。
- 実行の一環としてプログラムでサイズをチェックする。不一致は倍率が効いていないことを意味し、美学の問題ではなく、自分のリクエストに対するバグレポートです。
- 定義された基準で判断してください。ソースへの忠実度か知覚的なシャープさかで、アセットのカテゴリに応じて選びます。その基準をマトリックスの隣に書いておけば、次の人が「より良い」の意味を理解できます。
マトリックスが安定したら、ハーネスはリグレッションテストになります。クライアントコードを変更するたびに再実行し、以前の実行ディレクトリと比較してください。このガイドのすべての呼び出しはプラットフォームの他の画像エンドポイントと同じリクエスト形態を共有しているため、ここで構築したランナーは次に統合するどのモデルにも一般化できます。
関連記事
すべての記事を見る →-
チュートリアル
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 チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする