Documentation — MxChat Forms

Version 1.2.20 · Updated 7 days ago

MxChat Forms

Custom in-chat forms and multi-step wizards that fire naturally during conversations — for lead capture, support tickets, product recommendations, eligibility quizzes, and any other structured data you need to pull out of a chat session.

Overview

MxChat Forms turns your chatbot into a structured data-collection tool without breaking the conversational flow. Instead of bouncing visitors to a separate contact page, the form appears inline during the chat. A form can fire four ways — when the AI detects matching intent from your trigger phrases, after a set number of messages, after the visitor has been inactive for a set number of seconds, or as an AI Tool the chatbot opens on its own when a visitor's message calls for it. Trigger phrases are optional, so a form can run on any of the other paths alone. You build the fields and pick the trigger(s), and the add-on hooks straight into MxChat's action recognition and function-calling systems. Two wizard modes — Conditional (linear questions with outcome rules) and Branching (dynamic decision trees) — cover everything from a simple "drop your email" capture up to multi-step troubleshooting flows. Pro license required.

Setup

  1. Install the mxchat-forms plugin via Plugins → Add New → Upload Plugin, or download from the MxChat add-ons gallery.
  2. Activate via Plugins → Installed Plugins. MxChat (mxchat-basic) must already be active or you'll see a dependency notice.
  3. Confirm your MxChat Pro license is active under MxChat → Pro & Extensions. The Forms admin will warn you if it isn't.
  4. Find the admin under MxChat → Form Collection. From there: "Create New Form" for a standard form, or pick "Wizards" to build a Conditional or Branching wizard.
  5. Add fields, then pick how the form fires: trigger phrases (matched via embeddings — optional), a message-count trigger, an inactivity trigger, or switch the form on as an AI Tool. Set role restrictions as needed, then save.

Settings

Form Fields

Field builder with eight field types, set per field under Field Type: Static Text, Single Line Input, Message (multi-line), Email, Phone, Dropdown (single choice), Radio buttons (single choice), and Checkboxes (multiple choice). Each field has a label, optional placeholder, required/optional toggle, and a "Use label as placeholder" option for tighter layouts.

For the three choice types — Dropdown, Radio buttons, and Checkboxes — you give the field a list of options and the visitor picks from them right in the chat instead of typing a free-text answer. Dropdown and Radio buttons accept a single selection; Checkboxes allow more than one. Every submitted choice is validated against your option list before it is saved, and the values flow through to submission emails, the submissions table, the webhook payload, and CSV export like any other field (multiple checkbox selections are stored as a comma-separated list).

Trigger Phrases

Tag-style input where each phrase becomes its own embedding vector for accurate intent matching. Each form and wizard keeps its own phrases: from 1.2.20, saving or deleting one no longer changes another's (for example Form 1 and Form 12). Add as many as you need — the AI fires the form when the user message is semantically similar to any one of them. Legacy comma-separated phrase groups still work and display as a single "legacy" tag. Trigger phrases are optional — you can save a form with none and rely on a message-count trigger, an inactivity trigger, or the AI Tool path instead.

Similarity Threshold

Per-form slider controlling how closely a user message has to match a trigger phrase before the form fires. Raise it if forms trigger too eagerly; lower it if intent is being missed.

Message-Count Trigger

Fire the form after N total messages in the session, ignoring intent matching. Useful for "ask for email after the third exchange"-style nudges. Set to 0 to disable.

Trigger After Inactivity (Seconds)

Show the form after the visitor has gone quiet for a set number of seconds since their last chat message — the classic "looks like you stepped away — can we grab your email?" lead-capture pattern. Off by default; accepts 10–600 seconds. It fires at most once per conversation, waits while the bot is still answering or the visitor is typing, and never interrupts another form or a wizard already on screen.

Run a Form as an AI Tool

Every form can be exposed to the chatbot as its own AI Tool (function call). On MxChat's AI Tools page each form appears as a switch; turn one on and the chatbot can open that form by itself when a visitor's message calls for it — no trigger phrases required. Each form stays off as an AI Tool until you enable that specific one, and your existing trigger-phrase, message-count, and inactivity triggers keep working alongside it.

Role Restrictions

Limit triggering to specific WordPress roles (admin, subscriber, customer, visitor, etc.). The form is invisible to anyone outside the allowed roles.

Regex Pattern (optional)

Advanced match field. If set, the user message also has to match this regex before the form will fire — a useful way to lock a form to messages that contain a phone number, postcode, or other concrete pattern.

Message Shown Before Form (1.2.16+)

Optional text shown with the form when it opens in the chat. A form opened by a trigger phrase is returned on its own and the AI is not called for that turn, so without this field the form appears with no introduction. Leave it empty and the form appears as before. It is separate from the Success Message, which is shown after the visitor submits.

Success Message

The response text shown in chat after a successful submission. From 1.2.19 it can repeat what the visitor entered: put a field's label in curly brackets, for example Thanks {Name}, we will reply to {Email}.

Chat Input Blocking

Toggle that disables the chat textarea while the form is on-screen, forcing the user to either submit or cancel before they can keep typing. Use it when you need complete responses.

When core's Chat Persistence brings a conversation back after a page reload, forms and wizard questions return with it. From 1.2.18 the add-on asks the server which of them are still live before blocking anything: a form still waiting for an answer stays usable, a form already submitted shows its response message as it did before the reload, the wizard step the visitor is actually on stays usable, and every other restored question is greyed out. The message box is blocked only while a live form or wizard step is on screen. From 1.2.19 a form that blocks the message box blocks only its own chatbot, and your own placeholder returns when the form releases it.

Email Notifications

Notification Email takes one or more addresses, separated by commas (1.2.19), that receive a notification on every submission. Left blank, the WordPress admin email is used. Each notification uses human-readable field labels and sets a Reply-To header to the visitor's submitted email.

Attach the chat transcript to the notification email (1.2.19) is a per-form checkbox. On, the conversation that led to the submission is attached as a text file; off, the email carries only the form's answers. It is on for existing forms. From 1.2.19 the attachment is built without writing to the public uploads folder.

Wizard Notification Email and Webhook URL (1.2.15+)

Both wizard editors — Conditional and Branching — carry a Notification Email (one or more comma-separated addresses from 1.2.19) and, from 1.2.15, a Webhook URL with the same signing secret and Regenerate control the form editor has. The completion email labels each answer with the step's question (it used to print the step's internal id), prints the chat session id, and includes the triggered form's submitted fields when the outcome collected them. The webhook and its payload are described under API & Integration below.

Email Subject Line (Optional)

Per-form email subject override. Leave blank to use the form title. Before 1.2.19 the subject could be lost on save.

Privacy (1.2.19+)

A Privacy tab under MxChat → Form Collection holds a Data retention card. Delete submissions and wizard sessions after a number of days removes older submissions and wizard sessions once a day; deleted rows cannot be recovered. Enter 0 to keep everything until you delete it yourself, which is the default. Click Save retention to apply. Visitors can still request their own data through Tools → Export Personal Data and Tools → Erase Personal Data.

Translating forms (1.2.19+)

Field labels, choice option text, the Success Message and the Message Shown Before Form are registered with WPML String Translation and Polylang under the context MxChat Forms, so they appear in that plugin's string list and visitors see the translated text. Choice option values are not translated: the server checks submissions against the saved options, so only the text the visitor reads changes. Without either plugin nothing changes.

Features

  • Custom form builder: Eight field types — Static Text, Single Line, Message, Email, Phone, Dropdown, Radio buttons, and Checkboxes — with validation and required-field control. Choice fields take an option list and validate every submission against it; build the form once, fire it as many times as the chatbot needs.
  • Conditional Wizards: Linear question flows with outcome rules based on answer combinations. Great for guided lead-qualification where you want every visitor to answer the same set of questions.
  • Branching Wizards: Dynamic decision trees where each answer determines the next question. Ideal for product recommendations, troubleshooting paths, and eligibility checks where the path depends on what the visitor said.
  • Action-based triggering: Forms appear naturally during chats when the AI detects relevant intent. No "open form" CTA needed — the conversation just routes into the form when it makes sense.
  • Message-based triggers: Fire a form after a set number of messages for more controlled engagement (e.g. ask for contact info after the third exchange).
  • Inactivity trigger: Show a form after the visitor has been quiet for a set number of seconds (10–600), fired at most once per conversation — the "looks like you stepped away" lead-capture nudge.
  • Forms as AI Tools: Expose any form to the chatbot as a function-call tool on the AI Tools page. The bot opens the form itself when a visitor's message calls for it — so a form needs no trigger phrases to start. Off per form until you switch it on.
  • Role-specific forms: Restrict triggers to specific WordPress user roles so you can collect different data from admins, customers, and visitors.
  • Wizard session tracking: Completion rates, full session history per wizard, and a Delete All button to clean up old data. Export to CSV for iteration analysis.
  • Wizard answers in the chat transcript (1.2.15+, needs MxChat 3.2.22): Each question and the answer the visitor chose are recorded as the wizard runs, so MxChat → Transcripts, the Telegram and Slack live-agent handoff, Download Transcript, the emailed transcript and the form notification attachment all show the full run instead of a single [WIZARD_COMPLETE] marker; when the wizard finishes the transcript reads Completed wizard with the wizard's name and the matched outcome. The handoff card also gains a Wizard answers section, and the recent-conversation tail it carries is extended so the message that started the wizard is not pushed out. On MxChat older than 3.2.22 the transcript is unchanged.
  • Wizard completion webhook + action hook (1.2.15+): Every completed wizard session can be POSTed as signed JSON to a Webhook URL set on the wizard, with each step's question and answer, the matched outcome and the chat session id; when the outcome triggers a form, the wizard answers and that form's fields are delivered together in one request once the form is submitted. PHP integrations can listen on mxchat_forms_wizard_completed.
  • Custom email notifications + transcript: Route submissions to one or more comma-separated addresses, with the chat conversation attached as a text file (a per-form checkbox), plus a Reply-To header so replies go straight to the visitor.
  • Data retention (1.2.19+): Optionally delete submissions and wizard sessions older than a number of days you choose, from the Privacy tab. Off by default.
  • Translatable forms (1.2.19+): Labels, options and messages can be translated with WPML or Polylang.
  • Lighter chat script (1.2.19+): The form script in the chat widget no longer requires jQuery. Form progress is kept for seven days instead of leaving a database row for every chat session. From 1.2.20 wizard progress also expires after seven days instead of leaving permanent rows, and Forms reuses the chat's security token, so there are fewer background requests.
  • Cookie consent with Complianz (1.2.20+): With MxChat's Complianz integration on, Forms waits for cookie consent before checking for an unfinished wizard, and picks the wizard up as soon as the visitor gives consent.
  • Chat input blocking + CSV export: Block free-text while a form is open to guarantee complete responses, and export every submission to CSV with one click.
  • Visitor identity in live-agent handoffs (1.2.12+): When a visitor fills in a form mid-chat, their name and email now carry into the Slack and Telegram live-agent handoff notifications — which previously showed Anonymous / Not provided unless you had core's pre-chat capture enabled — and onto the session's rows in the Transcripts and Leads views. No setup and no new settings: the add-on takes the email from the form's first Email field with a valid value, and the name from the first Text field whose label contains "name" (falling back to the form's first Text field). A later submission with a real value replaces an earlier one; a blank or invalid value never wipes an identity you already have. See Live agent handoff for the handoff itself, which is core.
  • Covered by WordPress's personal data tools (1.2.13+): Form submissions and guided wizard answers are included in WordPress's built-in export and erasure requests under Tools → Export Personal Data and Tools → Erase Personal Data. A request is matched against the visitor's WordPress account and against the email address they typed into the form, so anonymous submissions are covered too. Exports present each answer next to the question it answered rather than as a raw data blob, and the suggested privacy policy text that MxChat contributes now describes what form data the site stores. Nothing to configure — registering with WordPress's tools is automatic once the add-on is active.
  • Webhooks + action hook (1.2.8+): Point any form at a Zapier / Make / n8n / Slack / custom endpoint with an optional Webhook URL — every submission is POSTed as JSON, signed with HMAC-SHA256, and recorded in a Webhook Log showing the last 100 deliveries. PHP integrations can instead listen on the mxchat_forms_submitted action hook.

API & Integration

MxChat Forms registers itself with MxChat's trigger system via the standard filter pipeline. Useful hooks:

  • mxchat_available_callbacks — Forms registers mxchat_handle_form_collection and mxchat_handle_wizard_collection so the chatbot can route messages into a form or wizard handler.
  • mxchat_function_calling_extra_tools — registers one AI-Tool per enabled form (mxchat_form_collect_<id>) so the chatbot's function-calling loop can open a form directly, no trigger phrase required. Per-form tools are off by default. Requires a current mxchat-basic that exposes this registry hook; on older core, Forms degrades gracefully to the trigger-phrase / message-count / inactivity paths.
  • mxchat_pre_process_message — used to check message-count triggers on every incoming message.
  • mxchat_forms_form_html (1.2.19) — filters a form's complete HTML before it is sent to the chat, with the form row and chat session id. Keep the data attributes, field names and the mxchat-submit-form button; the chat script relies on them.
  • mxchat_forms_field (1.2.19) — filters one field's config before it is rendered, with the form row. Change label or option_labels to alter what the visitor reads; leave name and options as they are, because the server validates against them.
  • mxchat_prepare_context — injects form/wizard state into the AI context so the model knows when a form is pending (shown but not submitted) vs successfully submitted, and adjusts its replies accordingly.

AJAX endpoints (all nonce-protected via mxchat_forms_nonce):

  • mxchat_submit_form — public submission handler.
  • mxchat_wizard_answer / mxchat_wizard_cancel / mxchat_wizard_resume_check — wizard step handlers.
  • mxchat_export_submissions — admin-only CSV export.

Email notifications go through standard wp_mail(), so any SMTP plugin (WP Mail SMTP, FluentSMTP, etc.) catches them automatically.

Webhooks and the submission event (1.2.8+)

As of 1.2.8 there are two ways to fan a submission out to other systems — no polling or email-parsing workarounds needed.

Per-form webhook. Each form has an optional Webhook URL (Optional) field in the form editor. Set it, and every successful submission is POSTed to that URL as a JSON body — ready for Zapier, Make, n8n, Slack, or a custom endpoint. Delivery is asynchronous (scheduled a few seconds after submission) so the visitor's chat flow is never blocked while the receiver responds. Each request carries these headers:

  • X-MxChat-Event: form.submitted
  • X-MxChat-Form-Id: <form id>
  • X-MxChat-Delivery: <unique delivery uuid>
  • X-MxChat-Signature: sha256=<hmac> — an HMAC-SHA256 of the raw request body, keyed with the form's Webhook Signing Secret. Verify it on your side to confirm the request genuinely came from your site.

The signing secret is generated automatically when you first set a Webhook URL, shown read-only in the form editor, and can be rotated with the Regenerate button. A Webhook Log page (under Form Collection) records the last 100 delivery attempts per form — status (Delivered / Failed), HTTP response code, and a response excerpt — filterable by form, so you can see exactly what your endpoint returned.

WordPress action hook. For integrations written in PHP, the add-on fires:

do_action( 'mxchat_forms_submitted', $submission, $form );

after every committed submission. $submission carries the labeled field values plus session metadata (session ID and page URL); $form is the full form record. Use it to push leads into a CRM, send a Slack message, write to a custom table, or anything else — no webhook endpoint required.

Wizard completion webhook and transcript rows (1.2.15+)

Wizard webhook. Both wizard editors have a Webhook URL field next to Notification Email, with the same signing secret and Regenerate control as forms. When a session completes, the add-on POSTs a JSON body shaped like:

{
  "event": "wizard_completed",
  "wizard_id": 3,
  "wizard_title": "Patient intake",
  "session_id": "mxchat_chat_…",
  "user_id": 0,
  "page_url": "https://example.com/contact/",
  "completed_at": "2026-09-20T14:02:11+00:00",
  "outcome": { "name": "Book a consult", "action_type": "trigger_form", "action_form_id": 5 },
  "answers": [ { "step_id": "q1", "question": "What brings you in?", "answer": "Back pain" }, … ],
  "form_submitted": true,
  "form": { "form_id": 5, "form_title": "Contact details", "submission_id": 812, "fields": { "Name": "…", "Email": "…", "Phone": "…" } }
}

It rides the same machinery as the form webhook: delivery is asynchronous, the request carries X-MxChat-Event: wizard.completed and an HMAC-SHA256 X-MxChat-Signature keyed with the wizard's secret, and every attempt is listed in the Webhook Log, which now has a Source column reading Wizard: <name> or the form's name.

One payload per visitor. When the outcome is Trigger a Form, delivery waits until that form is submitted and then sends one request carrying the wizard answers and the form's labelled fields, flagged form_submitted: true — so a Zapier or Make step writes one row per visitor with no join. The form's own form.submitted webhook carries the wizard answers too (a wizard key, added through the new mxchat_forms_webhook_payload filter). If the visitor never submits the form, the daily cleanup sends the wizard-only payload marked form_submitted: false. An outcome that hands to the AI sends the wizard-only payload at completion.

Action hook. For PHP integrations the add-on fires, with the same payload:

do_action( 'mxchat_forms_wizard_completed', $payload, $wizard );

the twin of mxchat_forms_submitted.

Transcript rows. From 1.2.15 on MxChat core 3.2.22 or newer, each wizard step's question and the visitor's answer are written into the chat transcript through core's save_session_message, and the completion line reads Completed wizard with the wizard's name and outcome. That is what makes the answers appear in Transcripts, in Download Transcript, in emailed transcripts and attachments, and in the Telegram and Slack handoff card — which additionally gets a Wizard answers section through core's mxchat_handoff_card_sections filter. On older core the steps still travel only through the wizard's own endpoint and the transcript shows the first step's card and, for an AI outcome, the [WIZARD_COMPLETE] marker.

Daily cron event mxchat_forms_wizard_cleanup sweeps abandoned wizard sessions so the table doesn't bloat, and from 1.2.15 also delivers the wizard-only webhook for sessions whose triggered form was never submitted.

Requirements

  • MxChat (mxchat-basic): Required, active.
  • MxChat Pro License: Required — activate under MxChat → Pro & Extensions. See https://mxchat.ai/pricing/.
  • WordPress: 5.0 or newer.
  • PHP: 7.4 or newer.
  • Third-party: None. Uses your existing MxChat AI provider (OpenAI / Gemini / xAI / etc.) for trigger phrase embeddings — no separate API key needed.

Troubleshooting

Form never appears in chat, or never submits

Check three things in order: (1) MxChat Pro license is active — the admin shows a warning notice if it isn't; (2) the form's enabled toggle is on; (3) raise the similarity threshold or add more trigger phrases. If the form has role restrictions, confirm you're testing as a user in an allowed role.

Update to 1.2.19 if any of these apply: forms fail to submit on pages served from a full-page cache; forms or wizards set to appear after a number of messages or after inactivity stopped appearing; a wizard does not resume after a page reload with Chat Persistence off; or a form switched off, or a wizard's Enable this wizard setting, does not stay as you set it. 1.2.19 also hardens how submissions are checked on the server; the update is recommended.

Phone field rejects a number with dots or an extension

Fixed in 1.2.19. Phone fields accept dots and extensions, Static Text fields show their text, and your own chat placeholder returns when a form releases the message box.

Forms cannot be saved on a MySQL server in strict mode

Update to 1.2.17. Earlier versions declared several columns in a way strict-mode MySQL rejects, so the conversational wizards table was never created and forms could not be saved. Affected sites recover on the first page load after updating. From 1.2.17, if the database refuses a change to one of the Form Collection tables, the error is recorded once and shown on the Form Collection screen.

Database update issue notice on admin pages

If the regex_pattern column is missing from the forms or intents table, the plugin shows an "update issue detected" notice. Deactivate and reactivate the plugin to re-run the schema migration.

Apostrophes in form titles showing as I\'m

Fixed in 1.2.6. Update the plugin and re-save the affected form — the heal routine strips accumulated backslashes automatically.

Notification emails not arriving

Test wp_mail() deliverability with any SMTP plugin first. If your test email arrives but form notifications don't, check the per-form email address setting (typos are the usual cause). Confirm the form actually submitted by checking MxChat → Form Collection → Submissions.

Duplicate submissions on a single click

Fixed in 1.2.3. Update to the current version — the fix includes a 5-second server-side dedup window plus a per-form click guard.

In-chat form looks squeezed, cut off, or hard to read

Fixed in 1.2.12 — update the add-on. The form used to render inside a shrink-wrapped message bubble with no width of its own, so it could collapse to a narrow column with the fields cut off; the bubble now stretches to hold it. The same release hardened the field styling against theme CSS: inputs keep a white background with dark text on any bubble color, checkboxes and radios stay visible on dark themes and pick up your accent color, and the submit button follows the bot accent instead of a fixed WordPress blue.

Live agent handoff still shows "Anonymous" after a form was filled in

From 1.2.12 the add-on syncs the visitor's identity from any mid-chat form submission, so this should resolve on update. If it persists, check the form actually has the field types it detects on: the email comes from an Email-type field, and the name from a Text field whose label contains "name" (or, failing that, the form's first Text field). A name collected through a Dropdown or Message field won't be picked up. Handoffs that start before any form is submitted still show Anonymous — enable core's pre-chat capture under Lead Capture if you need identity on every handoff.

From 1.2.14 the captured name and email are written into MxChat's sessions storage on core 3.2.19 or newer, which is the same place core's own pre-chat form writes to — so handoffs and the Leads tab read one consistent source instead of two. Older MxChat versions keep using the previous per-session storage and behave exactly as before; there is nothing to configure either way.

Wizard answers missing from Transcripts or the live-agent handoff

Update to 1.2.15 and MxChat core 3.2.22 — both are needed, because the transcript rows are written through a core function that arrived in 3.2.22. On older versions the answers exist only in Form Collection → Wizards → Sessions (with CSV export) and in the wizard's Notification Email.

Message box locked after a page reload

Update to 1.2.18. On sites with core's Chat Persistence on, earlier versions could lock the message box after a reload in two cases: when the restored conversation contained a wizard that had already been finished or cancelled, and when it contained a form the visitor had already submitted. The restored copy was treated as live and blocked input. From 1.2.18 restored questions that are no longer current are greyed out, a submitted form shows its response message, and input is blocked only for a form or wizard step that is still waiting for an answer.

Saving a form changed or removed another form's trigger phrases

Update to 1.2.20. Earlier versions could change the trigger phrases of a form or wizard with a similar number (for example Form 1 and Form 12) when another was saved or deleted, and phrases could be lost, emptied or left behind. Re-check the trigger phrases on your forms and wizards after updating and re-add any that are missing.

Another form or wizard starts when a wizard finishes

Fixed in 1.2.20. Finishing a wizard no longer starts another form or wizard by mistake; the chatbot answers with the finished wizard's guidance.

Admin screens look broken on a phone, tablet or small laptop

Update to 1.2.20, which fixes layout and display issues in the Forms, Wizards, Submissions, Wizard Sessions and Webhook Log screens on smaller screens.

Wizard session table growing without bound

The daily mxchat_forms_wizard_cleanup cron sweeps abandoned sessions automatically. Confirm WP-Cron is running (some hosts disable it) — if it isn't, trigger it manually via WP-CLI or set up a real system cron pointing at wp-cron.php.


Last reviewed by Sage on 2026-10-25. Spotted an issue? Open a ticket and we'll patch the doc.