cURL · バーチャルtry-on API
バーチャルtry-on API cURL の場合
要約
PHOTTA_API_KEYをエクスポートし、ドキュメントに記載されたJSONボディで https://api.photta.app/api/v1/api/v1/tryon/apparel にPOSTし、生成IDを取得します。その後、data.statusがcompletedになるまで3秒ごとに /api/v1/tryon/apparel/{id} に対してGETをループします。jqと組み合わせて出力URLを抽出してください。
- 所要時間の目安: 1.5–4 min
- Credits: 2Kで5 credits · 4Kで6 credits
- 処理方式: 非同期、ポーリング
- 制限: 600 リクエスト/分
- 認証: Bearerキー
このページに記載されている数値はすべて以下に基づきます: Photta APIドキュメント · 確認済み
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')
# $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed".
for i in $(seq 1 120); do
RESULT=$(curl -s "https://api.photta.app/api/v1/tryon/apparel/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.data.status')
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "generation failed" && exit 1
sleep 3
done
echo "$RESULT" | jq -r '.data.output_url'const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": true,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
}),
});
const { data } = await res.json(); // data.id, data.status
async function waitFor(id) {
for (let attempt = 0; attempt < 120; attempt++) {
const res = await fetch(`https://api.photta.app/api/v1/tryon/apparel/${id}`, { headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` } });
const { data } = await res.json();
if (data.status === "completed") return data.output_url;
if (data.status === "failed") throw new Error(data.error_message ?? "generation failed");
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("timed out after 6 minutes");
}import os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_type": "top",
"product_images": [
"https://cdn.yourstore.com/products/shirt-front.jpg"
],
"product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
"product_category": "t_shirt",
"mannequin_id": "mnk_f3a9b1",
"pose_id": "pose_c2d4e5",
"background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
"lock_background": True,
"resolution": "2K",
"aspect_ratio": "3:4",
"body_size": "M",
"expression": "neutral",
"user_instruction": "Keep the collar pattern crisp and centered."
},
)
data = res.json()["data"] # data["id"], data["status"]
import time
def wait_for(job_id):
for _ in range(120):
res = requests.get(f"https://api.photta.app/api/v1/tryon/apparel/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"})
data = res.json()["data"]
if data["status"] == "completed":
return data["output_url"]
if data["status"] == "failed":
raise RuntimeError(data.get("error_message", "generation failed"))
time.sleep(3)
raise TimeoutError("timed out after 6 minutes")概要
概要
- エンドポイント
- POST /api/v1/tryon/apparel
- 認証
- Bearer APIキー
- 処理方式
- 非同期 — ステータスエンドポイントをポーリング
- 所要時間の目安
- 1.5–4 min
- Credits
- 2Kで5 credits · 4Kで6 credits
- アスペクト比
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- 入力制限
- 1画像あたり最大10 MB、JPEG, PNG, WebP
- 冪等性
- なし
仕組み
シェルでの5ステップ、curlとjq以外の依存関係はありません。
ステップ 1
登録してキーを生成
ai.photta.app にアクセスし、Developersタブを開いて「Generate API key」をクリックします。本番キーは `photta_live_` で始まります。
ステップ 2
キーをエクスポート
以降のすべてのcurl呼び出しで自動的に読み込まれるよう、シェルのプロファイルまたは `.envrc` ファイルに `export PHOTTA_API_KEY="photta_live_xxx"` を設定します。
curl --version # macOS, Linux, WSL and Windows 10+ ship it export PHOTTA_API_KEY="photta_live_xxxxx"ステップ 3
ベースURLを固定
`export PHOTTA_BASE_URL="https://api.photta.app/api/v1"` を設定することで、curlコマンドを簡潔に保てます。
export PHOTTA_BASE_URL="https://api.photta.app/api/v1" export AUTH_HEADER="Authorization: Bearer $PHOTTA_API_KEY"ステップ 4
送信とポーリング
`$PHOTTA_BASE_URL/api/v1/tryon/apparel` に POST して ID を取得し、3 秒ごとに `curl $PHOTTA_BASE_URL/api/v1/tryon/apparel/{id}` をループします。レスポンスを jq にパイプして `.data.status` をクリーンに抽出します。
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \ -H "Authorization: Bearer $PHOTTA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product_type": "top", "product_images": [ "https://cdn.yourstore.com/products/shirt-front.jpg" ], "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg", "product_category": "t_shirt", "mannequin_id": "mnk_f3a9b1", "pose_id": "pose_c2d4e5", "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg", "lock_background": true, "resolution": "2K", "aspect_ratio": "3:4", "body_size": "M", "expression": "neutral", "user_instruction": "Keep the collar pattern crisp and centered." }') ID=$(echo "$RESPONSE" | jq -r '.data.id') # $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed". for i in $(seq 1 120); do RESULT=$(curl -s "https://api.photta.app/api/v1/tryon/apparel/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY") STATUS=$(echo "$RESULT" | jq -r '.data.status') [ "$STATUS" = "completed" ] && break [ "$STATUS" = "failed" ] && echo "generation failed" && exit 1 sleep 3 done echo "$RESULT" | jq -r '.data.output_url'ステップ 5
結果の保存
ジョブが完了したら、jq で `.data.output_url` を抽出し、`curl -o` でバイトデータをローカルストレージに保存します。これで次のパイプラインステップの準備は完了です。
エラー
- 400
invalid_request_error - The request is malformed or contains invalid parameters.
- 401
authentication_error - The API key is missing, invalid, or expired.
- 402
insufficient_credits_error - Your account does not have enough credits.
- 404
not_found_error - The requested resource does not exist.
- 409
conflict_error - The request conflicts with current state — e.g. your concurrent-batch cap is reached.
- 429
rate_limit_error - Too many requests. Slow down and retry.Retry-After: 30
- 500
api_error - An internal server error occurred. Retry later.
case "$STATUS_CODE" in
402) echo "insufficient_credits_error — top up before retrying" ;;
429) echo "rate_limit_error — wait the Retry-After seconds (30 by default)" ;;
4??) echo "$BODY" | jq '.error.type, .error.message' ;;
5??) echo "api_error — retry with backoff" ;;
esac制限
- APIキーごとに毎分600リクエスト (固定ウィンドウ方式。制限値はすべてのプランで共通です)
- 429にはRetry-After: 30 secondsが含まれます
- 1画像あたり最大10 MB
- フォーマット: JPEG, PNG, WebP
- プランごとの同時実行バッチ数: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- ポーリングのみ — APIはWebhookを送信しません。
API の検証に cURL が依然として最速である理由
- インストール不要 — cURL はすべての主要 OS に標準搭載
- スクリプト化されたパイプライン(CI、cron、シェルフック)向けに jq と連携
- コードに組み込む前にエンドポイントをスモークテストする最速の方法
- このページのすべてのコマンドは、任意の POSIX シェルにそのまま貼り付け可能
できないこと
- ポーリングループがターミナルをブロックします — 並行ワーカーを動かす場合は Node または Python に移行してください
- 完了を検知する手段はポーリングのみです。API は webhook を送信しません
- Windows コマンドプロンプトのユーザーは、WSL または PowerShell の curl.exe を実行してください
開発者からのよくある質問
Photta の CLI ツールはありますか?
まだありません — ですが、cURL と 15 行の bash ラッパーがあればほぼ事足ります。どの言語でもサブプロセスを実行でき、シェルが CI パイプラインにおける共通項であるため、ドキュメントでは cURL ファーストの例を優先しています。
API を使用するには jq が必要ですか?
厳密には不要です — ですが、スクリプト化されたパイプラインを組むなら導入を強く推奨します。jq を使えば、手作業で解析することなく JSON レスポンスから `.data.id`、`.data.status`、`.data.output_url` を抽出できます。macOS では `brew install jq`、Debian/Ubuntu では `apt install jq` でインストールしてください。
curl で認証するにはどうすればよいですか?
すべてのリクエストに `-H "Authorization: Bearer $PHOTTA_API_KEY"` を追加します。キーは環境変数に保持し、コミットするスクリプト内にインラインでハードコードしないでください。`curl --oauth2-bearer` も使用できますが、明示的なヘッダー形式のほうがドキュメントやログでの可読性に優れています。
本番環境で curl ベースのスクリプトを使用できますか?
単発のバッチバックフィルや cron ジョブであれば可能です — 実際に何千ものチームがこの方法でカタログのバックフィルを実行しています。ただし、常駐アプリケーションの場合は、適切なエラー処理、リトライ、可観測性を確保できる本格的なプログラミング言語の使用が適しています。Node や Python に移植した後も、リクエストの形式は同一であるため、このページの curl の例はそのまま参考になります。
bash ループからポーリングするにはどうすればよいですか?
ループ本体内でステータスチェックを行う `for i in $(seq 1 120); do … ; sleep 3; done` を使用します。`.data.status` が `completed` または `failed` になったらブレークします。このページのコードサンプルには、ジョブ停止時にスクリプトが無限ハングしないよう厳格な上限を設けた実装パターンが示されています。
curl でエラーレスポンスを読み取るにはどうすればよいですか?
`curl -w "\n%{http_code}"` を使用して、JSON ボディと一緒に HTTP ステータスコードを取得します。ステータスに応じて分岐処理を行います。credits 不足は 402、レートリミットは 429(Retry-After の値を遵守)、一時的なサーバーエラーは 5xx です。エラーボディには常に `error.code` フィールドと `error.message` フィールドが含まれます。
関連ページ
Node.js
Node.jsでのバーチャルtry-on API
ネイティブのfetchを使用してNode.jsバックエンドからPhottaのバーチャルtry-on APIを呼び出します。SDKは不要です。キーを保存し、ジョブを送信して、結果をポーリングするだけです。
読むPython
Python での バーチャルtry-on API
requests ライブラリを使用して Python で Photta の バーチャルtry-on API を呼び出します。30行のラッパーで、httpx による非同期対応も可能であり、Django、FastAPI、Celery で動作します。
読む機能一覧
バーチャルtry-on API アパレル向け
AIマネキンにアパレルを着せるREST API。非同期処理、生成時間は1.5〜4分、2Kで5クレジット、4Kで6クレジット。cURL、Node.js、Pythonのサンプルコードあり。
読む実装
アプリ向けのバーチャル try-on 機能を構築する
Photta API を使ったバーチャル try-on 機能リリースのためのエンドツーエンド実装レシピ:アップロード、ジョブ送信、ワーカーからのポーリング、結果のレンダリング。TypeScript + サーバー専用パターン。
読む実装
iOSまたはAndroidアプリにバーチャルtry-onを追加する
Photta APIを使用してネイティブのiOSまたはAndroidアプリにAIバーチャルtry-onを追加する方法:キーをデバイスに絶対に含めず、バックエンド経由でプロキシし、ジョブステータスをミラーリングします。
読むクイックスタート
5 分以内に最初の Photta 画像を生成。
サインアップ、API キーの生成、最初の cURL 呼び出しの実行、完了までのポーリング、結果の保存。エンドツーエンドで文書化された 5 つのステップ。
読むリファレンス
Photta API の料金体系
Photta APIの各endpointにおける2Kおよび4Kでのcredits消費量、請求と返金の仕組み、無料のendpoint一覧。画像単位の金銭的価格設定はありません。
読む
このページに記載されている数値はすべて以下に基づきます: Photta APIドキュメント · 確認済み
5分でAPIを試す
Photta APIキーを生成し、上記のcURLスニペットを貼り付ければ、コーヒーが淹れ終わる前に最初のモデル着用画像が手に入ります。
- 1.5–4 min
- 2Kで5 credits · 4Kで6 credits
- 非同期、ポーリング
- 600 リクエスト/分
- Bearerキー