MyBotBoxMyBotBox

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 auf maxPromptLength (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.*>:

AusgabeTypBeschreibung
promptstringDer Prompt des Aufrufers, bereinigt und längenvalidiert
contextjson | nullDas context-Objekt oder null, wenn nicht angegeben
metadatajson | nullDas metadata-Objekt oder null, wenn nicht angegeben
requestIdstringServerseitig generierte ID — wird in Logs/Traces weitergegeben
callerstringAbgeleitete Aufruferidentität (bearer-hash / header-hash / hmac-hash / IP)
timestampstringISO-8601-Empfangszeit des Servers
guardrailsTriggeredbooleanTrue, wenn ein bekanntes Prompt-Injection-Muster erkannt wurde
matchedInjectionPatternsarrayNamen der erkannten Muster (leer, wenn keines zutrifft)

Authentifizierung

Unterstützt dieselben 4 Modi wie der generische Webhook-Trigger:

ModusGesendeter HeaderGeeignet für
noneÖffentliche Endpunkte, interne Tools hinter einem anderen Gateway
bearerAuthorization: Bearer <token>Programmatische KI-Aufrufer — empfohlener Standard
custom_header<konfigurierter-Name>: <token>Anpassung an bestehende Konventionen
hmac_sha256X-Signature: <hex> über den rohen BodyMaximale 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 du 401 — 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 Wiederholungsversuche 200 { "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:

  1. Webhook-URLhttps://staging-app.mybotbox.com/api/webhooks/prompt/<path>
  2. HMAC-Secret — der Wert, den du in das Feld „HMAC secret" eingegeben hast
  3. Name des Signatur-HeadersX-Signature (Standard) oder welchen benutzerdefinierten Namen du festgelegt hast
  4. Body-Vertrag — die Form { prompt: string, context?: object, metadata?: object }, dein konfiguriertes maxPromptLength sowie ob requireContext aktiviert 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:

  1. 1Password / Bitwarden shared item — auf die E-Mail-Adresse des Empfängers beschränkt, mit Ablaufdatum. Die meisten Teams haben dies bereits im Einsatz.
  2. Verschlüsselte Nachricht — Signal oder gpg --encrypt --recipient <them@…>, dann den Geheimtext über einen beliebigen Kanal senden.
  3. Einmaliger Secret-Linkhttps://onetimesecret.com oder ein selbst gehostetes Äquivalent. Einmalige Ansicht, automatische Vernichtung nach wenigen Minuten.
  4. 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 wie 1234567890 sind 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-Timestamp mehr als N Sekunden von der Serverzeit abweicht. Standard 300s, 0 deaktiviert.
  • Idempotenz: Wenn aktiviert, geben doppelte Requests (abgeglichen über X-Idempotency-Key, Body-id oder 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 429 mit Retry-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

  1. API Prompt-Trigger (dieser Block) — Aufrufer sendet { prompt, context }.
  2. Agent / LLM-Block — empfängt <apiprompt1.prompt> und <apiprompt1.context>, plant nächste Aktionen mithilfe von Tool-Calling.
  3. Nachgelagerte Aktionsblöcke (E-Mail, Datenbank, Drittanbieter-APIs) — führen den Plan aus.
  4. 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 istDer Body strukturiertes JSON mit festen Feldern ist
Der erste Block ein LLM/Agent ist, der plantDer erste Block eine Bedingung / Datenbankoperation ist
Der Aufrufer ein KI-System oder Chatbot istDer Aufrufer ein Dienst ist, der Ereignisse sendet
Du Guardrails + per-Caller-Rate-Limits von Haus aus möchtestDu 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.