API Prompt
Natürlichsprachlicher HTTP-Trigger für KI-orientierte Workflows.
Der API Prompt-Trigger stellt einen HTTP-Endpunkt bereit, der einen natürlichsprachlichen Prompt (plus optionalen strukturierten Kontext und Metadaten) entgegennimmt und einen Workflow ausführt, wobei diese Felder als Block-Ausgaben verfügbar sind. Dieser Trigger ist die richtige Wahl, wenn sich deine API eher wie „Chat mit einem Workflow" anfühlen soll als wie „dieses JSON-Schema ausfüllen".
Request-Vertrag
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, erforderlich) — natürlichsprachliche Anweisung. Begrenzt aufmaxPromptLength(Standard 10.000 Zeichen, Maximallimit 50.000).context(object, optional) — beliebiges JSON. Verwende es, um strukturierte Referenzen (IDs, Dateipfade, Benutzerprofil) zusammen mit dem Prompt zu übergeben.metadata(object, optional) — vom Aufrufer bereitgestellte Bezeichner, die für Routing/Logging sichtbar sein sollen.
Alle weiteren Top-Level-Felder werden ignoriert. Verschachteltes JSON innerhalb von context und metadata bleibt erhalten.
Block-Ausgaben
In nachgelagerten Blöcken verfügbar über <apiprompt1.*>:
| Ausgabe | Typ | Beschreibung |
|---|---|---|
prompt | string | Der Prompt des Aufrufers, bereinigt und längenvalidiert |
context | json | null | Das context-Objekt oder null, wenn nicht angegeben |
metadata | json | null | Das metadata-Objekt oder null, wenn nicht angegeben |
requestId | string | Serverseitig generierte ID — wird in Logs/Traces weitergegeben |
caller | string | Abgeleitete Aufruferidentität (bearer-hash / header-hash / hmac-hash / IP) |
timestamp | string | ISO-8601-Empfangszeit des Servers |
guardrailsTriggered | boolean | True, wenn ein bekanntes Prompt-Injection-Muster erkannt wurde |
matchedInjectionPatterns | array | Namen der erkannten Muster (leer, wenn keines zutrifft) |
Authentifizierung
Unterstützt dieselben 4 Modi wie der generische Webhook-Trigger:
| Modus | Gesendeter Header | Geeignet für |
|---|---|---|
none | — | Öffentliche Endpunkte, interne Tools hinter einem anderen Gateway |
bearer | Authorization: Bearer <token> | Programmatische KI-Aufrufer — empfohlener Standard |
custom_header | <konfigurierter-Name>: <token> | Anpassung an bestehende Konventionen |
hmac_sha256 | X-Signature: <hex> über den rohen Body | Maximale Sicherheit — zustandslos, Replay-geschützt |
Siehe Webhooks → Authentifizierung für Signierungsbeispiele in bash / Node / Python.
Aufrufen von einem Consumer — HMAC-Schnellstart
Wenn du HMAC-SHA256-Authentifizierung konfigurierst, erwartet die Plattform einen Hex-Digest der exakten rohen Bytes deines Request-Bodys, signiert mit deinem gemeinsamen Secret, gesendet im X-Signature-Header (oder welchen Namen du unter Signature header festgelegt hast).
Die Signatur muss die tatsächlich übertragenen Bytes abdecken. Wenn dein HTTP-Client das JSON neu serialisiert (Schlüssel umsortiert, Whitespace entfernt, Unicode anders escapet), stimmt die Signatur nicht mehr überein. Baue den Body-String einmalig auf, signiere diesen String und sende diesen String. Verwende in curl --data-raw. In Python kodiere vorher mit json.dumps(...).encode() und übergib data=body. In Node erstelle den String und übergib ihn als body an fetch.
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"Hinweise:
X-Timestamp(Unix-Sekunden oder ISO-8601) ist erforderlich, wenn das Replay-Fenster des Triggers aktiviert ist (Standard 300s). Ohne diesen Header erhältst du401 — timestamp outside replay window.- Das Präfix
sha256=wird akzeptiert, ist aber nicht erforderlich — der Server entfernt es unabhängig von der Groß-/Kleinschreibung. X-Idempotency-Key: <deine-request-id>ist optional, aber empfohlen, damit Wiederholungsversuche200 { "status": "duplicate" }zurückgeben, anstatt den Workflow erneut auszulösen.
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())Einen Consumer einbinden
Wenn du einem Dritten Zugang zu einem deiner API Prompt-Trigger gibst, teile genau vier Dinge — und nichts darüber hinaus:
- Webhook-URL —
https://staging-app.mybotbox.com/api/webhooks/prompt/<path> - HMAC-Secret — der Wert, den du in das Feld „HMAC secret" eingegeben hast
- Name des Signatur-Headers —
X-Signature(Standard) oder welchen benutzerdefinierten Namen du festgelegt hast - Body-Vertrag — die Form
{ prompt: string, context?: object, metadata?: object }, dein konfiguriertesmaxPromptLengthsowie obrequireContextaktiviert ist
So teilst du das Secret sicher
Das HMAC-Secret authentifiziert jeden Aufruf. Wenn es durchsickert, kann jeder deinen Workflow mit beliebigen Prompts auslösen. Behandle es wie ein Datenbankpasswort.
Nicht empfohlen:
- Per E-Mail oder Slack im Klartext versenden
- In geteilte Dokumente einfügen (Notion, Confluence, Google Docs)
- In ein Repository committen, auch nicht in private
- Dasselbe Secret für Staging und Produktion wiederverwenden
Empfohlen, in Reihenfolge der Präferenz:
- 1Password / Bitwarden shared item — auf die E-Mail-Adresse des Empfängers beschränkt, mit Ablaufdatum. Die meisten Teams haben dies bereits im Einsatz.
- Verschlüsselte Nachricht — Signal oder
gpg --encrypt --recipient <them@…>, dann den Geheimtext über einen beliebigen Kanal senden. - Einmaliger Secret-Link —
https://onetimesecret.comoder ein selbst gehostetes Äquivalent. Einmalige Ansicht, automatische Vernichtung nach wenigen Minuten. - Vorlesen in einem Videoanruf — der Empfänger gibt es direkt in seinen eigenen Secret-Store ein, dann schließt ihr beide den Share. Nichts wird aufgeschrieben.
Betriebshygiene
- Starkes Secret generieren:
openssl rand -hex 32(256 Bit). Platzhalter wie1234567890sind für den ersten Rauchtest in Ordnung, aber rotiere das Secret, bevor du es extern teilst. - Alle 90 Tage rotieren, oder sofort wenn ein Consumer ausscheidet. Aktualisiere das Secret in der Trigger-Oberfläche, speichere, und benachrichtige deinen Consumer. Alte Signaturen hören im Moment des Speicherns auf zu funktionieren — wenn du ein Übergangsfenster benötigst, betreibe während der Umstellung zwei Trigger parallel.
- Consumers mitteilen, wo das Secret gespeichert werden soll: in ihrem Secret-Manager (AWS Secrets Manager / GCP Secret Manager / HashiCorp Vault / Doppler) oder ihrem CI-Umgebungsvariablen-Store. Niemals im Quellcode.
- Nach der Rotation die Logs beobachten: ein plötzlicher Anstieg von 401-Fehlern bedeutet meist, dass ein Consumer die Rotationsnachricht verpasst hat.
Die URL, die die Trigger-Oberfläche heute anzeigt, ist der kanonische Endpunkt:
/api/webhooks/prompt/<path>. Die ältere Form /api/webhooks/trigger/<path> (die die
Oberfläche in früheren Versionen für jeden Trigger-Typ ausgegeben hat) funktioniert noch
zur Rückwärtskompatibilität — beide Routen teilen dieselbe HMAC-Verifizierung und
Sicherheitsmechanismen. Bevorzuge die /prompt/-Form beim Dokumentieren von Integrationen.
Replay-Schutz, Idempotenz und Rate-Limiting
- Replay-Fenster (nur HMAC-Modus): Requests ablehnen, bei denen
X-Timestampmehr als N Sekunden von der Serverzeit abweicht. Standard 300s,0deaktiviert. - Idempotenz: Wenn aktiviert, geben doppelte Requests (abgeglichen über
X-Idempotency-Key, Body-idoder Body-Hash)200 { status: "duplicate" }zurück, ohne den Workflow erneut auszuführen. Deduplizierungsfenster: 7 Tage. - Per-Caller-Rate-Limit: Standard 20 Requests/Min, basierend auf der abgeleiteten Aufruferidentität. Löst
429mitRetry-After-Header aus, wenn überschritten.
Prompt-Injection-Guardrails
Wenn aktiviert (Standard: an), scannt die Plattform den Prompt gegen eine kleine Deny-List bekannter Injection-Muster (ignore previous instructions, system:-Präfix, Chat-Template-Marker usw.) und stellt das Ergebnis als guardrailsTriggered und matchedInjectionPatterns bereit. Die Guardrails sind nicht blockierend — der Workflow läuft trotzdem — sodass du pro Workflow entscheiden kannst, ob du ablehnst, zur manuellen Prüfung weiterleitest oder fortfährst.
Guardrails sind ein Best-Effort-Vorfilter und kein Ersatz für LLM-seitige Abwehrmaßnahmen. Behandle den Prompt in nachgelagerten Blöcken immer als nicht vertrauenswürdige Eingabe. Bei riskanten Operationen (E-Mails versenden, Code ausführen, kostenpflichtige APIs aufrufen) füge explizite Bestätigungsschritte hinzu oder leite zur Prüfung weiter, wenn guardrailsTriggered true ist.
Typische Workflow-Struktur
- API Prompt-Trigger (dieser Block) — Aufrufer sendet
{ prompt, context }. - Agent / LLM-Block — empfängt
<apiprompt1.prompt>und<apiprompt1.context>, plant nächste Aktionen mithilfe von Tool-Calling. - Nachgelagerte Aktionsblöcke (E-Mail, Datenbank, Drittanbieter-APIs) — führen den Plan aus.
- Response-Block — gibt die Zusammenfassung des Agenten an den ursprünglichen Aufrufer zurück.
Beispiel — PDF-Zusammenfassung
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"
]
}
}'Workflow-Konfiguration:
- API Prompt-Block → Agent (Claude Haiku)-Block mit Tools
[gcs_read_file, gmail_send]und System-Prompt"Follow the user's instructions. Use tools as needed.". - Benutzernachricht des Agenten:
<apiprompt1.prompt>\n\nContext: <apiprompt1.context>.
Mit den mitgelieferten Skripten verifizieren
# 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>Quelle: apps/sat/tests/staging/triggers/api_prompt/.
Wann API Prompt vs. generischer Webhook verwenden
| Verwende API Prompt, wenn… | Verwende Generic Webhook, wenn… |
|---|---|
| Der Body ein Prompt + Kontext ist | Der Body strukturiertes JSON mit festen Feldern ist |
| Der erste Block ein LLM/Agent ist, der plant | Der erste Block eine Bedingung / Datenbankoperation ist |
| Der Aufrufer ein KI-System oder Chatbot ist | Der Aufrufer ein Dienst ist, der Ereignisse sendet |
| Du Guardrails + per-Caller-Rate-Limits von Haus aus möchtest | Du Provider-artiges HMAC + Deduplizierung möchtest |
Generic Webhook ist einfacher und schneller, wenn die Body-Felder 1:1 auf Workflow-Variablen abgebildet werden. Verwende API Prompt, wenn das LLM der Router sein soll.