Daten empfangen

Zuletzt aktualisiert 23 May 2026

Eine eingehende Web-Anfrage wird in den __data-Namespace zerlegt, mit Body-Feldern, Headern und Werten aus früheren Schritten

Was Flexie akzeptiert

Wenn eine Anfrage Ihren Endpunkt erreicht, liest Flexie die Daten dort aus, wo sie liegen, und führt sie zu einem einzigen Satz von Werten zusammen. Flexie durchläuft die Anfrage in dieser Reihenfolge und nimmt das Erste, was zutrifft:

  1. Formularkodierte Daten: application/x-www-form-urlencoded (HTML-Formular-Posts) oder multipart/form-data (Formular-Posts mit Datei-Uploads). Die Formularfelder werden mit dem Query-String zusammengeführt.
  2. Ein JSON-Body: wenn die Anfrage JSON mitbringt. Wird dekodiert und mit dem Query-String zusammengeführt. Verschachtelte Objekte und Arrays bleiben erhalten (sodass order.items[0].sku mit dem richtigen Token erreichbar ist).
  3. Ein Roh-Body: alles andere (reiner Text, XML, CSV usw.). Der gesamte Body wird unter einem einzigen Feld gekapselt, damit Sie ihn als Text lesen können.
  4. Nur der Query-String: wenn kein Body vorhanden ist, ausschließlich die URL-Parameter.

Ob der Aufrufer also JSON, ein Formular oder nur Query-Parameter postet, die Felder landen immer am selben Ort. Sie konfigurieren das nicht. Es funktioniert einfach.

Akzeptierte Methoden

Der Endpunkt akzeptiert die Methoden, mit denen man einen Webhook-Empfänger erwartungsgemäß aufruft: GET, POST, PUT und OPTIONS (Letzteres ist der CORS-Preflight, der automatisch behandelt wird). Die oben beschriebene Reihenfolge der Body-Extraktion gilt unabhängig davon, welche Methode verwendet wird.

Wo jedes Element landet

Alles, was eine eingehende Anfrage mitbringt, also Body-Felder, Header und etwaige Zusätze, liegt unter dem __data-Namespace:

Was ankam Wie Sie es in einem Schritt auslesen
Ein Feld im Anfrage-Body {{ __data.field_name }}
Ein Anfrage-Header {{ __data.__headers.header_name }}
Ein Wert, den ein früherer Schritt abgelegt hat {{ __data.your_stored_name }}
Die ID des angemeldeten Nutzers (falls der Aufrufer eine Flexie-Sitzung hatte) {{ __data.__logged_in_user_id }}
Der Name des angemeldeten Nutzers (gleiche Bedingung) {{ __data.__logged_in_user_full_name }}
Zusätzliche Daten im JWT (falls authentifiziert und der Token einen data-Claim hatte) {{ __data.__headers.__jwt_data[0] }}

Body-Felder liegen hier nicht auf oberster Ebene. Sie liegen unter __data. Ein Anfrage-Body, der email enthält, wird also als {{ __data.email }} ausgelesen, nicht als {{ email }}. Auch Header und von Schritten erzeugte Werte liegen unter __data.

EINGEHENDER POST Content-Type: application/json Authorization: Bearer … { "email": "john@example.com", "amount": 2500, "type": "invoice" } ?utm_source=web (query) zerlegen __data (der Notizblock des Workflows) BODY + QUERY __data.email __data.amount __data.type __data.utm_source HEADER __data.__headers. content-type user-agent (keine Cookies, keine Auth) ZUSÄTZE __data.__headers.__jwt_data[0] __data.__logged_in_user_id

Beispiel

Ein Aufrufer postet dieses JSON:

{
  "invoice_amount": 2500,
  "customer_email": "john@example.com",
  "customer_name": "John Doe"
}

Innerhalb des Workflows lesen Sie aus:

{{ __data.invoice_amount }}     → 2500
{{ __data.customer_email }}     → john@example.com
{{ __data.customer_name }}      → John Doe
{{ __data.__headers.content-type }}  → application/json

Header, und was entfernt wird

Alle Anfrage-Header sind unter {{ __data.__headers.* }} verfügbar, bis auf einige, die aus Sicherheitsgründen entfernt und niemals offengelegt werden: Cookies und sämtliche Authentifizierungs-Credentials, die die Anfrage mitbringt.

Wenn Ihre Authentifizierung von etwas abhängt, das normalerweise in einem Cookie transportiert wird, senden Sie es stattdessen als eigenen Header oder als Teil des Bodys.

Arbeiten mit den Daten

Nutzen Sie das volle Flexie-Scripting-Toolkit auf dem, was ankam. Häufige Anforderungen:

Gegen fehlende Felder absichern, ein Aufrufer könnte etwas auslassen:

{{ __data.customer_email | default("") }}
{% if __data.invoice_amount is defined and __data.invoice_amount %}…{% endif %}

Einen JSON-Wert dekodieren, der als Text ankam (zum Beispiel eine verschachtelte Struktur, die als String übergeben wurde):

{% set order = __data.body_field | json_decode %}
First item: {{ jsonPath(order, "$.items[0].name") }}

Einen passenden gespeicherten Datensatz aus einem eingehenden Wert nachschlagen und dann darauf reagieren:

{% set existing = findOne("contact", "email", __data.customer_email) %}
{% if existing %}
  Found contact {{ existing.id }}
{% endif %}

Authentifizierte Aufrufe und der JWT-Data-Claim

Wenn am Endpunkt die Authentifizierung aktiviert ist, wird der Token des Aufrufers verifiziert, bevor irgendein Schritt läuft:

  • Der Token muss im Header Authorization: Bearer <token> stehen (ein einfacher token-Header wird ebenfalls akzeptiert).
  • Er muss mit HS256, HS384 oder HS512 und dem endpoint_secret des Listeners signiert sein.
  • Sein iss-Claim (Issuer) muss dem endpoint_key des Listeners entsprechen.
  • Für geringe Zeitunterschiede zwischen Aufrufer und Flexie wird eine Toleranz von 60 Sekunden gewährt.

Ein Token, der fehlt, ungültig oder abgelaufen ist oder dessen Issuer nicht passt, wird abgewiesen, bevor irgendein Workflow-Schritt läuft. Ihr Workflow bekommt diese Anfragen gar nicht zu sehen. Das vollständige Protokoll, die Fehler-Statuscodes und Code-Beispiele zum Erstellen von Tokens in allen gängigen Sprachen finden Sie unter Authentifizierung & CORS im Detail.

Wenn der Aufrufer einen data-Claim in den Token aufnimmt, wird dessen Inhalt dem Workflow unter dem Header-Namespace bereitgestellt. Da Header-Werte als Liste gespeichert werden (ein Eintrag pro Vorkommen), greifen Sie mit [0] darauf zu:

{# Token's payload was { "iss":"internal-tools", "data": { "tenant":"acme" } } #}
{{ __data.__headers.__jwt_data[0].tenant }}   →  acme

Das ist nützlich, um Metadaten einer Anfrage zu transportieren, die nicht zum Body gehören, etwa eine Tenant-ID, ein Feature-Flag oder eine Akteur-Identität, ohne sie fest in jeden Anfrage-Body schreiben zu müssen.

Was in __data landet, zusammengefasst

Pfad Wann er gesetzt ist
{{ __data.<field_name> }} Bei jeder Anfrage, Body-Felder und Query-Parameter
{{ __data.__headers.* }} Bei jeder Anfrage, alle Header außer Cookies und Credentials
{{ __data.__logged_in_user_id }} / {{ __data.__logged_in_user_full_name }} Der Aufrufer kam mit einer gültigen Flexie-Sitzung
{{ __data.__headers.__jwt_data[0] }} Der Endpunkt verlangt JWT-Auth und der Token des Aufrufers enthielt einen data-Claim
{{ __data.<your_name> }} Ein früherer Schritt im Workflow hat einen Wert unter <your_name> abgelegt
{{ __data.__entity_inserted_id }} / {{ __data.__entity_type }} Ein früherer Schritt hat einen Datensatz erstellt

Wie die Daten weiterfließen

Alles, was Ihre Schritte ablegen (mit der Aktion Wert ablegen) oder erzeugen (die ID eines erstellten Datensatzes, eine Webhook-Antwort), kommt auf denselben __data-Notizblock und steht späteren Schritten zur Verfügung, genau wie in jedem Workflow. Siehe Daten zwischen Schritten weitergeben.

Ein typischer Endpunkt-Workflow sieht also so aus:

  1. liest die eingehenden Body-Felder ({{ __data.… }}),
  2. schlägt daraus echte Datensätze nach oder erstellt sie,
  3. legt benötigte IDs oder Werte ab (__data.…),
  4. verzweigt darauf mit einer virtuellen Bedingung,
  5. und antwortet dem Aufrufer optional.

Nächste Schritte