Inbound WhatsApp Flows completion webhook
Receives a Meta Flow-completion event when a customer finishes a multi-step interactive Flow. Authenticates using the X-Devotel-Org-Id header (org id shape-validated, then the org’s WhatsApp connection credentials + flow private key are resolved). The request body is the Meta-endpoint envelope (encrypted_flow_data, data = ); the signature is HMAC-SHA256 over the raw body using the org’s app_secret. Payloads are persisted to <tenant>.whatsapp_flow_responses keyed to the matching flow. Returns the Meta-specified AES-128-GCM-encrypted JSON as text/plain (NOT the standard { data, meta } envelope); failure replies use the uniform 401 error envelope below.
Authorizations
Dashboard JWT token from Clerk
Headers
Orbit organization id that owns the flow (required).
HMAC-SHA256 over the raw body using the org's app_secret.
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
1 - 255Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
true, false Body
Meta endpoint envelope: encrypted_flow_data (AES-128-GCM over RSA-OAEP-wrapped key) plus data.flow_id, contact_id, conversation_id references.
Meta endpoint envelope: encrypted_flow_data (AES-128-GCM over RSA-OAEP-wrapped key) plus data.flow_id, contact_id, conversation_id references.
Response
Meta-specified raw base64 AES-128-GCM body sent as text/plain; this shape is Meta-mandated and intentionally NOT the standard { data, meta } envelope. Any failure branch returns the same uniform 401 (see route description).
Meta-specified raw base64 AES-128-GCM body sent as text/plain; this shape is Meta-mandated and intentionally NOT the standard { data, meta } envelope. Any failure branch returns the same uniform 401 (see route description).