# パイプライン

> REST でストーリー → 動画のパイプラインを開始し、各ステージを確認してゲートを承認し、監督とチャットして、完成したパイプラインをステージから分岐します。

Source: https://nodaro.ai/ja/docs/developers/api/pipelines

**パイプライン API** は、コードから**ストーリー → 動画**（Story → Video）を実行します。1 行のストーリーを送信すると、パイプラインエンジンが脚本を書き、キャスト、小道具、ロケーションを作成し、ショットを計画します。続けて、キーフレームをレンダリングし、音声付きで動画化して、映画を結合します。各ステージは、あなたの承認を待って停止することも、自動で進むことも、監督とのチャットを開くこともできます。

パイプラインは Nodaro Cloud でのみ動作します。Community エディションと Business エディションでは `403 edition_required` が返されます。セルフホスティング環境では、[**脚本生成**（Generate Script）](https://nodaro.ai/docs/nodes/video/generate-script)、[**画像生成**（Generate Image）](https://nodaro.ai/docs/nodes/image/generate-image)、[**動画生成**（Generate Video）](https://nodaro.ai/docs/nodes/video/generate-video)などのノードを使って、同じ手順をワークフローとして組み立てます。ルートにはベアラートークンが必要です。OAuth アプリのトークンには、以下に挙げるスコープが必要です。[認証](https://nodaro.ai/docs/developers/api/authentication)を参照してください。

## エンドポイント
| メソッド | パス | スコープ | 説明 |
| --- | --- | --- | --- |
| `POST` | `/v1/pipelines` | `pipelines:execute` | パイプラインを作成し、開始します。 |
| `GET` | `/v1/pipelines` | `pipelines:read` | 自分のパイプラインを、新しい順に一覧表示します。 |
| `GET` | `/v1/pipelines/:id` | `pipelines:read` | ステータス、現在のステージ、クレジットを取得します。 |
| `GET` | `/v1/pipelines/:id/events` | `pipelines:read` | パイプラインのイベントをストリーミングします（サーバー送信イベント）。 |
| `GET` | `/v1/pipelines/:id/stages/:stage` | `pipelines:read` | 1 つのステージのステータス、出力、クリティックのフィードバックを取得します。 |
| `GET` | `/v1/pipelines/:id/pending-approvals` | `pipelines:read` | 承認待ちのステージを一覧表示します。 |
| `GET` | `/v1/pipelines/:id/timeline` | `pipelines:read` | 組み立てられた映画を取得します。シーン、長さ、オーディオです。 |
| `GET` | `/v1/pipelines/:id/entities?type=` | `pipelines:read` | パイプラインのキャラクター、オブジェクト、ロケーション、またはシーンを一覧表示します。 |
| `POST` | `/v1/pipelines/:id/stages/:stage/approve` | `pipelines:approve` | ステージを承認します。任意で編集を加えられます。 |
| `POST` | `/v1/pipelines/:id/stages/:stage/reject` | `pipelines:approve` | フィードバックを付けて脚本を却下し、書き直させます。 |
| `POST` | `/v1/pipelines/:id/sub-gates/:gate/approve` | `pipelines:approve` | 動画化ステージの中のチェックポイントを承認します。 |
| `POST` | `/v1/pipelines/:id/sub-gates/:gate/reject` | `pipelines:approve` | そのチェックポイントを却下し、パイプラインを停止します。 |
| `POST` | `/v1/pipelines/:id/entities/:sceneId/helpers/accept_match_cut_break` | `pipelines:approve` | シーン画像ステージで、マッチカットの不連続を 1 件承認します。 |
| `POST` | `/v1/pipelines/:id/stages/:stage/chat` | `pipelines:approve` | 監督にメッセージを送信します（ガイド付きモード）。 |
| `GET` | `/v1/pipelines/:id/stages/:stage/chat` | `pipelines:read` | ステージのチャットを読み取ります。 |
| `POST` | `/v1/pipelines/:id/stages/:stage/chat/turns/:turnId/apply` | `pipelines:approve` | 監督が提案した変更を適用します。 |
| `POST` | `/v1/pipelines/:id/branch` | `pipelines:execute` | 完了したパイプラインをステージから再実行し、新しいパイプラインにします。 |
| `POST` | `/v1/pipelines/:id/fork` | `pipelines:execute` | パイプラインを停止し、そのキャンバスを通常のノードとして残します。 |
| `POST` | `/v1/pipelines/:id/cancel` | `pipelines:execute` | 実行中のパイプラインをキャンセルし、使われなかったクレジットを返還します。 |

## ステージとモード
パイプラインは、8 つのステージを順番に進みます。パスの `:stage` には、次のいずれかの名前が入ります。

| ステージ | 作られるもの |
| --- | --- |
| `script` | 構成案です。タイトル、シーン、キャスト、ロケーション、小道具です。 |
| `characters` | キャストの役ごとのキャラクターです。 |
| `objects` | ストーリーに必要な小道具です。 |
| `locations` | ストーリーに登場するロケーションです。 |
| `shot_list` | 各シーンのショットです。カメラと連続性の選択を含みます。 |
| `scene_images` | 各ショットのキーフレームです。 |
| `animate_audio_edit` | 動画化されたショットです。セリフ、ナレーション、音楽、編集を含みます。 |
| `post_merge` | 最終的に結合された映画です。 |

作成時に選ぶ `mode` によって、パイプラインを誰が先に進めるかが決まります。

| モード | 動作 |
| --- | --- |
| `manual`（デフォルト） | すべてのステージが `awaiting_approval` で停止します。承認、編集、却下のいずれかを行うと、パイプラインが先に進みます。 |
| `auto` | エンジンがすべてのステージを自分で実行します。クリティックが、脚本、キャスト・ロケーション・小道具の網羅性、キーフレームをチェックします。進行を止める判定が 3 回続くと、パイプラインは失敗し、使われなかったクレジットが返還されます。[マッチカットの不連続](#match-cut-breaks-in-the-scene-images-stage)があるときだけ停止し、すべての不連続が承認されるまで待機します。その間、status は `running` のままで、`pending-approvals` の一覧に `scene_images` ステージが含まれます。 |
| `guided` | `manual` と同じですが、`script` と `post_merge` のステージで監督とチャットできます。 |

## パイプラインを開始する
`POST /v1/pipelines` は、パイプラインを作成してクレジットを確保し、開始します。`{ id }` とともに `201` を返します。

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/pipelines \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
"root_node_id": "0e6b2f7c-4a1d-4c8e-9b3f-5d7a2c1e8f4b",
"story_prompt": "A lighthouse keeper must restart the light before the storm hits.",
"format": "short_film",
"target_duration_seconds": 60,
"mode": "auto",
"output_resolution": "720p"
}'
```

**TypeScript SDK**

```ts

const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})

const { id } = await client.pipelines.create({
root_node_id: crypto.randomUUID(),
story_prompt: 'A lighthouse keeper must restart the light before the storm hits.',
format: 'short_film',
target_duration_seconds: 60,
mode: 'auto',
})
```

```json
{ "id": "c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c" }
```

<TypeTable
type={{
story_prompt: { type: 'string', description: '映画の内容で、最大 4,000 文字です。', required: true },
format: { type: "'trailer' | 'short_film' | 'music_video' | 'reel' | 'commercial'", description: '映画の種類です。使える長さを決めます。', required: true },
target_duration_seconds: { type: 'integer', description: '映画の長さ（秒）で、format の範囲内である必要があります。最大 600 です。', required: true },
root_node_id: { type: 'string', description: 'パイプラインのルート用の id です。キャンバスのノードがパイプラインを開始したのではない場合は、新しい UUID など、任意の一意な id を送ってください。', required: true },
mode: { type: "'manual' | 'auto' | 'guided'", description: 'パイプラインを誰が先に進めるかです。', default: 'manual' },
output_resolution: { type: "'480p' | '720p' | '1080p' | '4K'", description: '完成した映画の解像度です。', default: '720p' },
language: { type: 'string', description: '脚本とセリフの言語です。', default: 'en' },
workflow_id: { type: 'string (uuid)', description: '映画を組み立てる、自分のワークフローです。' },
config: { type: 'object', description: '任意の切り替え項目です。music_enabled、narration_enabled、lipsync_enabled で、デフォルトはすべて true です。' },
max_cost_credits: { type: 'integer', description: 'パイプラインが使えるクレジットの上限です。' },
}}
/>

各 format には、使える長さの範囲があります。

| 形式 | 最短 | 最長 |
| --- | --- | --- |
| `reel` | 7 秒 | 90 秒 |
| `commercial` | 10 秒 | 90 秒 |
| `trailer` | 30 秒 | 180 秒 |
| `short_film` | 12 秒 | 600 秒 |
| `music_video` | 30 秒 | 600 秒 |

## パイプラインの進行を確認する
`GET /v1/pipelines/:id` は、パイプラインの状態を返します。数秒おきにポーリングするか、`GET /v1/pipelines/:id/events` を開いて、変化をサーバー送信イベントとして受け取ります。

```json
{
"id": "c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c",
"status": "running",
"current_stage": "scene_images",
"mode": "auto",
"spent_credits": 412,
"reserved_credits": 1180,
"upfront_credit_estimate": 1650,
"failure_reason": null,
"current_progress_message": "Rendering keyframe 5 of 9",
"branched_from_pipeline_id": null,
"branched_from_stage": null
}
```

`status` は、`queued`、`running`、`awaiting_approval`、`completed`、`failed`、`cancelled`、`forked` のいずれかです。`failure_reason` は、`failed` になったパイプラインの理由を説明します。

パイプラインが `completed` になると、`GET /v1/pipelines/:id/timeline` は、レンダリングしたり編集アプリに渡したりできるデータとして、映画を返します。

```json
{
"fps": 24,
"width": 1280,
"height": 720,
"scenes": [
{ "compositeUrl": "https://cdn.nodaro.ai/pipelines/scene-1.mp4", "durationSeconds": 8.5 },
{ "compositeUrl": "https://cdn.nodaro.ai/pipelines/scene-2.mp4", "durationSeconds": 11 }
],
"musicUrl": "https://cdn.nodaro.ai/pipelines/score.mp3",
"narrationUrl": "https://cdn.nodaro.ai/pipelines/narration.mp3"
}
```

動画化ステージの実行中は、timeline に `animateProgress`（`{ totalShots, shotsDone, percent }`）も含まれます。外部の編集アプリでカットを仕上げる方法については、[タイムラインを書き出す](https://nodaro.ai/docs/developers/api/studio-productions#export-a-timeline-to-an-editing-app)を参照してください。

**curl**

```bash
curl https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c \
  -H "Authorization: Bearer $NODARO_API_KEY"

curl https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c/timeline \
  -H "Authorization: Bearer $NODARO_API_KEY"
```

**TypeScript SDK**

```ts
const pipeline = await client.pipelines.get(id)
console.log(pipeline.status, pipeline.current_stage)

const timeline = await client.pipelines.getTimeline(id)
for (const scene of timeline.scenes) {
console.log(scene.compositeUrl, scene.durationSeconds)
}
```

## ステージを承認または却下する
`manual` モードと `guided` モードでは、各ステージが `awaiting_approval` で停止します。`GET /v1/pipelines/:id/pending-approvals` は、待機中のステージを一覧表示し、それぞれ `{ stage_name, output }` です。ステージの全体は `GET /v1/pipelines/:id/stages/:stage` で読み取り、`{ status, output, critic_feedback }` が返されます。

- **承認する**。`POST /v1/pipelines/:id/stages/:stage/approve` は `{ ok: true }` を返し、パイプラインが先に進みます。先にステージの出力を変更するには、`{ edits }` を送信します。承認の前に出力に適用される JSON Patch です。
- **却下する**。却下できるのは脚本だけです。`{ feedback }` を付けて `POST /v1/pipelines/:id/stages/script/reject` を呼び出すと、`{ ok: true }` が返され、エンジンはその内容を踏まえて脚本を書き直します。ほかのステージでは `400 stage_not_implemented` が返されます。脚本を却下できるのは最大 2 回で、脚本のクリティックによってすでに修正されている場合は、それより少なくなります。

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c/stages/script/approve \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "edits": [{ "op": "replace", "path": "/title", "value": "The Last Light" }] }'

curl -X POST https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c/stages/script/reject \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "feedback": "Make the story darker and more suspenseful." }'
```

**TypeScript SDK**

```ts
const approvals = await client.pipelines.pendingApprovals(id)
const { output } = await client.pipelines.getStage(id, 'script')

await client.pipelines.approveStage(id, 'script', [
{ op: 'replace', path: '/title', value: 'The Last Light' },
])
// or
await client.pipelines.rejectStage(id, 'script', 'Make the story darker and more suspenseful.')
```

### 動画化ステージの中のチェックポイント
`manual` モードと `guided` モードでは、`animate_audio_edit` ステージが、独自の 2 つのチェックポイントで停止することがあります。

- **`dialogue_recheck`**。このステージは、セリフの実際の長さを計画と比較し、シーンのタイミングを調整します。シーンが目標の 10% 以内に収まらない場合、ステージはあなたの承認を待ちます。
- **`silent_cut_preview`**。このステージは、音楽なしのカットのプレビューを組み立て、音楽を生成して料金が発生する前に、あなたの承認を待ちます。

`POST /v1/pipelines/:id/sub-gates/:gate/approve` はステージを再開し、`{ ok: true, gate, resumed_at }` を返します。`POST /v1/pipelines/:id/sub-gates/:gate/reject` は、ステージとパイプラインを失敗させ、使われなかったクレジットを返還します。`auto` モードでは、ステージは停止せずに続行します。

### シーン画像ステージでのマッチカットの不連続
`scene_images` ステージは、3 つ目のチェックポイントである `match_cut_break_pending` で停止することがあります。2 つのショットの間で計画したマッチカットが成立しない場合、`auto` を含むすべてのモードで、ここで停止します。ステージの出力の `match_cut_break_pending` に、該当するショットが列挙されます。

上のサブゲートのルートでは、このチェックポイントを解除できません。これらのルートは `400 invalid_sub_gate` を返し、エラーメッセージには、解除に使うルートが示されます。不連続は 1 件ずつ、`{ "shotId": "<shot id>" }` を付けて `POST /v1/pipelines/:id/entities/:sceneId/helpers/accept_match_cut_break` で承認します。`sceneId` は、そのショットを含むシーンの `id` で、`metadata.scene_id` ではありません。`GET /v1/pipelines/:id/entities?type=scene` はシーンを一覧表示し、各シーンのショットは `metadata.scene_node_data.shots` に含まれます。

不連続を承認するには `pipelines:approve` スコープが必要で、クレジットはかかりません。この呼び出しは `{ ok: true, pendingRemaining }` を返します。`pendingRemaining` は、まだ待機中の不連続の数です。最後の 1 件を承認すると、ステージが続行します。

## 監督とチャットする
`guided` モードでは、承認待ちのステージにチャットがあります。`POST /v1/pipelines/:id/stages/:stage/chat` に `{ message }` を付けて、最大 8,000 文字のメッセージを送信します。監督は 1 文で答え、変更を提案することもあります。

```json
{
"turnId": "f1a3c5e7-9b2d-4f6a-8c1e-3d5b7f9a2c4e",
"role": "assistant",
"content": "I moved the keeper's reason for staying into scene 2 and tightened the ending.",
"proposed_change": {
"change_type": "edit_artifact",
"json_patch": [{ "op": "replace", "path": "/scenes/1/description", "value": "The keeper finds his late wife's log and decides to stay." }]
}
}
```

`proposed_change` は、`null`、`json_patch` を持つ `edit_artifact`、または `from_stage` と `reason` を持つ `suggest_branch` のいずれかです。

| ステージ | 監督が提案できる内容 | ターン数 |
| --- | --- | --- |
| `script` | 構成案への編集（タイトル、シーン、キャスト、ロケーション、小道具に対する JSON Patch）、または、パッチを当てるには構造的すぎる変更の場合は分岐です。 | パイプラインごとに 20 |
| `post_merge` | 完成した映画の診断と、前のステージからの分岐です。映画自体にパッチを当てることはできません。 | パイプラインごとに 8 |

提案を受け入れるには、`POST /v1/pipelines/:id/stages/:stage/chat/turns/:turnId/apply` を呼び出します。`{ applied: true, attemptId, newOutput }` を返し、ステージを承認します。変更が構成案を壊す場合、たとえば、シーンでまだ使われているキャラクターを削除してしまう場合は、`{ applied: false, error }` が返され、監督が何を直せばよいかを説明するターンを追加します。有効ではない提案や、すでに待機中ではなくなったステージには、`409` が返されます。`GET /v1/pipelines/:id/stages/:stage/chat` は、会話全体である `{ turns }` を返します。

ガイド付きのパイプラインは、開始時にチャット用として 40 クレジットを追加で確保します。使わなかった分は返還されます。

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c/stages/script/chat \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Make the keeper'\''s motivation clearer in scene 2." }'
```

**TypeScript SDK**

```ts
const reply = await client.pipelines.chatStage(id, 'script', "Make the keeper's motivation clearer in scene 2.")
if (reply.proposed_change) {
const result = await client.pipelines.applyChatProposal(id, 'script', reply.turnId)
if (!result.applied) console.log(result.error.code)
}
```

## 完成したパイプラインを分岐する
`POST /v1/pipelines/:id/branch` は、`completed` になったパイプラインを 1 つのステージから再実行し、新しいパイプラインにします。`fromStage` より前のステージは承認済みとしてコピーされ、`fromStage` は実行を開始し、それ以降のステージは新しく作成されます。元のパイプラインは `completed` のままです。

分岐は、キャラクター、オブジェクト、ロケーションを新しいパイプラインにコピーしますが、画像ファイルは再利用するため、ファイルが重複することはありません。チャットは空の状態で始まります。

**curl**

```bash
curl -X POST https://app.nodaro.ai/v1/pipelines/c2f8a4e6-1b9d-4f3a-8c7e-6d2b9f1a5e3c/branch \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "fromStage": "scene_images" }'
```

**TypeScript SDK**

```ts
const branch = await client.pipelines.branch(id, { fromStage: 'scene_images' })
console.log(branch.pipelineId, branch.clonedStages)
```

このルートは、`{ pipelineId, clonedStages, clonedEntities }` とともに `201` を返します。新しいパイプラインの id、承認済みとしてコピーされたステージ、コピーされたキャラクター、オブジェクト、ロケーションの数です。`fromStage` には、上の表にあるどのステージ名でも指定できます。

## パイプラインをキャンセルまたはフォークする
- **キャンセルする**。`POST /v1/pipelines/:id/cancel` は、実行中のパイプラインを停止し、まだ実行されていない作業分の確保済みクレジットを返還して、`{ ok: true }` を返します。すでに完了、失敗、キャンセルのいずれかの状態になったパイプラインでは `409 already_terminal` が返され、何も変わりません。
- **フォークする**。`POST /v1/pipelines/:id/fork` は、キャンバスをパイプラインの管理から外します。パイプラインが作成したすべてのノードは、編集できる通常のノードになり、使われなかったクレジットが返還され、status は `forked` になります。フォークは元に戻せません。引き続きエンジンを使うには、新しいパイプラインを開始してください。

## クレジット
パイプラインは、開始時に見積もり額を確保します。`upfront_credit_estimate` に表示されます。`spent_credits` と `reserved_credits` は、実行の現在の状況を示します。キャンセルまたは失敗したパイプラインは、使わなかった分を返還し、`max_cost_credits` が合計の上限になります。[クレジット](https://nodaro.ai/docs/developers/api/credits)を参照してください。

## MCP と SDK から使う
SDK は、すべてのルートを `client.pipelines.*` としてラップしています。CLI にはパイプラインのコマンドはありません。AI アシスタントは、次の MCP ツールを使います。

| ツール | スコープ | 説明 |
| --- | --- | --- |
| `start_pipeline` | `pipelines:execute` | パイプラインを開始します。デフォルトの mode は `auto` です。 |
| `get_pipeline_status` | `pipelines:read` | ステータス、ステージ、クレジットを読み取ります。 |
| `pipeline_pending_approvals` | `pipelines:read` | 承認待ちのステージを一覧表示します。 |
| `chat_pipeline_stage`、`apply_chat_proposal` | `pipelines:approve` | 監督とチャットし、提案を適用します。 |
| `get_pipeline_stage_chat` | `pipelines:read` | ステージのチャットを読み取ります。 |
| `branch_pipeline` | `pipelines:execute` | 完了したパイプラインを分岐します。 |

アシスタントから映画をガイド付きで監督する方法については、[Film Director](https://nodaro.ai/docs/mcp/film-director) を参照してください。

## エラー
| ステータス | コード | 意味 |
| --- | --- | --- |
| `400` | `validation_error` | ボディが無効です。たとえば、長さが 5 秒未満または 3,600 秒超の場合や、分岐の `fromStage` がステージ名ではない場合です。 |
| `400` | `duration_out_of_bounds` | 長さが format の範囲外か、600 秒を超えています。 |
| `400` | `pipeline_not_completed` | `completed` ではないパイプラインから、分岐がリクエストされました。 |
| `400` | `invalid_stage` | チャットの送信または読み取りで、`script`、`shot_list`、`post_merge` 以外のステージが指定されました。 |
| `400` | `invalid_stage_name` | 承認で、8 つのステージのいずれでもないステージが指定されました。そのようなステージを読み取ると、このコードとともに `404` が返されます。 |
| `400` | `stage_not_implemented` | 却下の呼び出しで、`script` 以外のステージが指定されました。 |
| `400` | `invalid_change_type_for_stage` | `post_merge` ステージに対してパッチが提案されました。このステージが受け付けるのは分岐だけです。 |
| `400` | `invalid_sub_gate` | そのゲートは、サブゲートのルートで解除できるゲートではありません。`match_cut_break_pending` の場合は、各不連続を承認するルートがメッセージに示されます。 |
| `400` | `shot_not_found` | 不連続を承認するショットが、そのシーンにありません。 |
| `400` | `not_a_match_cut` | 不連続を承認するショットに、計画されたマッチカットがありません。 |
| `400` | `invalid_entity_type` | エンティティの一覧で、`character`、`object`、`location`、`scene` 以外の `type` が指定されました。 |
| `401` | `unauthorized` | トークンがないか、無効か、取り消されています。 |
| `402` | `insufficient_credits` | アカウントが、確保分の料金をまかなえません。 |
| `403` | `edition_required` | このインスタンスは Nodaro Cloud ではありません。 |
| `403` | `insufficient_scope` | OAuth アプリのトークンに、ルートが必要とするスコープがありません。 |
| `404` | `not_found` | あなたのパイプラインの中に、その id のものがありません。サブゲートの呼び出しでは、ステージがそのゲートで待機していないことも意味します。 |
| `404` | `pipeline_not_found` | 分岐の呼び出しで指定したパイプラインが、存在しないか、あなたのものではありません。 |
| `404` | `stage_not_started` | 読み取ろうとしたステージは、まだ開始されていません。 |
| `404` | `stage_not_found` | サブゲートの呼び出しで、対象のパイプラインの動画化ステージがまだ開始されていません。ステージの承認または却下では、このコードとともに `409` が返されます。 |
| `404` | `scene_not_found` | パイプラインに、その id のシーンがありません。 |
| `409` | `patch_invalid` | チャットの提案が有効な変更ではなく、適用できませんでした。 |
| `409` | `stage_not_awaiting` | チャットの提案を適用するとき、または編集付きで承認するときに、ステージがすでに承認待ちではありません。 |
| `409` | `stage_already_advanced` | 編集なしで承認するとき、または却下するときに、ステージがすでに承認待ちではありません。 |
| `409` | `stage_not_awaiting_approval` | サブゲートの呼び出しで、対象の動画化ステージが承認待ちではありません。 |
| `409` | `already_terminal` | キャンセルの呼び出しで、対象のパイプラインがすでに完了、失敗、キャンセルのいずれかの状態です。 |
| `409` | `critic_retry_cap_reached` | 脚本は、あなたまたは脚本のクリティックによって、すでに 2 回修正されています。 |
| `409` | `scene_not_planned` | シーンにまだショットの計画がないため、そのシーンでは不連続を承認できません。 |
| `501` | `chat_not_wired_for_stage` | ステージに、動作するチャットがありません。現在、該当するのは `shot_list` だけです。 |

## Frequently asked questions

### ストーリー → 動画のパイプラインは、何を作りますか？

完成した映画と、その背後にあるワークフローです。パイプラインは脚本を書き、キャラクター、オブジェクト、ロケーションを作成し、ショットを計画し、キーフレームをレンダリングし、音声付きで動画化して、結果を結合します。GET /v1/pipelines/:id/timeline は、組み立てられたシーンを返します。

### 誰も承認しなくても、パイプラインを実行できますか？

はい。mode を auto に設定して作成すると、エンジンがすべてのステージを自分で実行し、クリティックが出力を自動でチェックします。status が completed または failed になるまで、GET /v1/pipelines/:id をポーリングしてください。実行が止まるのは、2 つのショットの間で計画したマッチカットが成立しない場合だけです。その場合、status は running のままで、すべての不連続が承認されるまで、GET /v1/pipelines/:id/pending-approvals の一覧に scene_images ステージが含まれます。

### 完成した映画を、1 つのステージからやり直すには、どうすればよいですか？

やり直すステージを指定して、POST /v1/pipelines/:id/branch を呼び出します。Nodaro は、それより前のステージを保ったまま、そのステージとそれ以降を再実行する新しいパイプラインを作成します。元のパイプラインは変わりません。

### パイプラインをキャンセルすると、クレジットはどうなりますか？

まだ実行されていない作業分のために確保されていたクレジットは、返還されます。すでに完了した作業分のクレジットは返還されません。すでに完了、失敗、キャンセルのいずれかの状態になったパイプラインは、キャンセルできません。その呼び出しには 409 already_terminal が返され、何も変わりません。

### セルフホスティング環境でも、パイプラインを実行できますか？

いいえ。パイプラインは Nodaro Cloud でのみ動作し、セルフホスティングのエディションでは 403 edition_required が返されます。セルフホスティング環境では、同じ手順をキャンバス上のワークフローとして組み立ててください。
