ArchitectureIVR Webhook Flow

title: IVR Webhook Flow description: How Genesys Cloud posts one webhook per IVR answer and HiveCFM merges them into a single Response row keyed by callId.

IVR Webhook Flow

The IVR (“phone survey”) path in HiveCFM is a Genesys Cloud integration: a Genesys Data Action calls a HiveCFM Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. endpoint once per answered question, and a dedicated v1 client route merges answers into a single Response row keyed by callId. It is not a generic third-party webhook, so there is no HMAC signature check — authentication is a per-environment API key that Genesys sends in the x-Api-Key header.

Step explanations.

1-2. In production, a Genesys Architect flow invokes the HiveCFM_SubmitAnswer Data Action once per collected digit/utterance. The data action YAML in hivecfm-core/genesys-data-actions/ hard-codes the request template, including the x-Api-Key header and the URL pattern /api/v1/client/:envId/ivr/:surveyId/responses.

3-5. The Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. handler validates the body with ZIvrResponseInput (zod), loads the survey, and confirms it belongs to the claimed environment before touching any data.

6-7. Two normalization passes follow: numeric strings are coerced to numbers (so rating/NPS questions end up typed correctly), and DTMF digits are rewritten to the corresponding multipleChoiceSingle choice id using a 1-indexed lookup against the survey’s blocks.

8-12. The handler uses callId as singleUseId to find an existing Response; on hit it merges the new answers into the existing data via updateResponseWithQuotaEvaluation. On miss it creates a fresh response, attaching meta.source = "ivr", callerNumber, and a synthetic userAgent of { browser: "IVR", device: "phone", os: "telephony" }.

13-16. Each persistence path emits sendToPipeline(...) just like the browser response flow, which feeds the same internal /api/pipeline fan-out (webhooks, follow-ups, HubHubThe Go service that owns background processing, integrations, and the admin API. Sibling to Core. push — see Survey Response Flow).

Auth model. There is no signature verifier in the IVR endpoint. The route treats environmentId + a shared x-Api-Key (set in the Genesys Data Action inputs) as the authentication boundary. Replay protection comes from callId uniqueness (singleUseId) rather than from request signing.

Where to look in the code

  • hivecfm-core/apps/web/app/api/v1/client/[environmentId]/ivr/[surveyId]/responses/route.ts — inbound handler.
  • hivecfm-core/apps/web/app/api/v1/client/[environmentId]/ivr/[surveyId]/route.ts — survey metadata endpoint Genesys fetches on call start.
  • hivecfm-core/apps/web/app/api/v1/client/[environmentId]/ivr/[surveyId]/prompts/route.ts — per-question audio prompts.
  • hivecfm-core/apps/web/app/api/v1/client/[environmentId]/ivr/[surveyId]/lib/ivr.tslinearizeSurveyForIvr helper.
  • hivecfm-core/genesys-data-actions/HiveCFM_SubmitAnswer.json — Genesys Data Action definition showing the exact headers, URL template, and input schema.
  • hivecfm-core/apps/web/lib/genesys-cloud/client.ts — Genesys Cloud API client used for the admin-side integration (prompt sync, mappings).
  • hivecfm-core/apps/web/app/api/v1/integrations/genesys-cloud/mappings/route.ts — read-only endpoint for the Genesys console to fetch saved prompt/question mappings.