Webhook Integrations¶
Beta — limited availability
Customer Forms is in beta and currently only available to a small group of pilot users. If your team can't see this feature in the ZAI portal, that's expected.
Webhook integrations let a remote system (Cloud Radial, Halo PSA, Power Automate, Zapier, anything that can POST JSON) trigger a customer form submission. ZAI extracts values from the JSON using a per-field mapping and runs the form's workflow as if a user had submitted it directly.
Where to find it¶
Open a form → Webhooks. You'll see one card per configured integration with:
- The endpoint URL CR or your sender posts to (and a copy button).
- The API key (copy button included).
- Last received timestamp and last status (Success / Failed / Skipped).
- Active/inactive toggle.
- Configure opens the wizard. Activity shows the last 100 calls. Test sends a payload through the same pipeline.
For a cross-form view, open Customer Forms → Webhooks from the main landing — that lists every webhook across every form in one table.
Configuring a webhook¶
The wizard has three steps:
| Step | What it does |
|---|---|
| Source | Pick a preset (Cloud Radial, Halo PSA, Power Automate generic) or Custom. Sets the integration name. |
| Sample payload | Paste a sample JSON payload, load the preset's sample, or Capture from incoming request (recommended). |
| Field mapping | For each form field, pick the JSON path that provides the value. |
Capture from incoming request¶
The capture button mints a one-shot URL that listens for one incoming POST for up to 10 minutes:
- Click Capture from incoming request.
- Copy the capture URL.
- Paste it into the remote system's webhook configuration (temporarily) and trigger a test submission.
- The wizard auto-fills the sample payload textarea and discovers all available JSON paths.
- Switch the remote system back to the real webhook URL.
JSON path syntax¶
The path extractor supports a useful subset of JSONPath:
| Pattern | Meaning |
|---|---|
$.foo.bar |
Dot-notation object traversal |
$.items[0].name |
Array index |
$.questions[?(@.Id=='Email')].Value |
Predicate filter — find the first array element where Id == 'Email', then take its Value |
Predicate filters are essential for Cloud Radial's Ticket.Questions[] array, where each answer is keyed by jsonId.
Activity log¶
Every webhook call (live or test) is recorded as a WebhookActivity row. The most recent 100 are kept per integration. The Activity drawer shows:
- Timestamp, status, source IP.
- Whether the call was a test or a real submission.
- A link to the resulting submission (if one was created).
- The raw payload (capped at 32 KB).
Use this to debug payload-shape mismatches without having to re-trigger from the remote system.
Test send¶
The Test button on each webhook card POSTs an arbitrary JSON payload through the same processing pipeline as a real call, but flags the resulting submission as IsTestRun=true so production workflows aren't triggered.
The test modal also shows the extracted field values — useful for verifying your mapping is pulling the right paths before you go live.
Active toggle¶
The toggle on each card flips the integration between Active and Inactive. Inactive integrations still accept incoming calls but reject them with 409 Conflict and write a Skipped activity row, so you can see when callers are still hitting an old URL.