ドキュメントキーの 作成 から 最初の クリップ まで
最初の生成に必要なすべて:キー、1つのリクエスト、ジョブ、そしてWebhook。
開発者APIは申請制です。
概要
HTTPS経由のRESTで、入出力はJSONです。すべての生成は非同期です。
- ベースURL
https://api.pershot.app/v1- 認証
- Authorization: Bearerの後にキーを付けます。キーはsk_test_またはsk_live_で始まり、1回だけ表示されます。当社はハッシュのみを保存します。
- キーの権限
- 各キーにはスコープがあり、スタジオで設定した場合はモデルとツールの許可リストもあります。許可リストのあるキーは、リストにあるもの(ツールを含む:画像のアップスケール、背景除去、高画質化、リップシンク、アウトペイント、画像エディター)しか使えません。それ以外には403 forbidden_modelが返されます。高画質化で1080pや4Kにするには、動画モデルと高画質化の両方が必要です。
- エラーの形式
{ "error": { "code", "message", "param", "request_id" } }- ID
- 種類ごとの接頭辞が付きます:job_、qt_、key_、up_。
- OpenAPI
- /api/v1/openapi.json
- AIエージェント向け
- AIエージェント向けのテキスト:入力、指定できる値、設定ごとの価格、リクエスト例
seedance-2.0-fastseedance-2.0-miniqwen-image-2512-lightningqwen-image-2512qwen-image-edit-2511-lightningqwen-image-edit-2511
実際の生成はまだ公開されていません。モデルのページでメールアドレスを残していただければ、公開時に一度だけご連絡します。
クイックスタート
4つのステップと、それぞれで表示されるはずのレスポンス。
- 01
キーを
取得 開発者APIは申請制です。スタジオの「APIキー」から申請してください。利用できるようになったら、そこでキーを作成してすぐにコピーします。キー全体が表示されるのは1回だけです。
export API_KEY="sk_test_…" - 02
リクエストを
送信 Idempotency-Keyとmax_creditsの上限を付けてショットをPOSTします。すぐに202と待機中のジョブが返り、クレジットが保留されます。
curl https://api.pershot.app/v1/videos/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0-fast", "prompt": "Perfume mist in hard side light. Slow push-in, black background, grain.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "max_credits": 34 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": null } - 03
ジョブを
確認 statusがsucceededになるまでジョブをGETします。出力のURLは署名付きで期限があるため、残したいものはダウンロードしてください。
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "succeeded", "money_status": "settled", "requested_model": "seedance-2.0-fast", "resolved_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": 34, "outputs": [ { "kind": "video", "url": "https://…/job_01J9ZK4T8W.mp4?sig=…", "width": 1280, "height": 720, "duration_s": 5 } ], "error": null } - 04
Webhookを
受信 webhook_urlを渡すと、状態が変わるたびにタイムスタンプ付きの署名を添えてPOSTします。2xxで応答してください。失敗した配信はバックオフしながら再試行されます。
{ "id": "evt_01J9ZKB1QX", "type": "job.succeeded", "created_at": "2026-09-29T14:02:31Z", "data": { "job": { "id": "job_01J9ZK4T8W", "object": "job", "status": "succeeded", "money_status": "settled", "credits_charged": 34, "outputs": [ { "kind": "video", "url": "https://…/job_01J9ZK4T8W.mp4?sig=…", "width": 1280, "height": 720, "duration_s": 5 } ] } } }
エンドポイント
すべてのパスはベースURLからの相対パスです。
| メソッド | パス | 内容 |
|---|---|---|
| GET | /v1/models | アカウントで利用できるモデル、機能、ステータス |
| GET | /v1/pricing | 公開価格。ログイン時はアカウントの価格 |
| POST | /v1/quotes | 計画、内訳、最大課金額、有効期限(10分) |
| POST | /v1/videos/generations | 動画の生成。202とジョブを返す |
| POST | /v1/images/generations | 画像の生成または編集。202とジョブを返す |
| GET | /v1/jobs/{id} | ステータス、署名付きリンクとしての出力、実際の費用 |
| GET | /v1/jobs | ジョブの一覧(新しい順) |
| POST | /v1/jobs/{id}/cancel | キャンセルを要求。モデルがすでにジョブを受け付けていない限り、保留したクレジットは返金されます |
| GET | /v1/balance | 種類別の利用可能なクレジットと保留中のクレジット |
| GET | /v1/usage | 日別またはモデル別の使用状況(JSONまたはCSV) |
| POST | /v1/uploads | 10 MBまでのJPEG、PNG、WebPをアップロード |
見積 もりと 上限
すべての生成には、quote_idかmax_creditsの上限のどちらか一方が必要で、両方は指定できません。quote_idの場合はその見積もりで実行され、max_creditsの場合は価格が上限以下のときにのみ実行されます。
model: "auto"には常にmax_creditsが必要です。見積もりの有効期間は10分で、それを過ぎるとquote_expiredが返されます。
べき 等性
すべての生成リクエストに、Idempotency-Keyヘッダー(表示可能なASCII文字で1〜255文字)を付けて送信してください。
24時間以内に同じキーを送ると、202ではなくHTTP 200で同じジョブが返されるため、タイムアウト後に再試行しても、2つ目のジョブが作成されたり課金されたりすることはありません。
Webhook
生成(または一括生成)でwebhook_urlを渡すと、状態の変化を受信できます。各イベントはPOSTで、JSONのボディにはid、type、created_at、dataが含まれます:ジョブのイベントではdata.job、batch.completedではdata.batchです。
イベント
job.queuedjob.processingjob.succeededjob.failedjob.cancelledbatch.completed
- 各配信には、イベントID、タイムスタンプ、署名が付きます。ボディを信頼する前に検証してください。
- エンドポイントが10秒以内に2xxで応答すると、配信は完了とみなされます。それ以外の場合は、1 min、5 min、30 min、2 h、6 hの後に再試行され、その後失敗として記録されます。サポートが再送することもできます。リダイレクトには従いません。
- WebhookのURLはhttpsである必要があります。プライベート、ループバック、予約済みのアドレスのホストは、送信時にも接続時にも拒否されます。
ヘッダー
X-Signaturet=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>X-Event-Id- イベントIDで、ボディにも含まれます。再試行や再送でも同じIDが使われるため、保存しておき、処理済みのIDはスキップしてください。
- 署名シークレット
- アカウントごとに1つのwhsec_…シークレットで、スタジオの「APIキー」にあります。HMACの鍵は、接頭辞を含むシークレット全体です。
- ローテーション
- ローテーション後の24時間は、古いシークレットも2つ目のv1エントリーとして署名を続けます。いずれかのv1が一致すれば配信を受け付けてください。
再シリアライズしたコピーではなく生のボディに対してHMACを計算し、定数時間で比較して、5分より古いタイムスタンプは拒否してください。
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.エラー
コードとHTTPステータスは固定です。メッセージは人が読むためのものです。
| コード | HTTP | 発生条件 |
|---|---|---|
invalid_request | 400 | フィールドが欠けているか、範囲外 |
unauthorized | 401 | キーがない、取り消されたキー、または不正な署名 |
insufficient_credits | 402 | 残高が保留額に足りない |
forbidden_model | 403 | キーの許可リストにこのモデルまたはツールが含まれていない |
region_not_supported | 403 | お住まいの地域ではこのモデルが提供されていない |
developer_api_closed | 403 | 開発者APIが開いていないときの開発者キー。利用は申請制 |
member_connections_paused | 403 | ご自身のAIエージェントの接続を一時停止している間の会員ログイン(MCP、接続コード、コマンドライン) |
not_found | 404 | アカウントに該当するジョブ、見積もり、アップロードがない |
quote_expired | 409 | 見積もりが10分より古い |
price_changed | 409 | 価格が上限を超えた |
content_rejected | 422 | コンテンツが拒否された(課金なし) |
rate_limited | 429 | このキーのリクエストが多すぎる |
concurrency_limited | 429 | このアカウントで実行中のジョブが多すぎる |
internal_error | 500 | 当社側で問題が発生した |
upstream_unavailable | 503 | モデルが利用できない(後で再試行) |
モデルの結果が不確定な場合はエラーではありません:ジョブはstatusとしてunknownを返し、再送信の前に確認が行われます。
制限
- リクエスト
- デフォルトでキーごとに毎分60。
- 同時実行数
- デフォルトでアカウントごとに同時3ジョブ。引き上げは申請してください。
- 上限
- モデルの処理能力が絶対的な上限です。キーを増やしても同時実行数は増えません。
画像
POST /v1/images/generationsも同じヘッダーを受け取ります。ティアと操作に応じてモデルIDを選びます。編集モデルにはimage_urlも必要で、生成モデルはimage_urlを受け付けません。
| ティア | 生成 | 編集 |
|---|---|---|
| Image Miniエコノミー · 試作 | qwen-image-2512-lightning | qwen-image-edit-2511-lightning |
| Image Fastおすすめ | qwen-image-2512 | qwen-image-edit-2511 |
モデル 別の 制限
各モデルのAPIページに、値、単位、確認する側、超えた場合の挙動をまとめた完全な表があります。GET /v1/modelsは同じ制限をJSONで返します。
- 当社が確認当社が確認し、見積もりや保留の前に400を返します。
- 提供元が確認仕入れ先が確認します。拒否されたジョブは失敗となり、課金されません。
- 推奨誰も確認しません。範囲内に収めると、より良い結果が得られます。
| モデル | 主な制限 | 完全な表 |
|---|---|---|
seedance-2.0-fastSeedance 2.0 Fast | プロンプト2〜2,000文字 · 4〜15 s · 参照画像最大9枚 · 画像は1辺300〜6,000 px | 表を開く |
seedance-2.0-miniSeedance 2.0 Mini | プロンプト2〜2,000文字 · 4〜15 s · 参照画像最大9枚 · 画像は1辺300〜6,000 px | 表を開く |
qwen-image-2512Qwen-Image-2512 | プロンプト2〜2,000文字 · 1Kまたは2K · 元画像なし | 表を開く |
qwen-image-2512-lightningQwen-Image-2512 · Lightning 4-step | プロンプト2〜2,000文字 · 1Kまたは2K · 元画像なし | 表を開く |
qwen-image-edit-2511Qwen-Image-Edit-2511 | プロンプト2〜2,000文字 · 1Kまたは2K · 元画像1枚(JPEG、PNG、WebP、最大10 MB) | 表を開く |
qwen-image-edit-2511-lightningQwen-Image-Edit-2511 · Lightning | プロンプト2〜2,000文字 · 1Kまたは2K · 元画像1枚(JPEG、PNG、WebP、最大10 MB) | 表を開く |
アップロード
POST /v1/uploadsは、ファイルの中身から形式を判定します。アップロードリンクの有効期間は7日です。
| ファイル | 形式 | 最大サイズ | 最大の長さ |
|---|---|---|---|
| 画像:開始フレーム、参照、編集の元画像 | JPEG, PNG, WebP | 10 MB | – |
| 動画:リップシンク | MP4 | 50 MB | 60 s |
| 音声:リップシンク | MP3, WAV, M4A | 10 MB | 60 s |
当社は他のホストから画像を取得しないため、そうしたリンクのサイズは仕入れ先が確認します。仕入れ先が拒否したジョブには課金されません。 同じ制限はJSONでも取得できます:GET /v1/modelsは、すべてのモデルについてlimitsオブジェクトを返します。
fal・Replicate・WaveSpeed からの 移行
ベースURLとキーを変えるだけでは足りません:すべてのリクエストで、ボディのモデルID、Idempotency-Keyヘッダー、価格の上限(max_creditsまたはquote_id)も必要です。移行ガイドでは、Seedance 2.0とQwen-Imageのすべてのフィールドを対応付け、そのまま引き継げないものを一覧にしています。