Nodaro ドキュメント
ドキュメントノードリファレンスモデルAI エージェント(MCP)開発者向けセルフホスティングリサーチ
REST API

ノード

POST /v1/<node-type> で、任意の Nodaro ノードを実行します。ノード、モデル、ピッカーの値を調べ、リファレンスや演出の ID でプロンプトを調整する方法も説明します。

ノードの実行は、ワークフローを組まずに、Nodaro のノードを 1 つだけ直接呼び出します。POST /v1/<node-type> に、ノードの設定をボディとして送信します。generate-image や generate-video から text-to-speech まで、すべての生成ノードがこの形に従っており、検出用のエンドポイントで、どのノード、モデル、設定が存在するかを調べられます。ほとんどのノードの実行は非同期です。レスポンスは jobId で、結果ができるまでポーリングします。

ノードを実行する

ノードタイプのルートは、POST /v1/ の後にそのタイプを付けたもので、ボディはノードの設定を JSON にしたものです。

POST /v1/generate-image
Authorization: Bearer ndr_…
Content-Type: application/json

{ "prompt": "a lighthouse in a storm, oil painting", "provider": "nano-banana-pro", "aspectRatio": "3:4" }

何が返ってくるかは、ノードによって異なります。

  • 生成ノードは、200 とともに { "jobId": "…" } を返します。処理はワーカー上で実行され、ステータスが completed になるまで GET /v1/jobs/:id/status でジョブをポーリングします。ジョブを参照してください。
  • 画像と動画の生成では、adjustments が加わることがあります。これは、選んだモデルのためにサーバーが補正した設定の一覧です。generate-video では、warnings が加わることもあります。パラメーターの補正を参照してください。
  • combine-text などのインラインノードは、jobId を返さずに、完全な結果をすぐに返します。
  • web-scrape などのスクレイパーも、すぐに応答します。レスポンスには、履歴のための jobId と、データ自体の両方が含まれます。

生成は、開始時にクレジットを確保します。アカウントがその実行分をまかなえない場合、呼び出しは 402 insufficient_credits を返します。

パスが長いノード

言語モデルを呼び出すテキストノードの多くは、同じ POST /v1/<node-type> の規則に従います。generate-script、image-critic、qa-check、describe-to-picker です。それ以外の一部は、より長いパスで登録されています。

ノードタイプルート
llm-chatPOST /v1/llm-chat/generate
after-effectsPOST /v1/after-effects/generate
motion-graphicsPOST /v1/motion-graphics/generate
lottie-overlayPOST /v1/lottie-overlay/generate
3d-titlePOST /v1/3d-title/generate
image-to-textPOST /v1/image-to-text/describe
video-composerPOST /v1/scene-graph/generate

SDK の client.nodes.run(type, params) は /v1/<type> に POST します。そのため、これらのノードは client.request('POST', '/v1/llm-chat/generate', { body }) のように呼び出します。

言語モデルのルートは、2 つの任意のフィールドを受け付けます。

  • reasoningEffort:モデルによって、none、low、medium、high、xhigh、max のいずれかです。省略するか、そのモデルが対応していない段階を指定すると、モデル自体のデフォルトになります。xhigh と max は、クレジットのティアが 1 段階上がります。
  • advancedMode: true:Gemini モデルのみです。リクエストはモデル開発元自身の API 上で実行されます。これは、temperature、maxTokens、推論の全範囲が効く唯一の経路です。reasoningEffort とは別に、クレジットのティアが 1 段階上がります。この経路がないモデルは、400 advanced_mode_unsupported を返します。

例:画像を生成する

ジョブを開始する

curl -s -X POST https://app.nodaro.ai/v1/generate-image \
  -H "Authorization: Bearer $NODARO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "prompt": "a knight on a hill at dawn, cinematic",
        "provider": "nano-banana-pro",
        "aspectRatio": "16:9",
        "resolution": "2K"
      }'
{ "jobId": "0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10" }
import { createClient, StaticTokenAuth } from '@nodaro/sdk'

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

const result = await client.nodes.run('generate-image', {
  prompt: 'a knight on a hill at dawn, cinematic',
  provider: 'nano-banana-pro',
  aspectRatio: '16:9',
  resolution: '2K',
})
nodaro nodes run generate-image \
  --param prompt="a knight on a hill at dawn, cinematic" \
  --param provider=nano-banana-pro \
  --param aspectRatio=16:9 \
  --param resolution=2K

ジョブをポーリングする

ステータスが completed か failed になるまで、2〜5 秒ごとにジョブのステータスを確認します。

curl -s https://app.nodaro.ai/v1/jobs/0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10/status \
  -H "Authorization: Bearer $NODARO_API_KEY" | jq -r .data.status

結果を読み取る

完了した画像のジョブは、画像の URL を output_data.imageUrl に持ちます。動画のジョブは videoUrl を、オーディオのジョブは audioUrl を使い、多くのジョブは thumbnailUrl も持ちます。

{
  "data": {
    "id": "0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10",
    "status": "completed",
    "progress": 100,
    "output_data": { "imageUrl": "https://…/0f1a9c2e.png" },
    "error_message": null
  }
}

SDK と CLI は、代わりにポーリングを行えます。

const output = await client.nodes.runAndWait('generate-image', {
  prompt: 'a knight on a hill at dawn, cinematic',
  provider: 'nano-banana-pro',
})
console.log(output.imageUrl)

// Several candidates at once, in input order:
const results = await client.nodes.runMany('generate-image', [
  { prompt: 'a knight on a hill, sunrise' },
  { prompt: 'a knight on a hill, golden hour' },
  { prompt: 'a knight on a hill, blue hour' },
])
for (const { jobId, output } of results) console.log(jobId, output.imageUrl)
nodaro nodes run generate-image \
  --param prompt="a knight on a hill at dawn, cinematic" \
  --param provider=nano-banana-pro \
  --watch --json | jq -r '.output_data.imageUrl'

runAndWait は、デフォルトで 2,000 ミリ秒ごとに、最大 15 分間ポーリングします。これは pollMs と maxMs で変更でき、signal に渡す AbortSignal で停止でき、onProgress で進行状況を追えます。instanceof で捕捉できる、型付きのエラーをスローします。

エラー発生する場合
InsufficientCreditsError、StorageExceededError、JobBlockedErrorジョブが開始される前に、実行が拒否された場合です。
JobFailedErrorジョブが failed か cancelled で終わった場合です。jobId とエラーメッセージを持ちます。
JobTimeoutErrormaxMs が経過した場合です。ジョブはキャンセルされず、通常はそのまま完了します。後で client.jobs.get(jobId) を使って取得してください。
JobAbortedError自分の signal が発火した場合です。
JobHeldError結果をレビューするデプロイ環境で、ジョブが pending_review になった場合です。ジョブはキャンセルされません。後で確認してください。

CLI では、配列やネストしたオブジェクトなどの複雑なボディを、--params-file body.json でファイルから渡します。同じキーについては、フラグの値がファイルの値を上書きします。true、false、null、数値は、テキストから変換されます。

画像生成の設定

以下のフィールドは、POST /v1/generate-image でよく使う設定です。各設定がエディターで何を行うかは、画像生成(Generate Image)を、各モデルが対応している内容は、画像モデルを参照してください。

Prop

Type

マスクを使った編集やリファインの料金は、そのモデルでの新規生成と同じです。

動画を生成する

動画を作るルートは 2 つあります。POST /v1/generate-video は、画像からアニメーションを作ります。imageUrl の開始フレーム、任意で endFrameUrl の最後のフレーム、または、対応しているモデルではリファレンスだけです。POST /v1/text-to-video は、プロンプトだけからクリップを作るので、prompt が必須です。provider を省略すると、プラットフォームのデフォルトの動画モデルが使われます。

{
  "imageUrl": "https://…/frame.png",
  "provider": "seedance-2",
  "prompt": "she turns toward the window",
  "duration": 8,
  "resolution": "720p",
  "direction": { "cameraMotion": "dolly-in", "timeOfDay": "dawn" }
}

レスポンスは { "jobId": "…" } で、当てはまる場合は warnings と adjustments も含まれます。完了したジョブは output_data.videoUrl を持ちます。

Prop

Type

モデルによって異なる規則が、いくつかあります。

  • Seedance 2 系列では、resolution と aspectRatio がそのまま渡されます。モデルが対応していない値は、拒否されずに無視されます。4k と adaptive に対応しているのは、Seedance 2 だけです。Seedance 2.5 は、1 回の呼び出しで最大 30 秒を作れます。開始フレームがある場合、常にそのフレームのアスペクト比でレンダリングします。
  • MiniMax Hailuo 3 の resolution は 2K または 768P で、まさにこの表記で指定します。送信する値は、GET /v1/nodes/:type の providerResolutionWire に一覧表示されます。
  • Seedance 2 と MiniMax Hailuo 3 では、フレームとリファレンスを組み合わせられます。開始または終了フレームと一緒にリファレンスを送信すると、そのフレームは固定の始点や終点ではなく、プロンプト内の番号付きリファレンスになります。Wan 3.0 では両方を送れないため、代わりにフレームがリファレンスの一覧の末尾に追加され、呼び出しはそのまま成功します。
  • リファレンス動画は、料金が高くなります。課金対象にしているモデルでは、リファレンスクリップの料金は、そのクリップ自体の長さと出力の長さを合わせて決まります。そのため、元のクリップが長いほど、確保されるクレジットも増えます。Wan 3.0 は、出力の秒数だけを課金します。

各モデルの長さ、解像度、クレジット料金については、動画モデルを読むか、GET /v1/models を呼び出してください。

リファレンスを使う

リファレンスは、モデルに合わせてほしい画像、そして動画ではクリップとオーディオでもあります。フラットな URL のリストとして送ることも、ルートが番号を振り、ラベルを付けてプロンプトに書き込む構造化されたリファレンスとして送ることもできます。これは、エディターが接続されたノードに対して行うのと同じです。

構造化されたリファレンス

connectedReferences は、POST /v1/generate-image、POST /v1/generate-video、POST /v1/text-to-video、POST /v1/extend-video で受け付けられます。各エントリーは、1 枚の画像を表します。

Prop

Type

動画のルートでは、これらのエントリーを番号付きのリファレンスに変換します。

  • メンションしなかったリファレンスは、すべて添付されます。その URL は重複を除いてリファレンスの一覧に加わり、@image_1 (reference): <label> のような行が付きます。wired-character のエントリーは、代わりに「Use these characters:」という指示の一部になります。
  • 一覧は、番号を振る前に、そのモデルの上限で打ち切られます。そのため、プロンプト内のリファレンス番号が、送信されていない画像を指すことはありません。
  • プロンプト内の {image:N:label} は、添付されたリファレンスに対して番号が振られ、「@image_N からの label」になります。
  • {ref:<id>} と {ref:<id>:label} は、指定した id でリファレンスを指定します。プラットフォームは、一覧に番号を振った後に、そのトークンをリファレンスの番号に置き換えます。そのため、番号は自分で計算する必要がありません。一覧には、まずフラットな referenceImageUrls、次にメンションしなかったキャラクター、その後は指定した順のほかのエントリー、という順序で番号が振られます。上限を超えていた、あるいはモデルがリファレンスを受け付けないなどの理由でリファレンスが添付されなかったトークンは、そのラベルに、それもなければ defaultName に、それもなければ何もない状態にフォールバックします。生のテキストのままモデルに渡ることはありません。
  • referenceOrder は、リファレンス ID のリストで、リファレンスの順序を変え、それに合わせて番号も振り直します。POST /v1/generate-image でも使えます。

connectedReferences が扱うのは画像だけです。referenceVideoUrls と referenceAudioUrls は、フラットなリストのままです。connectedReferences を省略すると、ルートは以前と同じように動作します。prompt と referenceImageUrls は、そのまま送信されます。

画像のリファレンスに対応する動画モデル

モデルファミリー画像のリファレンス
Seedance 2 系列最大 9
HappyHorse Ref2V最大 9
Gemini Omni、Kling 3 Omni、Grok Imagine image-to-video最大 7
VEO 3.1 Fast、VEO 3.1 Lite最大 3

それ以外のモデルでは、{image:N} トークンはラベルに置き換えられるだけで、何も添付されません。VEO 3.1 Quality は一覧にありません。veo3 で送ったリファレンスは無視され、実行にはそのフレームが使われます。

リファレンスだけから動画を作る

POST /v1/generate-video では、送信するリファレンスの種類のうち少なくとも 1 つにモデルが対応していれば、開始フレームは省略できます。たとえば、referenceImageUrls だけを使う Kling 3 Omni です。VEO 3.1 Fast または Lite でリファレンスだけの実行を行うと、自動でリファレンスモードに切り替わるため、generationType は不要です。モデルが使えない種類のリファレンスは数に入りません。画像だけを受け付けるモデルにオーディオだけのリファレンスを送ると、400 で拒否されます。

終了フレームだけも、それをリファレンスに組み込むモデルでは使えます。Seedance 2 系列、MiniMax Hailuo 3、Wan 3.0 です。endFrameUrl を 1 回送信するだけでよく、referenceImageUrls に同じ画像を重ねて指定する必要はありません。@nodaro/shared パッケージは videoProviderFoldsLoneEndFrame(provider) をエクスポートしているので、自分のインターフェースでも同じ規則を使えます。

リクエストに開始フレームもリファレンスモードもなく、モデルが使えるリファレンスもない場合、応答はモデルによって異なります。

  • Kling 3 Omni、HappyHorse Ref2V、Hailuo 2.3 のように、テキストだけから動画を作れないモデルは、400 image_required を返します。メッセージには、代わりにリファレンスが使えるかどうかが示されます。該当するモデルについては、GET /v1/models が正式な情報源です。
  • それ以外のすべてのモデルは 400 validation_error を返し、プロンプトだけのクリップには POST /v1/text-to-video を使うように伝えます。

動画を延長

POST /v1/extend-video が connectedReferences と referenceImageUrls を受け付けるのは、provider: "seedance-2-extend" のときだけです。それ以外の延長用モデルは、400 で拒否します。上限は自分の画像 8 枚です。元のクリップの最後のフレームが、リファレンス枠を 1 つ使うためです。この枠は自分の画像の後に置かれるので、自分の番号がずれることはありません。元のクリップの最後の 2 秒は @video_1 として渡され、延長の料金にすでに含まれています。リファレンス画像によって、クレジットが追加でかかることはありません。動画を延長(Extend Video)には direction も subject もありません。プロンプトは、すでに見た目が決まっているクリップの続きだからです。

説明だけのリファレンス

describedReferences は、説明はできるが、まだ画像がない被写体を指定します。台本の役どころなどです。POST /v1/generate-image、/v1/generate-video、/v1/text-to-video、/v1/extend-video は、{ name, description } のエントリーを最大 10 個受け付けます。name は最大 80 文字、description は最大 2,000 文字です。

  • 何も添付されません。説明だけのリファレンスはリファレンス枠を使わないため、ほかのリファレンスの番号も変わりません。
  • モデルには、1 行のテキストとして渡されます。<Name> — <description>. という形です。プロンプトには名前をそのまま残します。たとえば Natalie walks down the pier. のようにします。この行が、Natalie が誰であるかをモデルに伝えます。@ によるメンションは書かないでください。その記法は、添付された画像を指すためのものです。
  • 単独でも機能します。connectedReferences なしで describedReferences だけを送信できます。まだキャラクターが存在しない段階で書かれたストーリーでは、これが一般的なケースです。
  • 名前か説明のないエントリーは取り除かれ、同じ名前が繰り返されている場合は 1 回だけ書き込まれます。説明だけのリファレンスは URL を持たないため、どの延長用モデルでも使えます。

実行ごとの説明とキャプション

  • descriptionOverride は、connectedReferences のエントリーに指定するもので、このリファレンスがこの実行に限って何であるかを、最大 2,000 文字で示します。保存された説明より優先して、リファレンスの指示にすでにある説明を埋めます。指示に説明がない場合は、1 行を追加します。そのため、モデルに伝わるのは 1 回だけで、2 回になることはありません。
  • referenceVideoCaptions と referenceAudioCaptions は、POST /v1/generate-video と /v1/text-to-video で、リファレンスのクリップとオーディオを、それぞれ最大 500 文字で説明します。これらはインデックスで対応しています。referenceVideoCaptions[0] は referenceVideoUrls[0] を説明します。それぞれが @video_1: <caption>. のような行になり、空のエントリーは、対応をずらさずに 1 つのクリップを読み飛ばします。

プロンプトでリファレンスをメンションする

POST /v1/generate-image では、リファレンスを末尾の一覧に残す代わりに、文の中に置くことができます。@<name-slug>:<index> と書くか、@<name-slug>:<index>:<role> と書いて、そこから何を取り入れるかを指定します。

{
  "prompt": "a wide shot of @nessie:1 rising beside @dock:2:material",
  "connectedReferences": [
    { "id": "cr-1", "defaultName": "Nessie", "source": "wired-creature", "url": "https://…/nessie.png" },
    { "id": "ob-1", "defaultName": "Dock", "source": "wired-object", "url": "https://…/dock.png" }
  ]
}

モデルは「a wide shot of the creature from reference image A rising beside the material from reference image B」を受け取ります。

  • スラッグは defaultName から作られます。小文字にし、それ以外の文字の連続は 1 つの - に変換します。Old Town は old-town になります。スラッグを設定するフィールドはありません。
  • インデックスは、メンションをリファレンスに一致させるためだけのものです。プロンプトに書き込まれることはなく、リファレンスへの番号付けはプラットフォームが自分で行います。
  • 画像(manual と wired-image)の役割は、object、person、face、clothes、background、style、pose、texture です。クリーチャーは creature、anatomy、markings、pose、color、style を取ります。オブジェクトは object、shape、material、color、texture、style を取ります。それ以外の 1 語は、書かれたとおりに渡されます。役割を指定しない場合は、そのエントリーの defaultRole が適用されます。
  • メンションの後に付ける ~lock と ~nolock は、@town:1:background~lock のように、そのメンションに限って、リファレンスの顔の固定をオンまたはオフにします。
  • 名前は、次の順序で照合されます。キャラクター、ロケーション、画像、クリーチャー、オブジェクトです。キャラクターと画像が同じ名前を共有している場合はキャラクターを意味し、同じ種類の中では、最初に一致したものが優先されます。
  • スラッグが数字で始まる名前は、メンションできません。たとえば 3D Render は 3d-render になります。メンションするには、リファレンスの名前を変更してください。モデルの上限を超えていたリファレンスへのメンションは、そのままの文字として残ります。
  • リファレンスをメンションすると、その位置が移動します。末尾の一覧から、入力した場所へと移ります。それより後のリファレンスの文字も、文に合わせて変わります。クリーチャーやオブジェクトでは、メンションによって、末尾に追加されるはずだった行も置き換えられます。

リファレンスの固定

POST /v1/generate-image の referenceLock は、シーンの前に、検証済みの、リファレンスに忠実に従わせる Nodaro の言い回しを追加します。

値追加される内容使う場面
standardリファレンスに写っているものだけを使い、似姿を保ち、それらを組み合わせるという指示複数のリファレンスからの合成
multi-person上記に加えて、顔を変えたり混ぜたりしないという規則1 つのショットに 2 人以上の顔

送信するのはテキストではなく ID です。言い回しはプラットフォーム側が持っており、クライアントを更新しなくても改善されます。フィールドを省略すると、ロックは追加されません。

ID による演出

direction は、カメラ、光、ルックを、文章ではなくピッカー ID で表します。POST /v1/generate-image、POST /v1/generate-video、POST /v1/text-to-video が受け付けます。Nodaro は、各 ID に対応する検証済みの言い回しを、自分でプロンプトに書き込みます。そのため、保存したリクエストは、クライアントが書いたテキストのまま固定されるのではなく、時間とともに改善された言い回しを取り込みます。

{
  "prompt": "a knight on a hill",
  "provider": "nano-banana-pro",
  "direction": {
    "shotSize": "wide-shot",
    "lens": "wide-24mm",
    "lightingStyle": "rembrandt",
    "style": "anime",
    "mood": ["happy", "joyful"]
  }
}

キーと、その ID の取得元

各キーは、クリエイティブコントロールピッカーの 1 つのフィールドです。有効な ID は、エディターのピッカーが使うのと同じカタログである GET /v1/picker-catalogs/<picker> から取得します。

キーピッカー画像動画
shotSize、angle、coverage、composition、vantageフレーミング(Framing)はいはい
poseポーズ(Pose)はいはい
compositionEffect構図エフェクト(Composition Effects)はいはい
cameraFormatカメラ/フィルム(Camera / Film Stock)はいはい
lensレンズ(Lens)はいはい
aperture、shutterSpeed、isoValue露出設定(Exposure Settings)はいいいえ
timeOfDay、lightingStyle、lightingDirection、lightingRatio、colorTemperatureライティング(Lighting)はいはい
colorLookカラー/ルック(Color / Look)はいはい
atmosphere大気効果(Atmosphere)はいはい
postProcessポストプロセスエフェクト(Post-Process Effects)はいいいえ
styleスタイル(Style)はいはい
moodムード(Mood)はいはい
aestheticテイスト(Aesthetic)はいはい
photoGenre写真ジャンル(Photo Genre)はいいいえ
photographer写真家(Photographer)はいいいえ
renderQualityレンダリング品質(Render Quality)はいいいえ
setting舞台設定(Setting)はいはい
era年代/時代(Era)はいはい
backdrop背景(Backdrop)はいはい
cameraMotionカメラモーション(Camera Motion)いいえはい
actionFxアクション FX(Action FX)いいえはい
temporalSpeed、temporalFreeze、temporalDirection、temporalShutter時間表現(Temporal)いいえはい
transitionトランジション(Transition)いいえはい
loopSubjectループの被写体(Loop Subject)いいえはい

あるルートに当てはまらないキーも受け付けられ、何も追加しないだけです。そのため、ルックの ID を 1 つのマップにまとめて、変更せずに画像と動画の両方のルートに送信できます。

値と上限

  • 1 つの ID か、リストです。複数選択のキーである mood、aesthetic、photographer、atmosphere、postProcess、composition、lightingStyle は、それぞれ独自の上限まで受け付け、それを超える ID は取り除かれます。単一選択のキーにリストを指定した場合は、最初のエントリーが使われます。
  • 拒否される上限が 2 つあります。400 validation_error になるのは、1 つのキーに 8 個を超えるエントリーを指定した場合と、100 文字を超える ID を指定した場合です。
  • なしと空は違います。キーがないことは、ヒントがないことを意味し、デフォルト値を意味することはありません。空の文字列や空のリストも、何も追加しません。
  • 不明なキーと不明な ID は、拒否されずに読み飛ばされます。古いサーバーに新しいクライアントを使うと、エラーの代わりにヒントが減るだけです。新しいキーを送るクライアントより先に、サーバーを更新してください。
  • カスタムのカタログパックです。独自のカタログパックを登録したデプロイ環境では、GET /v1/picker-catalogs が、パックが追加する ID を一覧表示します。これらの ID は受け付けられますが、direction に言い回しを追加することはありません。

言葉が入る場所

これらの一節は、プロンプトの後の [style] セクションに追加されます。フィルムの行には cameraFormat、colorLook、style、era が、シーンの行にはそれ以外のルックのキーが入ります。

a knight on a hill

[style]:
<film line>
<scene line>
  • 行の中の順序は、プラットフォーム側の固定の順序であり、指定したキーの順序ではありません。2 つのキーが同じ一節を指すと、それは 1 回だけ書き込まれます。
  • 何も入らない行は省かれます。どのキーも何も追加しない場合、セクション自体がなくなり、prompt はそのままモデルに渡ります。
  • 動画のルートでは、モーションのキーは異なる働き方をします。cross-dissolve のような短い専門用語を追加し、本文の中、つまり自分の文章の後にとどまります。モーションはショットの一部だからです。cameraMotion が最初に来ます。[style] セクションに入るのは、ルックのキーだけです。

プロンプトが長すぎる場合

各モデルが受け付けるプロンプトの長さには、それぞれ上限があります。direction をすべて含めると、それだけで小さな上限を超えることがあります。たとえば、画像側の Seedream では 3,000 文字、動画側の Kling では 1,000 文字です。そうなった場合、Nodaro は、固定の順序の末尾から、プロンプトが収まるまで、direction の一節を 1 つずつ取り除きます。それより先に、ほかの部分が取り除かれることはありません。

  • subject の一節が取り除かれるのは、direction の一節がすべて取り除かれた後だけです。
  • 自分の文章、リファレンス、それらを結び付ける語句、@ によるメンション、Style: と Avoid: の行は、常に残ります。
  • ヒントがなくなってもまだプロンプトが収まらない場合に限り、テキストの末尾が切り詰められ、... が追加されます。

動画のルートでは、この予算に、ルートが追加するリファレンスの指示も数えられ、これらが取り除かれることはありません。ネガティブプロンプトの設定がないモデルでは、negativePrompt が Avoid: の行として追加され、その分の余地が最初に確保されます。そのため、長いネガティブプロンプトは、文章ではなくヒントの一節を犠牲にします。任意の injectCharacterContext のテキストは、この処理の後に追加され、この予算には含まれません。

ジョブには、何が起きたかが記録されます。input_data.prompt はモデルが受け取った内容、input_data.userPrompt は自分が送信したテキスト(direction だけを送信した場合は空の文字列)、input_data.direction は送信したとおりの ID です。

ノードに保存された演出

保存されたワークフロー内の画像生成ノードは、API、MCP、またはワークフローを作成するアプリが書き込んだ、同じ direction オブジェクトをデータの中に持てます。エディターは、実行のたびに、そして最終的なプロンプトのプレビューでも、これを反映します。保存された ID は、接続されたフレーミング、ライティング、スタイルのピッカーに追加されます。接続によるヒントが先に来て、その後に保存された ID が続きます。プリセットとワークフローのエクスポートは、ノードのほかの部分と一緒に ID を保持します。

ID による被写体の指定

subject は、ショットに誰が写っているかについての、同じ考え方です。人物、そのスタイリング、フレーム内の小道具です。POST /v1/generate-image、POST /v1/generate-video、POST /v1/text-to-video が受け付けます。

{
  "prompt": "on the seawall at dusk",
  "provider": "nano-banana-pro",
  "subject": {
    "type": "woman",
    "age": "age-30s",
    "ethnicity": "east-asian",
    "hairBase": "base-short-straight",
    "makeup": "makeup-smoky",
    "outerwear": "outerwear-trench",
    "heldProp": "smartphone"
  }
}
  • キーは、人物(Person)とスタイリング(Styling)ピッカーのフィールドです。type、age、ethnicity、faceShape、hairColor、skinTone、makeup、outfit、outerwear、footwear などで、これに加えて 3 つの小道具のキー、heldProp(手に持つ小道具(Held Prop))、material(素材(Material))、animal(動物(Animal))があります。GET /v1/picker-catalogs/person と /styling に、すべてのフィールドと ID が一覧表示されます。
  • subject と direction は、決して重なりません。それぞれのキーは別々なので、1 つの選択が 2 つの一節を追加することはありません。pose は direction に属します。
  • customAge は、数値を指定する唯一のフィールドです。正確な年齢を指定するには、"age": "age-custom" と一緒に "customAge": 34 を送信します。値は四捨五入され、0〜120 の範囲に保たれます。
  • リストには、キーごとに上限があります。jewelry、wardrobeState、distinctiveFeature は 3 個までです。ethnicity、regionalAesthetic、hairColor、eyeColor、lipState、eyeState、skinTexture、hairState、heldProp、material は 2 個までです。animal を含む、それ以外のすべてのキーは 1 個までです。それを超える ID は取り除かれます。
  • 拒否される上限:1 つのキーに 8 個を超えるエントリー、100 文字を超える ID、128 個を超えるキー、64 文字を超えるキーは、いずれも 400 validation_error になります。
  • 不明なキーは取り除かれ、不明な ID は読み飛ばされます。ジョブの input_data.subject には、実際に使われた ID がそのまま記録されます。
  • subject の一節は、自分の文章の一部です。direction の一節より前に置かれ、[style] セクションに入ることはありません。人物が 1 つの一節に、スタイリングがもう 1 つの一節になり、重なる選択は 1 回だけ書き込まれます。画像のルートでは、それぞれの選択が完全な一節を追加しますが、動画のルートでは短い用語だけを追加します。開始フレームに、すでに被写体が誰であるかが写っているためです。

ノードを調べる

GET /v1/nodes は、サーバーが認識するすべてのノードタイプを一覧表示し、GET /v1/nodes/:type は 1 つを返します。どちらも公開されており、トークンは不要で、5 分間キャッシュされます。不明なタイプは 404 not_found を返します。

curl -s https://app.nodaro.ai/v1/nodes/generate-image | jq .data
const { data: nodes } = await client.nodes.list()
const imageNodes = nodes.filter((n) => n.category === 'ai-image')

const { data: generateImage } = await client.nodes.get('generate-image')
console.log(generateImage.providers)
nodaro nodes list --category ai-image
nodaro nodes get generate-image
{
  "data": {
    "type": "generate-image",
    "label": "Generate Image",
    "category": "ai-image",
    "description": "Generate an image from a text prompt using an AI provider.",
    "outputType": "image",
    "creditCost": "2-620",
    "providers": ["nano-banana-pro", "gpt-image-2", "gpt-image-2-5-flare", "seedream-5-pro", "z-image"],
    "capabilities": ["supports-reference-image", "supports-aspect-ratio"],
    "inputSchema": {
      "fields": [
        { "key": "prompt", "type": "text", "required": true },
        { "key": "provider", "type": "select", "options": ["nano-banana-pro", "gpt-image-2"] },
        { "key": "aspectRatio", "type": "select" },
        { "key": "promptPrefix", "type": "text" },
        { "key": "promptSuffix", "type": "text" }
      ]
    }
  }
}
フィールド意味
typeノードタイプです。ルートの POST /v1/<type> にもなります。
label、category、descriptionエディターが、このノードをどう名付け、どうグループ分けするかです。
outputTypetext、image、video、audio、data、none のいずれかです。
creditCostノードのクレジット料金、またはその範囲です。Nodaro Cloud のみです。クレジットのないエディションでは省かれます。
providersノードが provider に受け付けるモデル ID です。
capabilitiessupports-reference-image のような、機能のフラグです。
inputSchema.fieldsノードの設定です。型、必須かどうか、選択肢を含みます。

プロンプトを受け付けるすべてのノードには、promptPrefix と promptSuffix も一覧表示されます。プロンプトの前後に追加されるテキストです。プロンプトの前後のテキストを参照してください。モデルごとの上限があるノードには、追加のフィールドがあります。

フィールド意味
maxDurationSecノードが受け付ける、最長の長さです。
sparseProvidersセグメントの長さの選択肢が少ないモデルです。その間の値は、最も近いものに変更されます。
providerResolutions各モデルの解像度です。たとえば { "minimax-h3": ["2K", "768P"] } です。
providerResolutionWire各解像度について送信する、正確な値です。たとえば MiniMax Hailuo 3 の安いティアでは、768p ではなく 768P です。
soundtrack動画生成 Pro(Generate Video Pro)で、サーバーが元の音声の soundtrack 入力を受け付けることを示します。

このディスクリプターのフィールドは今後も増えていくため、知らないフィールドは無視してください。同じデータが、ノードリファレンスのもとにもなっています。

モデルを調べる

GET /v1/models は、種類と開発元でグループ分けされたモデルカタログを返します。公開されており、5 分間キャッシュされ、MCP の list_models ツールが返すのと同じデータです。

curl -s "https://app.nodaro.ai/v1/models?kind=video&mode=i2v" | jq '.totalModels'
const catalog = await client.models.list({ kind: 'video', mode: 'i2v' })
for (const section of catalog.sections)
  for (const family of section.families)
    for (const m of family.models) console.log(m.id)
nodaro models list --kind video --mode i2v

レスポンスは { sections, recommendations, totalModels } です。各モデルは、その機能(modes、features、aspectRatios、resolutions、durations)、Nodaro Cloud でのバリアントごとのクレジット pricing、簡潔な promptTips、そして doctrineCovered を持ちます。doctrineCovered は、そのモデルファミリーについて、出典のあるプロンプトガイドが存在する場合にだけ true になります。

クエリ値絞り込み対象
kindimage、video、audio のいずれかメディアの種類 1 つ
modeたとえば t2i、i2v、t2v、tts、video-analysis操作 1 つ
family開発元です。たとえば Google や Bytedance です開発元 1 つ
featuredOnlytrue注目のモデル

モデルのページにも、同じカタログが載っています。

ピッカーの値を調べる

クリエイティブコントロールのピッカーには、有効な ID の公開カタログがあります。direction と subject が取る値です。

メソッドパス返す内容
GET/v1/picker-catalogsすべてのピッカーです。nodeType、label、kind、そのフィールド、optionCount、imageCount です。
GET/v1/picker-catalogs/:nodeType1 つのピッカーの選択肢です。?detail=full を付けると、各選択肢の description と promptHint が加わります。?category= は単一フィールドのピッカーを絞り込み、?field= は複数フィールドのピッカーの 1 つのフィールドを返します。
GET/v1/catalogsデプロイ環境が整備したとおりの、すべてのカタログを 1 回の呼び出しで返します。data が存在するのは、デプロイ環境がカタログパックを登録した場合だけです。
POST/v1/text-to-picker「AI Fill」です。自由記述のシーンの説明から、多くのピッカーの ID を選びます。クレジットがかかります。

すべての選択肢は、id、label、そしてプロンプトで使う短い言い回しである term を持ち、画像がある選択肢には imageUrl も付きます。カタログは、@nodaro/shared npm パッケージのデータとしても提供されます。完全な形については、ピッカーカタログを読んでください。ターミナルからは、nodaro pickers list、nodaro pickers get mood --full、nodaro pickers analyze "<text>" を使います。

構造化された LLM 出力

POST /v1/llm/structured は、1 回の言語モデルの呼び出しを実行します。その回答は、指定した JSON Schema に強制的に当てはめられ、検証されたうえで、オブジェクトとして返されます。料金は、モデルのティアに応じたクレジットで課金されます。

{
  "system": "You write production plans.",
  "input": "A rainy chase through Rome.",
  "jsonSchema": {
    "type": "object",
    "properties": { "title": { "type": "string" } },
    "required": ["title"]
  }
}

回答は { jobId, output, usage: { inputTokens, outputTokens } } で、output が、指定したスキーマの形になります。

  • フィールド:system、input、jsonSchema が必須で、任意で schemaName(最大 64 文字)、llmModel、reasoningEffort、maxRetries、origin、advancedMode、temperature、maxTokens を指定できます。system と input は、それぞれ最大 100,000 文字まで指定でき、input には少なくとも 1 文字が必要です。
  • モデル:llmModel を指定しない場合、呼び出しは Gemini 3.6 Flash で実行されます。
  • スキーマ:ルートは、単純なオブジェクトのスキーマである必要があり、最大 64 KB、深さ 20 レベルまでです。properties、required、additionalProperties、items、基本の型、ルートより下の enum、const、anyOf、oneOf、数値と長さの範囲、multipleOf、exclusiveMinimum、description を使えます。not、if、then、else、dependent 系のキーワード、外部の $ref、ルートでのコンビネーターは 400 を返します。ルートより下の required 分岐による anyOf は受け付けられますが、強制はされません。フィールドをまたぐ規則は、自分で確認してください。
  • 再試行:maxRetries は 0〜3 で、デフォルトは 2 です。無効な回答を、検証エラーとともにモデルへ差し戻す回数です。
  • サンプリング:maxTokens はすべての呼び出しに適用され、モデル自体の上限を超えることはできません。temperature は、advancedMode: true も一緒に送信しない限り無視されます。この場合、クレジットのティアが 1 段階上がります。
  • 所要時間:この呼び出しは同期的で、数分かかることがあります。各試行は、2 つの経路のそれぞれで最大 240 秒かかることがあるため、最悪の場合、デフォルトの maxRetries では 24 分、最大値では 32 分かかります。HTTP クライアントのタイムアウトを延ばすか、下記のジョブの形式を使ってください。SDK のデフォルトの timeoutMs である 60 秒では短すぎます。
  • エラー:400 validation_error、401、402、500 internal_error、再試行を使い切った後の 502 llm_error、503 provider_unavailable です。

SDK では、client.llm.structured(body) を呼び出します。

ジョブとして実行する

POST /v1/llm/structured/jobs は、同じボディを受け取り、すぐに { jobId } を返します。GET /v1/jobs/:id/status をポーリングしてください。completed になると、output_data は { output, inputTokens, outputTokens } になり、failed になると、error_message に理由が示されます。作成したドラフトは、GET /v1/jobs?type=llm-structured&origin=<your app> でもう一度見つけられます。3 つの追加フィールドを受け付けます。

  • label:ジョブの表示名で、最大 120 文字です。
  • videoUrl:動画からドラフトを作ります。動画はまず、自分が所有する別のジョブとして、動画分析の料金で分析され、その分析結果が input に追加されます。実行中は、output_data.stage が analyzing、続いて drafting になります。
  • videoAnalysis:その分析のための { llmModel?, selectionMode? } です。

POST /v1/jobs/:id/cancel でドラフトをキャンセルすると、実行中の分析もキャンセルされます。分析が拒否されると、ドラフトのために確保されていたクレジットはすべて返還されます。言語モデルの呼び出しを nodaro.ai に送るインストール環境では、ジョブの形式は 503 provider_unavailable を返します。その場合は、同期呼び出しを使ってください。SDK では、client.llm.structuredJob(body) を呼び出します。

よくある質問

最終更新

目次