End-to-End-Beispiele

Zuletzt aktualisiert 23 May 2026

Vier End-to-End-Webhook-Beispiele, eine JSON-Bestätigung, ein Website-Formular, eine authentifizierte Abfrage und eine Verzweigung zwischen Ping und Event

Vollständige Durchläufe zum Übernehmen. Jedes zeigt die eingehende Anfrage, die Workflow-Schritte, die verwendeten Tokens und die Antwort.

Alle Beispiele setzen einen veröffentlichten virtuellen Workflow voraus, dessen Startschritt der Endpunkt-Listener ist (siehe Einen Endpunkt anlegen).

AUFRUFER Externes System POST /listener/… { amount: 2500 } 200 OK { "status": "ok" } Anfrage Antwort FLEXIE · VIRTUELLER WORKFLOW Entscheidung E-Mail nicht leer? Notiz erstellen am Kontakt Endpunkt-Antwort return_type: data SYNC-Ausführungsmodus __data.amount = 2500 Listener: return_type = continue · Auth: JWT aus · CORS aus

Beispiel 1: Einen Webhook empfangen und bestätigen

Ziel: Ein anderes System meldet Flexie, dass eine Rechnung erstellt wurde; Flexie hält eine Notiz am passenden Kontakt fest und antwortet mit „empfangen".

Die Anfrage, die das andere System sendet:

curl -X POST https://your-flexie/listener/abc123…/def456… \
  -H "Content-Type: application/json" \
  -d '{
        "invoice_amount": 2500,
        "customer_email": "john@example.com"
      }'

Der Workflow:

  1. Entscheidung (virtuelle Bedingung): {{ __data.customer_email }} ist nicht leer
    • Nein: Die Aktion Endpunkt-Antwort gibt {"error":"email required"} zurück.
    • Ja: weiter.
  2. Aktion, Notiz erstellen am per E-Mail gefundenen Kontakt, Inhalt: Invoice raised: {{ formatCurrency(__data.invoice_amount, "€") }}.
  3. Endpunkt-Antwort (return_type = data): { "status": "received" }.

Einstellungen des Endpunkt-Listeners: return_type = continue (damit Schritt 3 die Antwort erzeugt), Workflow-Ausführungsmodus = Sync.

Wichtig: Die Felder aus dem Body werden aus dem __data-Namensraum gelesen, {{ __data.customer_email }}, {{ __data.invoice_amount }}, nicht auf der obersten Ebene.

Beispiel 2: Einen Kontakt aus einem Website-Formular anlegen oder aktualisieren

Ziel: Ihre Website sendet eine Anmeldung; Flexie legt den Kontakt an, falls er neu ist, aktualisiert ihn, falls er bereits existiert, und leitet den Besucher auf eine Dankeseite weiter.

Die Anfrage (form-encoded, direkt aus einem Browser):

POST /listener/…/…
Content-Type: application/x-www-form-urlencoded

first_name=John&last_name=Doe&email=john@example.com

Einstellungen des Endpunkt-Listeners: allow_cors = on, cors_domains = https://www.yoursite.com (weil ein Browser ihn direkt aufruft); return_type = redirect; return_redirect = https://www.yoursite.com/thanks?email={{ __data.email | url_encode }}.

Der Workflow:

  1. Aktion, Wert speichern existing = {{ findOne("contact", "email", __data.email).id | default("") }}.
  2. Entscheidung (virtuelle Bedingung): {{ __data.existing }} ist nicht leer
    • Ja: Aktualisieren Sie first_name und last_name dieses Kontakts.
    • Nein: Erstellen Sie einen Kontakt aus {{ __data.first_name }}, {{ __data.last_name }}, {{ __data.email }}.

Die Weiterleitung (am Listener eingestellt) schickt den Besucher unabhängig vom Zweig weiter.

Wenn Sie statt einer Weiterleitung lieber JSON an ein Frontend-Skript zurückgeben möchten, setzen Sie return_type = data und geben Sie { "ok": true } zurück.

Beispiel 3: Eine kleine eigene Abfrage-API (authentifiziert)

Ziel: Ein internes Tool fragt Flexie nach dem Lifetime Value eines Kontakts und erhält JSON zurück. Nur das Tool darf sie aufrufen.

Einstellungen des Endpunkt-Listeners:

  • add_authentication = on; endpoint_key = internal-tools; endpoint_secret = ein starkes Geheimnis, das auch das Tool kennt.
  • return_type = continue; Workflow-Ausführungsmodus = Sync.

Die Anfrage:

curl https://your-flexie/listener/…/… \
  -H "Authorization: Bearer <JWT signed HS256, iss=internal-tools>" \
  -H "Content-Type: application/json" \
  -d '{ "contact_id": 42 }'

(Der Token muss mit HS256, HS384 oder HS512 signiert sein und iss = internal-tools enthalten.)

Der Workflow:

  1. Endpunkt-Antwort (return_type = data):
{
  "contact_id": {{ __data.contact_id }},
  "lifetime_value": {{ findDealsValue("contact", "won", "*", __data.contact_id) }},
  "open_cases": {{ getCaseStats("contact", __data.contact_id).open }}
}

Da der Workflow Sync läuft, wird die Antwort innerhalb der Anfrage erzeugt und direkt an das Tool zurückgegeben. Ein nicht authentifizierter oder falsch signierter Aufruf wird abgewiesen, bevor ein einziger Schritt läuft.

Beispiel 4: Die Antwort je nach Eingang verzweigen

Ziel: Ein einziger Endpunkt verarbeitet sowohl „Ping"-Health-Checks als auch echte Events.

Der Workflow:

  1. Entscheidung (virtuelle Bedingung): {{ __data.type }} ist gleich ping
    • Ja: Endpunkt-Antwort (data): { "pong": true }.
    • Nein: das echte Event verarbeiten, dann Endpunkt-Antwort (data): { "status": "processed" }.

Listener: return_type = continue, Workflow-Ausführungsmodus = Sync. Zwei verschiedene Antworten aus einem Endpunkt, ausgewählt durch eine virtuelle Bedingung.

Wiederkehrende Lehren aus diesen Beispielen

  • Body-Felder liegen unter __data ({{ __data.email }}); Header sind {{ __data.__headers.* }}; gespeicherte Werte sind {{ __data.* }}.
  • continue + Sync-Ausführungsmodus ist die Kombination für Request/Response-APIs.
  • Authentifizieren Sie alles, was echte Daten zurückgibt.
  • CORS aktivieren Sie nur, wenn ein Browser den Endpunkt direkt aufruft.
  • Sichern Sie eingehende Werte ab mit default(...) oder is defined, denn Aufrufer senden nicht immer das, was Sie erwarten.

Zurück zu