Process-Engine API — Drittanbieter-Schnittstelle
Status: Phase 4.6 (2026-04-30) — public ab Production-Deploy. OpenAPI-Spec: GET https://api.prilog.chat/api/platform/v1/process/openapi.json
Konzept in 30 Sekunden
Die Process-Engine ist Prilogs interne Workflow-Plattform — sie läuft Flow-Designer, Konzept-Framework und Krisenmanagement (intern als „Apps"). Drittanbieter können dieselbe Engine nutzen, um eigene Workflows zu definieren und auszuführen.
ProcessTemplate (Vorlage, versioniert)
└── ProcessComponent (Schritte: Trigger, Action, Condition)
└── ProcessEdge (Übergänge mit optionaler Condition)
ProcessInstance (laufender Run einer Vorlage)
└── ProcessComponentState (Status pro Schritt)
└── ProcessEvent (Append-only Audit-Log)Zentrale Idee: Du bringst der Engine eigene "ComponentKinds" bei (HTTP-Call, E-Mail, Slack-Post …). Die Engine kümmert sich um Persistenz, Retries (perspektivisch), Audit, Concurrency. Du kümmerst dich nur um den eigentlichen Schritt.
Phase 3.5 liefert 11 generische flow.*-Components out-of-the-box, mit denen ein typischer Workflow ohne eigenen Code modellierbar ist.
Authentifizierung
Drittanbieter authentifizieren sich mit API-Keys. Jeder Schlüssel ist:
- pro Tenant (Schule/Verein) ausgestellt
- mit einer Scope-Liste versehen (feinkörnig)
- HMAC-sicher (
prilog_<keyId>_<secret>— sha256-gehashed in der DB) - jederzeit revoke- oder löschbar
Schlüssel erstellen (einmalig durch Admin)
curl -X POST https://api.prilog.chat/api/platform/v1/process/api-keys \
-H "Authorization: Bearer <ADMIN-JWT>" \
-H "Content-Type: application/json" \
-d '{
"name": "Mein Skript",
"scopes": [
"process:templates:read",
"process:instances:start",
"webhook:trigger"
]
}'Antwort (genau einmal sichtbar):
{
"keyId": "cmole8...",
"plainKey": "prilog_cmole8...XXXXXXXX",
"warning": "Dieser Schluessel wird nur einmal angezeigt. Sicher aufbewahren."
}Verwendung
curl https://api.prilog.chat/api/platform/v1/process/templates \
-H "Authorization: Bearer prilog_cmole8...XXXXXXXX"Verfügbare Scopes
| Scope | Erlaubt |
|---|---|
process:templates:read | Templates auflisten + Detail |
process:templates:write | Templates anlegen, ändern, archivieren |
process:instances:read | Instances + States lesen |
process:instances:write | Instances aborten, ComponentStates updaten |
process:instances:start | Neue Instance starten (POST /process/instances) |
process:secrets:write | TenantSecrets setzen/löschen |
webhook:trigger | Webhook-Endpoints auslösen |
Walkthrough: Webhook → HTTP → Matrix
1. Template anlegen
curl -X POST https://api.prilog.chat/api/platform/v1/process/templates \
-H "Authorization: Bearer prilog_..." \
-H "Content-Type: application/json" \
-d '{
"appKind": "flow",
"name": "Stripe-Zahlung benachrichtigen",
"description": "Bei eingehender Stripe-Webhook → Lehrerzimmer benachrichtigen"
}'→ Returns { id: 'cm...' } — die templateId.
2. Components hinzufügen
# 2a. Webhook-Trigger
curl -X POST https://api.prilog.chat/api/platform/v1/process/templates/<TEMPLATE_ID>/components \
-H "Authorization: Bearer prilog_..." \
-H "Content-Type: application/json" \
-d '{
"kind": "flow.webhook-trigger",
"label": "Stripe Webhook",
"config": { "pathSlug": "stripe-payment", "secret": "whsec_xxxxx" }
}'
# 2b. Matrix-Message
curl -X POST https://api.prilog.chat/api/platform/v1/process/templates/<TEMPLATE_ID>/components \
-H "Authorization: Bearer prilog_..." \
-H "Content-Type: application/json" \
-d '{
"kind": "flow.matrix-message",
"label": "Lehrerzimmer benachrichtigen",
"config": {
"spaceId": "<LEHRERZIMMER_SPACE_ID>",
"body": "Zahlung eingegangen: ${data.amount} EUR von ${data.customer_email}"
}
}'3. Edge zwischen den Components
curl -X POST https://api.prilog.chat/api/platform/v1/process/templates/<TEMPLATE_ID>/edges \
-H "Authorization: Bearer prilog_..." \
-H "Content-Type: application/json" \
-d '{
"sourceId": "<TRIGGER_ID>",
"targetId": "<MATRIX_MSG_ID>",
"condition": { "type": "always" }
}'4. Webhook-URL bei Stripe registrieren
URL: https://api.prilog.chat/api/platform/v1/process/webhooks/<DEIN_TENANT_SLUG>/stripe-payment
Header: X-Prilog-Signature: sha256=<HMAC_SHA256(body, secret)>5. Run beobachten
# Liste alle Instances dieses Templates
curl https://api.prilog.chat/api/platform/v1/process/templates/<TEMPLATE_ID>/instances \
-H "Authorization: Bearer prilog_..."
# Audit-Log einer Instance
curl https://api.prilog.chat/api/platform/v1/process/instances/<INSTANCE_ID>/state \
-H "Authorization: Bearer prilog_..."ComponentKind-Referenz
Trigger
| Key | Zweck | config |
|---|---|---|
flow.webhook-trigger | HTTP startet einen Run | { pathSlug, secret, payloadSchema? } |
flow.schedule-trigger | Cron-basierter Start | { cron, payload? } |
Generic Actions
| Key | Zweck | config |
|---|---|---|
flow.http-request | Outbound HTTP | { method, url, headers?, body?, authRef?, timeoutMs?, storeResponseAs? } |
flow.set-data | Variablen mutieren | { operations: [{key, op, value, from?}] } |
flow.delay | Wartet ms ms | { ms } |
Prilog-internal Actions
| Key | Zweck | config |
|---|---|---|
flow.matrix-message | Matrix-Raum-Post | { roomId? | spaceId?, body } |
flow.send-email | E-Mail (Mailpace) | { to, subject, body } |
flow.dms-write | Document erzeugen | { scope, spaceId?, title, content, folderId? } |
flow.create-task | WorkItem im Aufgaben-Hub | { spaceId, boardId, title, assignedUserId?, dueAt? } |
Control-Flow
| Key | Zweck | config |
|---|---|---|
flow.sub-process | Anderes Template als Sub-Instance | { templateId, inputData?, awaitCompletion } |
flow.loop | Iteration über Array (max 1000) | { iterableFrom, bodyTemplateId, parallel, maxConcurrency? } |
Template-Variablen
In allen config-Strings sind ${...}-Platzhalter erlaubt:
| Namespace | Quelle |
|---|---|
${data.foo.bar} | Laufzeit-Daten der Instance (Webhook-Payload, HTTP-Response, set-data) |
${tenant.id} / ${tenant.slug} | Aktueller Tenant |
${env.HOSTNAME} | Whitelist-Env-Variablen |
${output.x} | Output der zuletzt ausgeführten Component |
Kein Eval. Reine Substitution. Conditionals oder Arithmetik werden nicht ausgewertet.
TenantSecrets (für flow.http-request)
Secrets sind AES-256-GCM verschlüsselt im Tenant-Scope.
# Setzen
curl -X PUT https://api.prilog.chat/api/platform/v1/process/secrets/stripe_api_key \
-H "Authorization: Bearer prilog_... (Scope: process:secrets:write)" \
-H "Content-Type: application/json" \
-d '{"value": "sk_live_xxxxx"}'
# In flow.http-request referenzieren:
{
"kind": "flow.http-request",
"config": {
"method": "GET",
"url": "https://api.stripe.com/v1/charges",
"authRef": "stripe_api_key"
}
}→ Engine löst authRef zur Laufzeit auf, setzt Authorization: Bearer <wert>.
Plain-Werte werden NIE im API-Response zurückgegeben.
Webhook-Empfang: HMAC-Signing
# Sender (z.B. Stripe, Zapier, eigenes Skript):
SECRET="dein-webhook-secret"
PAYLOAD='{"event": "charge.succeeded", "amount": 4200}'
SIG=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" -binary | xxd -p -c 999)
curl -X POST https://api.prilog.chat/api/platform/v1/process/webhooks/<TENANT>/<SLUG> \
-H "Content-Type: application/json" \
-H "X-Prilog-Signature: sha256=$SIG" \
-d "$PAYLOAD"Server-Antwort:
202 { accepted: true, instanceId }— Run gestartet401 FORBIDDEN— Signatur falsch404 NOT_FOUND— Tenant oder Slug unbekannt
SSRF-Schutz
flow.http-request blockiert:
localhost,127.0.0.0/8,0.0.0.0,::1- Private RFC1918-Ranges:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - Link-Local + AWS/GCP Metadata:
169.254.0.0/16,metadata.google.internal
Maximaler Timeout: 60 s. Maximale Antwort-Größe: 1 MB.
Limits
| Wert | |
|---|---|
Max. Iterations pro flow.loop | 1000 |
| Max. Verschachtelung Sub-Process | 10 (perspektivisch) |
| HTTP-Request Timeout | 60 s |
| HTTP-Response Body | 1 MB |
| TenantSecret-Wert | 8192 Zeichen |
| Component-Config-JSON | per Postgres JSONB-Limit (≈ 1 GB; kein Soft-Limit) |
| Webhook-Pfad-Slug | 1–80 Zeichen (a-z 0-9 _ -) |
Versionierung
Die API ist unter /api/platform/v1/process/* versioniert. Breaking Changes erfolgen via /v2/-Prefix mit Deprecation-Periode.
Support
- OpenAPI-Spec:
https://api.prilog.chat/api/platform/v1/process/openapi.json - Bugs / Feature-Requests:
https://github.com/brasilspace/prilog_docs/issues - E-Mail:
contact@ordiem.com