Node.js · ゴーストマネキン API
ゴーストマネキン API Node.js
要約
環境変数にPHOTTA_API_KEYを設定し、https://api.photta.app/api/v1向けにBearerキーを含むシンプルなfetchヘルパーを作成して/api/v1/ghost-mannequinにPOST後、ステータスがcompletedになるまで3秒ごとに/api/v1/ghost-mannequin/{id}をポーリングします。
- 所要時間の目安: 1.5–4 min
- Credits: 2Kで4 credits · 4Kで5 credits
- 処理方式: 非同期、ポーリング
- 制限: 600 リクエスト/分
- 認証: Bearerキー
このページに記載されている数値はすべて以下に基づきます: Photta APIドキュメント · 確認済み
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/ghost-mannequin \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}')
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/ghost-mannequin/$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/ghost-mannequin", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}),
});
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/ghost-mannequin/${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/ghost-mannequin",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
},
)
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/ghost-mannequin/{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/ghost-mannequin
- 認証
- Bearer APIキー
- 処理方式
- 非同期 — ステータスエンドポイントをポーリング
- 所要時間の目安
- 1.5–4 min
- Credits
- 2Kで4 credits · 4Kで5 credits
- アスペクト比
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- 入力制限
- 1画像あたり最大10 MB、JPEG, PNG, WebP
- 冪等性
- なし
仕組み
サインアップから最初の画像生成まで、5ステップで約5分。
ステップ 1
サインアップしてキーを生成
ai.photta.appでアカウントを作成します。ダッシュボードのDevelopersセクションを開き、APIキーの生成をクリックして本番キーを取得します。キーは`photta_live_`で始まり、その後に32文字の16進数が続きます。
ステップ 2
キーはソースコードではなく環境変数に保存
`.env`(またはプラットフォームのシークレット管理)に`PHOTTA_API_KEY=...`を追加し、`process.env`経由で読み込みます。キーをコミットしたり、`'use client'`とマークされたファイルにインポートしたりしないでください — バンドラによってブラウザ側に露出してしまいます。
node --version # 18 or later ships fetch echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .envステップ 3
軽量な fetch ヘルパーを作成する
`fetch()` をラップする20行のコード1つで、ベース URL、Authorization ヘッダー、JSON ボディ、およびエラーの正規化を処理できます。公式 SDK がリリースされるまでは、この抽象化だけで十分です。
// photta.js — one helper for every endpoint const BASE = "https://api.photta.app/api/v1"; export async function photta(path, init = {}) { const res = await fetch(BASE + path, { ...init, headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json", ...(init.headers ?? {}) } }); const body = await res.json(); if (!res.ok) throw Object.assign(new Error(body.error?.message ?? res.statusText), { status: res.status, retryAfter: res.headers.get("Retry-After"), body }); return body; }ステップ 4
try-on を送信してポーリングする
ドキュメント記載のサンプルボディを使用して `/api/v1/ghost-mannequin` に POST します(以下のコードには全フィールドが含まれています)。API は即座に生成 ID を返します。`status === 'completed'` になるまで、3秒ごとに `/api/v1/ghost-mannequin/{id}` をポーリングしてください。
const res = await fetch("https://api.photta.app/api/v1/ghost-mannequin", { method: "POST", headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "product_image": "https://cdn.yourstore.com/products/jacket-front.jpg", "back_image": "https://cdn.yourstore.com/products/jacket-back.jpg", "image_side": "front", "angle": "side", "style": "3d", "background_color": "white", "resolution": "2K", "aspect_ratio": "3:4", "user_instruction": "closed front, cream interior lining", "brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67" }), }); 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/ghost-mannequin/${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"); }ステップ 5
結果を永続化する
完了時のペイロードには `output_url` と `thumbnail_url` が含まれます。バイトデータを一度 fetch して自前のオブジェクトストレージに保存してください。URL は永続的ですが、レンダリングを Photta の CDN に依存させるべきではありません。
エラー
- 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.
try {
await photta("/ghost-mannequin", { method: "POST", body: JSON.stringify({
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}) });
} catch (err) {
if (err.status === 402) console.error("insufficient_credits_error: top up before retrying");
else if (err.status === 429) await new Promise((r) => setTimeout(r, Number(err.retryAfter ?? 30) * 1000));
else throw err;
}制限
- 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を送信しません。
現時点でヘルパーがクライアントライブラリより優れている理由
- Node 18+ はネイティブ fetch を標準搭載 — ランタイム依存関係なし
- 同じヘルパーが Next.js の Route Handlers、Server Actions、およびあらゆるワーカー内で動作
- API キーは環境変数に保持。バンドラーによる漏洩を防ぐため、'use client' モジュールからは絶対にヘルパーをインポートしないこと
- あらゆるキューや cron で動作: BullMQ、Inngest、Trigger.dev、Vercel Cron、Cloudflare Queues
対応していない事項
- 公式 @photta/node パッケージは未提供 — 現時点では REST が唯一の手段
- 完了通知はポーリングのみ — API は Webhook を送信しません
- Bearer キーのみ — OAuth クライアント認証情報フローはありません
開発者からのよくある質問
公式の Photta Node.js SDK はありますか?
まだありません。ドキュメント化されている方法は Node のネイティブ fetch による直接の REST 呼び出しです。このページのヘルパーが連携インターフェースのすべてであり、すべての機能で同様に機能します。
サポートされている Node.js のバージョンは?
ネイティブの `fetch` をサポートする環境 — つまり Node 18 以降です。Node 16 では `node-fetch` でポリフィルするか、アップグレードする必要があります。残りのコードはプレーンな ECMAScript 2020(async/await、テンプレートリテラル、動的インポート)であるため、その他のランタイム要件はありません。
Node からの認証方法は?
すべてのリクエストで `Authorization: Bearer photta_live_xxx` を送信します。キーは環境変数に設定し、`process.env` 経由で読み込んでください。ブラウザで実行されるファイルからは絶対にインポートしないでください。
生成待機の処理方法は?
生成エンドポイントは完全な非同期です。POST すると `status: 'processing'` とともに即座に生成 ID が返されます。`status` が `completed` または `failed` に変わるまで、3〜5秒ごとに `GET /api/v1/ghost-mannequin/{id}` をポーリングしてください。ジョブの停止によってリクエストがハングしないよう、試行回数には上限を設けてください。
Next.js 内から API を呼び出せますか?
はい — Route Handler(`app/**/route.ts`)、Server Action(`'use server'`)、または Middleware から呼び出せます。API キーはサーバー側に保持し、`'use client'` ファイルからヘルパーをインポートしないでください。Vercel の関数タイムアウトを超える長時間ジョブの場合は、ポーリングをキュー(Inngest、Trigger.dev、BullMQ)に委譲し、生成 ID をブラウザに返して独自のエンドポイントをポーリングさせてください。
API はどのようにエラーを通知しますか?
2xx 以外のレスポンスには、`error` オブジェクトを含む JSON ボディが付随します: `type`、`code`、`message`、およびサポート用のリクエスト ID です。代表的なケース: 不正なフィールドを示す `param` を伴う 400 invalid_request_error、`required` および `available` のカウントを示す 402 insufficient_credits、秒単位の `retry_after` と一致する Retry-After ヘッダーを伴う 429 rate_limit_exceeded です。5xx エラーは指数バックオフによる再試行が安全です。
関連ページ
Python
Python での ゴーストマネキン API
requests ライブラリを使用して Python で Photta の ゴーストマネキン API を呼び出します。30行のラッパーで、httpx による非同期対応も可能であり、Django、FastAPI、Celery で動作します。
読むcURL
cURLによるゴーストマネキン API
cURLを使用してシェルから直接Phottaのゴーストマネキン APIを呼び出します。送信、ポーリング、ダウンロード — すべてのスニペットはスクリプトパイプライン向けにjqと連携可能です。
読む機能一覧
ゴーストマネキン API ゴーストマネキン商品写真向け
AIゴーストマネキンエンドポイント。衣服写真からマネキンを除去し、内部のディテールを保持します。3Dまたは平置き、バッチ処理、2K で 4 credits。
読む実装
カタログのゴーストマネキン抽出を自動化する
夜間カタログ自動化のレシピ: 前日の製品更新を取得し、PhottaのゴーストマネキンAPIへバッチ送信、親バッチをポーリングして、データベースに永続化します。
読むクイックスタート
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で4 credits · 4Kで5 credits
- 非同期、ポーリング
- 600 リクエスト/分
- Bearerキー