Skip to Content
Lead FormsWebhooks

Lead Form Webhooks

Lead form webhooks send captured lead data from ResultFly to an external system such as a CRM, CDP, email platform, or custom backend.

Use them when you want a server-to-server delivery after a visitor submits a lead form.

Delivery events

Lead form webhooks can be delivered for two lead-form event types:

  • submitted: the final submit step of a lead form.
  • draft_submitted: a non-final step submit in a multi-step lead form.

Use submitted when you want only completed leads.

Use draft_submitted when you also want to capture partial leads from earlier steps. This is useful for capturing valuable lead data even when visitors abandon the form before completion — you can follow up with incomplete submissions and recover potential customers.

Important: When a visitor completes the form and the final submitted event is sent, it includes all the data accumulated from previous draft steps. You do not need to manually map or combine draft submissions — the final payload already contains the complete, up-to-date form data.

What marketers can use

A lead form webhook gives you two views of the same submission:

  • Data: a simple object with the most useful named fields, ready for CRM mapping.
  • Fields: a complete map of all submitted fields by field ID, including fields that do not have a public field name.

This keeps integrations easy for common cases without losing information from the original form.

Example payload

{ "eventId": "evt_01", "eventType": "lead.captured", "version": 1, "occurredAt": "2026-03-25T12:00:00Z", "campaign": { "id": "cmp_123", "name": "Spring promo" }, "session": { "id": "f9440f27-ce8e-4543-b2b4-dbbfad18612a" }, "context": { "embedUrl": "https://resultfly.com/campaign/123456" }, "data": { "firstName": "John", "lastName": "Doe", "email": "john.doe@example.com", "consent": { "accepted": true } }, "fields": { "field_first_name_uuid": { "fieldName": "firstName", "label": "First name", "semanticKey": "first_name", "valueType": "text", "required": true, "hidden": false, "readonly": false, "value": "John", "source": "user" }, "field_last_name_uuid": { "fieldName": "lastName", "label": "Last name", "semanticKey": "last_name", "valueType": "text", "required": true, "hidden": false, "readonly": false, "value": "Doe", "source": "user" }, "field_email_uuid": { "fieldName": "email", "label": "Email", "semanticKey": "email", "valueType": "email", "required": true, "hidden": false, "readonly": false, "value": "john.doe@example.com", "source": "user" }, "field_consent_uuid": { "fieldName": "consent", "label": "Privacy consent", "semanticKey": "consent", "valueType": "boolean", "required": true, "hidden": false, "readonly": false, "value": true, "source": "user" }, "field_without_name_uuid": { "fieldName": null, "label": "City", "semanticKey": null, "valueType": "text", "required": false, "hidden": false, "readonly": false, "value": "Barcelona", "source": "user" } } }

How data is built

data is optimized for quick setup in tools that expect named fields.

ResultFly can fill standard keys from field meaning:

  • email
  • firstName
  • lastName
  • phoneNumber
  • consent.accepted

Custom fields can also appear in data when they have a Field name.

If a field has no Field name and no standard meaning, it is not added to data. It still appears in fields.

How fields is built

fields is the complete view of the submission.

Each key is the internal field ID, and each value includes:

  • fieldName: the field name used for integrations, or null when not set
  • label: the label shown in the form
  • semanticKey: standard meaning such as email, first_name, or consent, or null when not set
  • valueType: expected value format, such as text, email, or boolean
  • required: whether the field is required
  • hidden: whether the field is hidden from the visitor
  • readonly: whether the field is read-only
  • value: the submitted value
  • source: whether the value came from the visitor or from prefill

Consent is included in fields like any other form field.

Field names

Use Field name for fields that should be easy to map in a CRM or automation tool.

Good examples:

  • firstName
  • lastName
  • email
  • company
  • city

Do not rely on the label as the integration key. Labels are user-facing text and may change for copy, branding, or localization reasons.

For the simple data view, consent is represented as:

{ "consent": { "accepted": true } }

The event timestamp is already available as occurredAt, so consent does not include a separate timestamp in the standard webhook payload.

The full consent field still appears in fields with its field ID, label, value type, required state, and submitted value.

Multiple webhook configs per campaign

You can set up multiple webhook configurations for the same campaign to send lead data to different destinations. Each webhook config can be independently:

  • Enabled or disabled using the enable toggle — pause delivery without deleting the configuration
  • Edited to update endpoint URLs, headers, or event types
  • Tested before activation

This is useful when you want to send leads to multiple CRM systems, analytics platforms, or internal services simultaneously, or when you need to temporarily pause one integration while keeping others active.

Test before launch

Before publishing, send a test webhook from the campaign Integrations modal and verify:

  • your endpoint accepts the request with a 2xx response;
  • your CRM/automation mapping reads the expected fields from data and fields;
  • your team can distinguish submitted and draft_submitted flows.