My solution
1
Native Webflow forms are submitted asynchronously via jQuery → ajaxComplete will notify a handler of the submission.
2
Of all the §1 notifications, the handler must process only those that correspond to the submission of a native Webflow form; the handler can identify them via its 3rd argument — ajaxOptions:
ajaxOptions.url?.includes('/api/v1/form/')
The specification of ajaxOptions is identical to the specification of settings for jQuery.ajax (because they are the same object).
3
The form could have been submitted by a spammer or contained errors that the client-side validation missed → the handler must verify that the form has passed Webflow's server-side validation.
The handler can do this via its 2nd argument — jqXHR.
jqXHR «is a superset of the browser's native XMLHttpRequest object» → it has the status property.
The check:
200 === jqXHR.status
4
Other forms might be present on the website → the handler must determine whether the submitted form is «the enquiry form».
4.1. The handler can do this via the form's name set in the Webflow Designer.
4.2. By default, Webflow assigns the name «Email Form» to all new forms → it is necessary to assign a unique name to «the enquiry form».
4.3. The handler can retrieve the form's name via its 3rd argument — ajaxOptions (as in §2).
4.4. The data property of ajaxOptions contains all the form data in the application/x-www-form-urlencoded format.
4.5. The code to identify the form by its name:
new URLSearchParams(ajaxOptions.data).getAll('name').includes('<Form Name>')
4.6. Webflow allows naming a form field name → new URLSearchParams(ajaxOptions.data) could contain multiple parameters named name → it is correct to use the syntax above instead of the naive check '<Form Name>' === new URLSearchParams(ajaxOptions.data).get('name').
5
The handler can push the corresponding custom event to the Google Tag Manager dataLayer in the standard way (without any Webflow specifics):
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({'event': 'generate_lead'});