Montagea API · v1
開発者 API ドキュメント
OpenAI 互換 API で Montagea の自社ホストのテキスト・画像・動画モデルを呼び出せます。開発者キーで認証し、有料クレジットまたは対象の Unlimited 特典を利用します。無料アカウントは API 非対応です。
使い始める
設定 → 開発者 API でキーを作成します。すべてのエンドポイントは下記の Base URL を使います。キーはサーバー側に保管し、公開の Web ページやアプリに埋め込まないでください。
export MONTAGEA_API_BASE="https://api.montagea.com/api/v1"
export MONTAGEA_API_KEY="mtg_..."すべてのリクエストで Authorization ヘッダーに Bearer キーを付けます。生成リクエストには Idempotency-Key も付けると、通信障害の後に安全に再試行できます。
料金
標準のクレジット課金価格はサイトと同じ計算方式で、課金システムから生成されます。有効な Unlimited プランの対象となる個人 API 呼び出しは 0 クレジットです。ドル換算は現在のクレジットパック価格に基づき、大きいパックほどクレジット単価が下がります。
| モデル | 課金単位 | クレジット | USD 目安 |
|---|---|---|---|
| qwen-27b | 入力 100 万トークンあたり | 480 | $1.20–$2.40 |
| qwen-27b | 出力 100 万トークンあたり | 2,880 | $7.19–$14.40 |
| qwen-image | 1K 画像 1 枚 | 20 | $0.050–$0.10 |
| qwen-image | 2K 画像 1 枚 | 60 | $0.15–$0.30 |
| z-image | 1K 画像 1 枚 | 20 | $0.050–$0.10 |
| minimax-h3 | 5 秒の 720p 動画 | 120 | $0.30–$0.60 |
| minimax-h3 | 10 秒の 720p 動画 | 240 | $0.60–$1.20 |
| minimax-h3 | 15 秒の 720p 動画 | 360 | $0.90–$1.80 |
- 実際の課金はクレジットです。USD は目安で、クレジットパックの価格は料金ページが正となります。
- テキストは実際のトークン数で課金し、1 リクエストあたり最低 1 クレジットです。
- 動画は秒単位の課金で、長さは 4〜15 秒です。失敗したリクエストは課金されません。
- Starter・Pro・Premium の API 呼び出しはサブスクリプションまたは購入クレジットを使用し、サイト内無料枠は適用されません。Unlimited Images は Z-Image と Qwen Image(2K を含む)、Unlimited Videos は H3 720p、Studio は両方をカバーします。個人 API キーによる対象モデルの呼び出しは 0 クレジットで、残高も不要、予算も消費しません。その他のモデルは有料クレジットを使用し、チャネルキーは契約に基づく課金を継続します。ボーナスクレジットは使用できません。有料リクエストは上限額を予約し、完了後に未使用分を返却します。GET /models は標準のクレジット価格を表示し、テキストのドル単価はクレジット換算の基準です。キー予算は予約分を含む累計クレジット上限です。
Web のタスクが優先されます。空き容量がある場合のみ受付し、混雑時は課金せず 429 と Retry-After を返します。開始済みの推論は中断しません。API は動画の追加 VM を起動しません。1 アカウントにつき同時 1 リクエスト、1 キーにつき毎分 60 回まで送信できます。
モデルと制限
テキスト
モデル:qwen-27b。system/developer/user/assistant/tool メッセージ、テキスト配列、ユーザーメッセージの image_url に対応します。32,768 token の合計上限にはメッセージ、ツール定義、Schema 指示、画像、出力予約枠が含まれます。入力全体は画像データを除き 64,000 文字までです。PNG/JPEG/WebP は最大 10 枚、各 20 MiB、合計 64 MiB。審査と推論の前に長辺 1024 px 以下に正規化します。出力上限は非ストリーム 2,048 token、ストリーム 8,192 token。実際のモデル使用量で精算し、未使用の予約分を返還します。
画像
モデル:qwen-image(1K/2K、参照画像は最大 8 枚)と z-image(1K、テキストからの画像生成のみ)。1 リクエストあたりの枚数 n:qwen-image は 1K で最大 6 枚(参照画像ありは 4 枚)、2K は 1 枚;z-image は最大 8 枚。いずれもアカウントの同時生成上限以内です。プロンプトは最大 5,500 文字。比率:1:1、16:9、9:16、4:3、3:4、3:2、2:3。seed は 0–2147483647 を任意指定でき、バッチでは 1 枚ごとに増え、上限を超えると 0 に戻ります。バッチが一部だけ成功した場合は、納品した画像分のみ課金します。
動画
モデル:minimax-h3。テキスト、開始/終了フレーム、または参照メディアから動画を生成。720p、4〜15秒。seed は0〜2147483647。比率:16:9、9:16、1:1、4:3、3:4、21:9。auto には画像または動画が必要です。返されたIDを5秒間隔で確認してください。生成音声を含みますが、参照音声とのリップシンクは保証されません。外部ホストモデルや生成の自動再送は使用しません。
参照素材はリダイレクトしない公開 HTTP(S) URL に対応し、画像は PNG/JPEG/WebP の base64 data URL も使えます。1 リクエストのダウンロードはすべて 45 秒以内に完了する必要があります。1 ファイル 20 MiB、合計 64 MiB まで。画像はアニメーションなし、1,600 万画素以下で、向き補正後に長辺 2048 px 以内へ縮小します。動画は MP4/MOV(最大 4K)で、毎秒 24 フレーム・幅 1920 px 以下に再エンコードして全フレームを審査し、モデルにはその再エンコード後のファイルを渡します。音声は MP3/WAV。各クリップおよび種類ごとの合計は 15 秒以内です。審査データは 14 MiB 以内で、超える場合はクリップを圧縮してください。無効または審査できない素材は課金前に拒否します。
MiniMax は start_frame_url / end_frame_url、または reference_image_urls(最大9枚)、reference_video_urls(最大3本)、reference_audio_urls(最大3本)に対応。両モードの併用は不可、参照ファイルは合計12個まで。音声参照には画像または動画参照が必要です。画像5枚以上、動画または音声を含む場合は出力10秒まで、それ以外は15秒まで。GPUの条件容量によりさらに制限される場合があり、無効な組み合わせは課金前に拒否されます。フレーム入力は元画像の比率に従います。
画像は response_format=url(既定)または b64_json に対応します。size は auto、256x256、512x512、1024x1024、1536x1024、1024x1536、1792x1024、1024x1792、Qwen のみ 2048x2048。対応する生成サイズで描画後、拡縮と中央切り抜きで指定の正確な寸法に合わせます。2K 課金になるのは 2048x2048 のみです。resolution/aspect_ratio との矛盾は拒否されます。同じ Idempotency-Key で response_format を変えても再生成・再課金されません。
POST /videos は JSON と multipart に対応します。input_reference は PNG/JPEG/WebP ファイル、画像 URL/data URL、または image_url を持つオブジェクトを先頭フレームとして受け付けます。file_id は未対応です。size=1280x720 または 720x1280 は向きと最終 MP4 の正確な寸法を指定します。size を省略すればネイティブ比率を使用できます。状態は queued、in_progress、completed、failed、created_at は Unix 秒です。GET /videos/{id}/content は同じ API キーで MP4 を取得します。サムネイル、spritesheet、remix、延長は未対応です。GET /requests/{id} は従来の状態形式を維持します。
エンドポイント
| GET | /models | モデルと現在の料金 |
| GET | /balance | 有料残高・無制限対象モデル・キー予算 |
| POST | /chat/completions | テキスト生成(JSON または SSE) |
| POST | /images/generations | 同期画像生成(最大8枚) |
| POST | /images/edits | Qwen画像編集(JSONまたはmultipart) |
| POST | /videos | 容量確保済み動画タスクの受付(202) |
| GET | /videos/{id} | 動画の状態と結果を取得 |
| GET | /videos/{id}/content | 完了済み MP4 をダウンロード(認証必須) |
| GET | /requests/{id} | ID でリクエストを再取得 |
リクエスト例
テキスト
リクエスト
curl "$MONTAGEA_API_BASE/chat/completions" \
-H "Authorization: Bearer $MONTAGEA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: chat-example-1' \
-d '{"model":"qwen-27b","messages":[{"role":"user","content":"Describe a quiet mountain lake."}],"max_tokens":1024}'レスポンス
{
"id": "req_8c41d2",
"object": "chat.completion",
"created": 1793102400,
"model": "qwen-27b",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "The lake lies perfectly still..." },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": 18, "completion_tokens": 96, "total_tokens": 114 },
"montagea_usage": { "credits": 1 }
}画像
リクエスト
curl "$MONTAGEA_API_BASE/images/generations" \
-H "Authorization: Bearer $MONTAGEA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: image-example-1' \
-d '{"model":"qwen-image","prompt":"A quiet mountain lake at sunrise","resolution":"1K","aspect_ratio":"16:9","n":1}'レスポンス
{
"id": "req_5b07e9",
"created": 1793102400,
"data": [{ "url": "https://.../req_5b07e9.png" }],
"montagea_usage": { "credits": 20 }
}動画
リクエスト
curl "$MONTAGEA_API_BASE/videos" \
-H "Authorization: Bearer $MONTAGEA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: video-example-1' \
-d '{"model":"minimax-h3","prompt":"A quiet mountain lake at sunrise","seconds":5,"resolution":"720p","aspect_ratio":"16:9"}'
# Poll every 5 seconds with the returned id
curl "$MONTAGEA_API_BASE/videos/req_3f2a9c" \
-H "Authorization: Bearer $MONTAGEA_API_KEY"レスポンス
// POST /videos -> 202
{
"id": "req_3f2a9c",
"model": "minimax-h3",
"object": "video",
"kind": "video",
"status": "in_progress",
"created_at": 1793102400,
"progress": 0,
"seconds": "5",
"size": "1344x768",
"result": null,
"error": null,
"usage": { "credits": 0, "cost_nano_usd": null, "reserved_credits": 120 }
}
// GET /videos/req_3f2a9c once finished
{
"id": "req_3f2a9c",
"status": "completed",
"result": { "url": "https://.../req_3f2a9c.mp4", "seconds": 5 },
"error": null,
"usage": { "credits": 120, "cost_nano_usd": null, "reserved_credits": 0 },
...
}Qwen画像編集
POST /images/edits は reference_image_urls を含むJSON、または multipart の image / image[] ファイルに対応し、OpenAI SDK images.edit でも利用できます。qwen-image の POST /images/generations も reference_image_urls に対応します。resolution、aspect_ratio、seed、n は画像生成と共通です。Z-Image は参照画像や編集に対応しません。
curl "$MONTAGEA_API_BASE/images/edits" \
-H "Authorization: Bearer $MONTAGEA_API_KEY" \
-H 'Idempotency-Key: edit-example-2' \
-F 'model=qwen-image' \
-F 'prompt=Change the background to a sunny garden' \
-F '[email protected]' \
-F 'resolution=1K' \
-F 'seed=42'MiniMaxのフレームと参照メディア
// POST /videos (JSON): first/last frames
{
"model": "minimax-h3", "prompt": "A person turns toward the camera",
"start_frame_url": "https://your-storage.example/start.png",
"end_frame_url": "https://your-storage.example/end.png",
"seconds": 5, "seed": 42
}
// POST /videos (JSON): reference media, without first/last frames
{
"model": "minimax-h3", "prompt": "The person walks through the garden",
"reference_image_urls": ["https://your-storage.example/person.png"],
"reference_video_urls": ["https://your-storage.example/motion.mp4"],
"reference_audio_urls": ["https://your-storage.example/voice.wav"],
"seconds": 5, "seed": 42
}テキストは choices と usage、画像は data[].url または data[].b64_json を返します。非ストリーミング生成結果には montagea_usage.credits が含まれます。動画は object=video、progress、size、seconds と、完了後の result.url を返し、失敗時は error.code と error.message を返します。usage は請求済み・予約済みクレジットを保持します。X-Request-ID と Inference-Id は受理済みリクエストを識別します。ストレージ URL は共有可能ですが、content ダウンロードには所有 API キーが必要です。
OpenAI SDK で呼び出す
テキスト、画像生成・編集、動画の作成・取得・ポーリング・ダウンロードは OpenAI SDK に対応しています。base_url を Montagea に設定し、Montagea のモデル ID を使用します。追加のネイティブ設定は extra_body に渡します。動画の画像アップロードは input_reference、画像編集は image を使用します。
from openai import OpenAI
client = OpenAI(base_url="https://api.montagea.com/api/v1", api_key="mtg_...")
reply = client.chat.completions.create(
model="qwen-27b",
messages=[{"role": "user", "content": "Describe a quiet mountain lake."}],
max_tokens=1024,
extra_headers={"Idempotency-Key": "chat-example-2"},
)
print(reply.choices[0].message.content)
image = client.images.generate(
model="qwen-image",
prompt="A quiet mountain lake at sunrise",
n=1,
extra_body={"resolution": "1K", "aspect_ratio": "16:9"},
extra_headers={"Idempotency-Key": "image-example-2"},
)
print(image.data[0].url)
with open("portrait.png", "rb") as reference:
edited = client.images.edit(
model="qwen-image",
image=reference,
prompt="Change the background to a sunny garden",
extra_body={"resolution": "1K", "seed": 42},
extra_headers={"Idempotency-Key": "edit-example-1"},
)
print(edited.data[0].url)
encoded = client.images.generate(
model="qwen-image", prompt="A quiet lake",
size="1536x1024", response_format="b64_json",
extra_headers={"Idempotency-Key": "image-base64-1"},
)
import base64
with open("lake.png", "wb") as output:
output.write(base64.b64decode(encoded.data[0].b64_json))
video = client.videos.create_and_poll(
model="minimax-h3", prompt="A quiet lake at sunrise",
seconds="4", size="1280x720", poll_interval_ms=5000,
extra_headers={"Idempotency-Key": "video-sdk-1"},
)
if video.status == "completed":
client.videos.download_content(video.id).write_to_file("lake.mp4")
else:
print(video.error)関数ツールは auto、none、required、関数名指定の tool_choice と parallel_tool_calls に対応します。ツールは利用者のアプリで実行し、対応する tool_call_id を付けた role=tool メッセージで結果を返します。response_format は text、json_object、json_schema に対応し、検証済みの構造化出力だけを返します。通常テキストへの自動切り替えはありません。Schema は各 16,000 文字まで。循環しないローカル参照に対応し、外部参照、動的参照、正規表現の制約は非対応です。ツールの説明、引数、結果、Schema も審査対象です。
# Tool calls are returned to your app; Montagea does not execute them.
reply = client.chat.completions.create(
model="qwen-27b",
messages=[{"role": "user", "content": "What is the weather in Paris?"}],
tools=[{"type": "function", "function": {
"name": "get_weather", "strict": True,
"parameters": {
"type": "object", "properties": {"city": {"type": "string"}},
"required": ["city"], "additionalProperties": False,
},
}}],
tool_choice="required",
)
print(reply.choices[0].message.tool_calls)
structured = client.chat.completions.create(
model="qwen-27b",
messages=[{"role": "user", "content": "Return the city Paris."}],
response_format={"type": "json_schema", "json_schema": {
"name": "city", "strict": True,
"schema": {
"type": "object", "properties": {"city": {"type": "string"}},
"required": ["city"], "additionalProperties": False,
},
}},
)
print(structured.choices[0].message.content)
import base64
with open("portrait.png", "rb") as image:
image_url = "data:image/png;base64," + base64.b64encode(image.read()).decode()
vision = client.chat.completions.create(
model="qwen-27b",
messages=[{"role": "user", "content": [
{"type": "text", "text": "Describe this picture."},
{"type": "image_url", "image_url": {"url": image_url}},
]}],
)
print(vision.choices[0].message.content)テキストのストリーミング
stream=true はモデルのライブ出力を読み取ります。通常テキストは生成中に審査済みの部分を順次送信します。出力審査は最大 3 回で、毎回対話全体と生成済みの接頭部分を確認します。最初の確認点は約 80 文字と 1,024 文字、最後は残り全体です。ツール引数と JSON 出力は全体の検証後に送信します。stream_moderation=buffered では回答全体の審査後に送信します。保活コメントは最初の内容 token に含めず、5 秒未満の到着は保証しません。末尾 usage は既定で有効、stream_options.include_usage=false で無効にできます。切断しても推論は継続します。途中の拒否や中断では送信済みの内容を取り消せず、承認済み部分の記録された使用量だけを課金し、残りを返還します。同じ Idempotency-Key または GET /requests/{id} で記録を取得できます。部分結果の再試行は再生成せず、[DONE] 前に元のエラーを返します。
stream = client.chat.completions.create(
model="qwen-27b",
messages=[{"role": "user", "content": "Write a short poem about rain."}],
max_tokens=512,
stream=True,
stream_options={"include_usage": True},
extra_headers={"Idempotency-Key": "chat-stream-example-1"},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")エラーと再試行
エラーには error.code、error.message、error.type と従来の detail が含まれます。拒否されたリクエストと、審査済み出力が全くない生成失敗は課金されません。失敗したストリームには課金済みの承認部分が残る場合があり、/requests/{id} の result.montagea_usage.partial と usage で確認できます。artifact_unavailable は生成・課金済み結果の一時的な読み出し失敗です。同じ Idempotency-Key または動画 ID で再試行してください。model_capability_unavailable と tokenizer_unavailable は運営側の設定確認が必要です。streaming_price_unavailable は分割審査の費用をチャネル価格で賄えない状態です。stream_moderation=buffered を使用するか運営に連絡してください。支払いで審査を回避することはできません。
| 400 | content_not_allowed | プロンプトまたは応答に禁止コンテンツが含まれています。課金されません。 |
| 401 | invalid_api_key | キーがない、無効、または無効化されています。 |
| 402 | insufficient_credits · key_budget_exceeded | 有料クレジットまたはキー予算が不足しています。 |
| 403 | paid_account_required · model_not_allowed · account_suspended · channel_only | アカウントに支払い履歴がない、モデルがこのキーで許可されていない、アカウントが停止されている、またはこのキーが Poe ボット専用です(channel_only)。 |
| 404 | request_not_found | リクエスト ID が存在しないか、別のキーのものです。 |
| 409 | idempotency_conflict · request_in_progress · price_changed | 同じ Idempotency-Key で内容が異なる、元のリクエストがまだ処理中、または承認後に価格が変わりました。 |
| 410 | request_expired | リクエストから 30 日が経過し、内容が削除されたため再実行できません。 |
| 413 | reference_too_large | 参照ファイルまたはリクエストがサイズ上限を超えています。課金されません。 |
| 422 | invalid_request · invalid_reference · context_too_large · n_exceeds_limit | パラメータが無効、会話がコンテキスト上限を超えている、参照素材を読み込めない、または n がアカウントの同時生成上限を超えています(n_exceeds_limit)。 |
| 429 | capacity_busy · account_busy · rate_limit | 容量が混雑している、アカウントで別のリクエストが実行中、または毎分の上限に達しました。Retry-After の後に再試行してください。 |
| 500 | generation_failed · submission_failed | 生成または送信に失敗しました。予約したクレジットは返却済みです。 |
| 503 | api_unavailable · capacity_unavailable · content_check_unavailable · model_unavailable · artifact_unavailable · tokenizer_unavailable · model_capability_unavailable · streaming_price_unavailable | API、容量、審査サービス、または結果ファイルが一時的に利用できません。同じリクエストで後ほど再試行してください。 |
再試行と結果
生成ごとに一意の Idempotency-Key を送ります。通信中断後は同じキーと内容で元の処理を再取得できます。同じキーで内容を変更すると 409 になります。失敗した処理を再実行する場合は新しいキーが必要です。キーの無効化後も受付済みの処理は精算されます。
データとプライバシー
- プロンプト、応答、参照メディアのコピー、生成ファイルはリクエスト作成から30日後に自動削除され、課金記録のみ残ります。APIデータをモデルの学習に使用しません。
- プロンプト、入力画像・動画・音声、およびテキスト応答はGoogle Geminiに送信され、禁止コンテンツの審査を受けます。読み取りや審査ができない場合、生成前に拒否されます。
- 参照メディアのコピーと生成画像・動画はMontageaに保存され、30日後に削除されます。保存先URLはログイン不要の共有リンクとして扱ってください。