API Prompt
AIファーストなワークフロー向けの自然言語HTTPトリガー。
API Prompt トリガーは、自然言語のプロンプト(オプションで構造化されたコンテキストやメタデータも含む)を受け付けるHTTPエンドポイントを公開し、それらのフィールドをブロック出力として利用できる状態でワークフローを実行します。「JSONスキーマを埋める」のではなく「ワークフローとチャットする」ような感覚をAPIに持たせたい場合に最適なトリガーです。
リクエスト仕様
POST /api/webhooks/prompt/{path}
Content-Type: application/json
{
"prompt": "Summarize these PDFs and email me the result",
"context": { "pdf_ids": ["abc", "def"] },
"metadata": { "request_origin": "internal-app-v2" }
}prompt(string、必須)— 自然言語の指示。maxPromptLength(デフォルト10,000文字、ハード上限50,000文字)で制限されます。context(object、任意)— 任意のJSON。IDやファイルパス、ユーザープロフィールなど、構造化された参照情報をプロンプトと一緒に渡すために使用します。metadata(object、任意)— ルーティングやロギングのために記録しておきたい、呼び出し元が提供する識別子。
トップレベルの追加フィールドは無視されます。contextおよびmetadata内のネストされたJSONは保持されます。
ブロック出力
下流のブロックから <apiprompt1.*> として参照できます:
| 出力 | 型 | 説明 |
|---|---|---|
prompt | string | 呼び出し元のプロンプト(トリムおよび長さ検証済み) |
context | json | null | contextオブジェクト、未指定の場合はnull |
metadata | json | null | metadataオブジェクト、未指定の場合はnull |
requestId | string | サーバー生成のID — ログ/トレースに伝播される |
caller | string | 導出された呼び出し元のID(bearer-hash / header-hash / hmac-hash / IP) |
timestamp | string | ISO-8601形式のサーバー受信時刻 |
guardrailsTriggered | boolean | 既知のプロンプトインジェクションパターンに一致した場合にTrue |
matchedInjectionPatterns | array | 一致したパターン名の配列(なければ空) |
認証
汎用Webhookトリガーと同じ4つのモードをサポートしています:
| モード | 送信ヘッダー | 適したケース |
|---|---|---|
none | — | パブリックエンドポイント、別のゲートウェイの背後にある内部ツール |
bearer | Authorization: Bearer <token> | プログラムによるAI呼び出し元 — 推奨デフォルト |
custom_header | <configured-name>: <token> | レガシー規約への対応 |
hmac_sha256 | X-Signature: <hex>(生ボディに対して) | 最高の保証 — ステートレスかつリプレイ保護付き |
bash / Node / Python での署名例については Webhooks → 認証 を参照してください。
呼び出し元向けクイックスタート — HMAC
HMAC-SHA256 認証を設定すると、プラットフォームはリクエストボディの正確な生バイトを共有シークレットで署名したHEXダイジェストを X-Signature ヘッダー(または Signature header で設定した任意の名前)で受け取ることを期待します。
署名は実際にネットワークで送信するバイト列を対象にする必要があります。HTTPクライアントがJSONを再シリアライズ(キーの並べ替え、空白の削除、Unicodeエスケープの違いなど)すると、署名が一致しません。ボディ文字列を一度だけ組み立て、その文字列に署名し、その文字列を送信してください。curlでは --data-raw を使用し、Pythonでは json.dumps(...).encode() で事前エンコードして data=body を渡し、Nodeでは文字列を組み立てて fetch の body として渡します。
curl
WEBHOOK_URL="https://staging-app.mybotbox.com/api/webhooks/prompt/<path>"
SECRET="<your HMAC secret>"
BODY='{"prompt":"Summarize last week of standup notes","context":{"team":"platform"}}'
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $NF}')
curl -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-H "X-Signature: $SIGNATURE" \
-H "X-Timestamp: $TIMESTAMP" \
--data-raw "$BODY"注意事項:
X-Timestamp(Unix秒またはISO-8601形式)は、トリガーのリプレイウィンドウが有効(デフォルト300秒)な場合に必須です。指定しないと401 — timestamp outside replay windowが返されます。sha256=プレフィックスは受け付けられますが必須ではありません — サーバーは大文字小文字を区別せずに除去します。X-Idempotency-Key: <your-request-id>は任意ですが、リトライ時にワークフローを再実行せず200 { "status": "duplicate" }を返すために推奨されます。
Python
import hmac, hashlib, json, time, requests
WEBHOOK_URL = "https://staging-app.mybotbox.com/api/webhooks/prompt/<path>"
SECRET = b"<your HMAC secret>"
body = json.dumps(
{"prompt": "Summarize last week of standup notes", "context": {"team": "platform"}},
separators=(",", ":"),
).encode()
sig = hmac.new(SECRET, body, hashlib.sha256).hexdigest()
resp = requests.post(
WEBHOOK_URL,
data=body,
headers={
"Content-Type": "application/json",
"X-Signature": sig,
"X-Timestamp": str(int(time.time())),
"X-Idempotency-Key": "req-2026-05-17-001",
},
)
print(resp.status_code, resp.text)Node.js / TypeScript
import { createHmac } from 'node:crypto'
const WEBHOOK_URL = 'https://staging-app.mybotbox.com/api/webhooks/prompt/<path>'
const SECRET = process.env.MBB_HMAC_SECRET! // never hardcode
const body = JSON.stringify({
prompt: 'Summarize last week of standup notes',
context: { team: 'platform' },
})
const sig = createHmac('sha256', SECRET).update(body).digest('hex')
const res = await fetch(WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Signature': sig,
'X-Timestamp': Math.floor(Date.now() / 1000).toString(),
},
body,
})
console.log(res.status, await res.text())呼び出し元へのオンボーディング
API Promptトリガーへのアクセスをサードパーティに付与する際は、4つの情報だけを共有してください — それ以外は渡さないようにします:
- Webhook URL —
https://staging-app.mybotbox.com/api/webhooks/prompt/<path> - HMACシークレット — 「HMAC secret」フィールドに入力した値
- 署名ヘッダー名 —
X-Signature(デフォルト)またはカスタムで設定した名前 - ボディ仕様 —
{ prompt: string, context?: object, metadata?: object }の形式、設定済みのmaxPromptLength、およびrequireContextが有効かどうか
シークレットを安全に共有する方法
HMACシークレットはすべての呼び出しを認証します。漏洩すると、誰でも任意のプロンプトでワークフローを実行できてしまいます。データベースのパスワードと同様に扱ってください。
やってはいけないこと:
- メールやSlackで平文のまま送信する
- 共有ドキュメント(Notion、Confluence、Google Docs)に貼り付ける
- どのリポジトリにもコミットする(プライベートであっても)
- ステージングと本番で同じシークレットを使い回す
推奨する方法(優先順位順):
- 1Password / Bitwarden の共有アイテム — 受信者のメールアドレスにスコープを絞り、有効期限を設定する。多くのチームがすでにこの仕組みを持っています。
- 暗号化メッセージ — Signalを使うか、
gpg --encrypt --recipient <them@…>で暗号化してから暗号文をいずれかのチャネルで送信する。 - ワンタイムシークレットリンク —
https://onetimesecret.comまたはセルフホスト版。一度しか閲覧できず、数分後に自動消滅する。 - ビデオ通話中に口頭で伝える — 受信者がライブで自分のシークレットストアに貼り付け、その後双方がシェアを閉じる。書き留めるものは何もない。
運用上のベストプラクティス
- 強力なシークレットを生成する:
openssl rand -hex 32(256ビット)。1234567890のようなプレースホルダーは最初の動作確認には使えますが、外部に共有する前にローテーションしてください。 - 90日ごとにローテーションする。または呼び出し元がオフボードした場合は直ちに実施する。トリガーUIでシークレットを更新して保存し、呼び出し元に通知します。保存した瞬間に古い署名は無効になります — 猶予期間が必要な場合は、切り替え期間中に2つのトリガーを並行稼働させてください。
- 呼び出し元に保管場所を伝える:シークレットマネージャー(AWS Secrets Manager / GCP Secret Manager / HashiCorp Vault / Doppler)またはCIの環境変数ストア。ソースコードには絶対に入れないよう伝える。
- ローテーション後はログを監視する:401エラーが急増した場合、ほとんどの場合は呼び出し元がローテーションの通知を見逃しています。
トリガーUIに現在表示されているURLが正規のエンドポイントです:
/api/webhooks/prompt/<path>。以前のバージョンですべてのトリガータイプに使用されていた古い /api/webhooks/trigger/<path> 形式も後方互換性のために引き続き動作します — どちらのルートも同じHMAC検証とセーフガードを共有しています。インテグレーションを文書化する際は /prompt/ 形式を優先してください。
リプレイ保護、べき等性、レート制限
- リプレイウィンドウ(HMACモードのみ):
X-Timestampがサーバー時刻からN秒以上離れているリクエストを拒否します。デフォルト300秒、0で無効化。 - べき等性:有効な場合、重複リクエスト(
X-Idempotency-Key、ボディのid、またはボディハッシュで照合)は200 { status: "duplicate" }を返し、ワークフローは再実行されません。重複排除ウィンドウは7日間。 - 呼び出し元ごとのレート制限:デフォルト20リクエスト/分、導出された呼び出し元IDをキーにします。超過すると
Retry-Afterヘッダー付きの429が返されます。
プロンプトインジェクションガードレール
有効時(デフォルトオン)、プラットフォームは一般的なインジェクションパターン(ignore previous instructions、system: プレフィックス、チャットテンプレートマーカーなど)の小規模な拒否リストに対してプロンプトをスキャンし、結果を guardrailsTriggered および matchedInjectionPatterns として公開します。ガードレールは非ブロッキング — ワークフローは引き続き実行されます — ので、拒否するか、人間によるレビューにルーティングするか、続行するかをワークフローごとに決定できます。
ガードレールはベストエフォートのプリフィルターであり、LLM側の防御策の代替ではありません。下流のブロックでは常にプロンプトを信頼できない入力として扱ってください。高リスクな操作(メール送信、コード実行、有料APIの呼び出し)では、明示的な確認ステップを追加するか、guardrailsTriggered がtrueの場合はレビューにルーティングしてください。
典型的なワークフロー構成
- API Prompt トリガー(このブロック)— 呼び出し元が
{ prompt, context }をPOSTする。 - Agent / LLM ブロック —
<apiprompt1.prompt>と<apiprompt1.context>を受け取り、ツール呼び出しを使って次のアクションを計画する。 - 下流のアクションブロック(メール、データベース、サードパーティAPI)— 計画を実行する。
- Response ブロック — エージェントのサマリーを元の呼び出し元に返す。
例 — PDF要約ツール
curl -X POST https://staging-app.mybotbox.com/api/webhooks/prompt/abc123 \
-H 'Authorization: Bearer $MBB_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "Summarize these PDFs into bullet points and email to team@example.com",
"context": {
"pdf_gcs_paths": [
"gs://my-bucket/docs/report-2026-q1.pdf",
"gs://my-bucket/docs/report-2026-q2.pdf"
]
}
}'ワークフローの設定:
- API Prompt ブロック → Agent(Claude Haiku) ブロック(ツール
[gcs_read_file, gmail_send]とシステムプロンプト"Follow the user's instructions. Use tools as needed."を設定)。 - エージェントのユーザーメッセージ:
<apiprompt1.prompt>\n\nContext: <apiprompt1.context>。
バンドルされたスクリプトで動作確認する
# Bearer token mode (recommended default).
bun apps/sat/tests/staging/triggers/api_prompt/verify.ts \
https://staging-app.mybotbox.com/api/webhooks/prompt/<path> \
--secret=<bearer-token>
# Or HMAC mode.
bun apps/sat/tests/staging/triggers/api_prompt/verify.ts \
https://staging-app.mybotbox.com/api/webhooks/prompt/<path> \
--hmac=<hmac-secret>python3 apps/sat/tests/staging/triggers/api_prompt/verify.py \
https://staging-app.mybotbox.com/api/webhooks/prompt/<path> \
--secret=<bearer-token>ソース:apps/sat/tests/staging/triggers/api_prompt/。
API Prompt と汎用Webhook の使い分け
| API Prompt を使うべき場合… | 汎用Webhook を使うべき場合… |
|---|---|
| ボディがプロンプト+コンテキスト | ボディが固定フィールドの構造化JSON |
| 最初のブロックがLLM/エージェントで計画を立てる | 最初のブロックがCondition / Databaseアクション |
| 呼び出し元がAIシステムやチャットボット | 呼び出し元がイベントをPOSTするサービス |
| ガードレールと呼び出し元ごとのレート制限をすぐに使いたい | プロバイダースタイルのHMAC+重複排除が欲しい |
ボディフィールドがワークフロー変数に1:1でマップされる場合は汎用Webhookの方がシンプルで高速です。LLMをルーターにしたい場合はAPI Promptを使用してください。