Skip to main content

Integrations

Forms is designed to connect with the rest of Votel — CRM, Workflows, Click Tracking, Payments — and expose its submission data to external systems via API. This page covers each integration surface.

CRM (Contacts)

Every form submission becomes a CRM lead by default. The integration is automatic — there's no setup beyond mapping individual fields to contact properties.

Field-to-Contact Mapping

In each field's Properties tab, the Save to Contact Field dropdown maps the field's value to a property on the contact created from each submission. Fields from the Contact & Personal palette category come pre-mapped (First Name → first_name, Email → email, etc.).

Fields with no mapping live only on the submission row and don't propagate to the contact record. Use this to keep arbitrary form data in submissions without polluting the contact schema.

See Field Properties → Save to Contact Field for the full list of contact properties you can map to.

Lead De-Duplication

The lead matcher attempts to find an existing contact before creating a new one. Match priority is localStorage.votel_lead_id → email → phone → name. See Submissions → Lead Matching for the algorithm.

Updating Existing Contacts

When a submission matches an existing lead, the contact is updated with any new mapped values. Existing properties are not overwritten with empty strings — only non-empty new values replace old ones.

This means a returning visitor filling out a different form can enrich their existing record without losing prior data.

Workflows

Every form can trigger workflows. Workflows are the way to take action on each submission — send emails, notify your team, enroll in campaigns, route leads, score, tag.

The "Form Submitted" Trigger

In the Workflows builder, add a trigger of type Form Submitted and pick a specific form. The workflow runs once per submission to that form.

Available variables in the workflow:

VariableContents
submission.idSubmission UUID
submission.form_idForm UUID
submission.form_nameForm name at time of submit
submission.lead_idLead UUID
submission.responsesObject — field UUID → value
submission.responses.<field-slug>Direct access to a field's value by its (immutable) slug
submission.metadataStripe / payment metadata, if any
lead.first_name / lead.email / etc.Standard lead variables

Common Workflow Patterns

PatternSetup
Confirmation emailForm Submitted → Email node sending to {{lead.email}}
Slack notificationForm Submitted → Slack node posting {{lead.first_name}} just signed up for {{submission.form_name}}
Tag the leadForm Submitted → Tag Lead node with a fixed tag like Form Lead — Newsletter
Lead scoringForm Submitted → Update Contact node bumping lead_score by N
Pipeline stage updateForm Submitted → Set Pipeline node moving the lead to "New Inquiry"
Outbound campaign enrollmentForm Submitted → Add to Campaign node
Conditional routingForm Submitted → Decision node branching on submission.responses.<field> value

Multiple Workflows Per Form

You can have multiple workflows triggered by the same form. They all run in parallel on each submission. Useful for separating concerns (one workflow for email confirmations, another for CRM tagging, another for Slack notifications).

Click Tracking Attribution

If your form is reached via a Click Tracking link, attribution is automatic.

When a visitor clicks a tracked link and lands on your form (or arrives with a click_id URL parameter), the form's submission row carries the visitor's lead_visitor_id, which the click engine uses to attribute conversions back to the originating click.

Set up:

  1. Add a Conversion Pixel on your form's success page (the redirect target after submit).
  2. The pixel reads the click_id from the URL or local storage and attributes the conversion.

Now your reports show clicks → form submissions → revenue end-to-end.

Stripe Payments

When a form has a Payment field, Stripe handles the actual money movement. The form-builder knows about your connected Stripe account through Settings → Integrations → Stripe.

Connecting Stripe

  1. Go to Settings → Integrations.
  2. Click Connect Stripe and complete the OAuth flow.
  3. Your account's products show up in the Payment field's product dropdown.

Once connected, Payment fields can take charges — see Payment Fields for modes.

Recurring Subscriptions

When a Payment field's mode is Sell Products and a product is configured for MONTHLY / YEARLY / QUARTERLY billing, submitting the form creates a Stripe customer + subscription. The lead is then linked to the Stripe customer, and you can manage subscriptions from Payment & Billing → Subscriptions.

Webhooks

Stripe events (subscription created, charge succeeded, charge failed, subscription updated) flow back through your account's Stripe webhook into the CRM, updating the lead's billing status and triggering any subscription-aware workflows.

Public Submission API

You can submit to a form programmatically without going through the hosted UI. POST to:

POST /api/forms/public/{slug}/submit

Body:

{
"responses": {
"<field-uuid>": "<value>",
"...": "..."
},
"is_final": true,
"submission_id": null,
"submitted_from_page": "https://your-app.com/...",
"referrer_url": "https://google.com/...",
"is_embedded": false
}

Response:

{
"submission_id": "...",
"lead_id": "..."
}

Use this when you want to write submissions from your own backend (e.g. importing form responses from another system, or adding submissions during a programmatic flow).

File Upload API

For File Upload fields, the upload endpoint:

POST /api/forms/public/{slug}/upload

Multipart body with a single file field. Returns:

{
"url": "/api/upload/<tenant>/attachment/<uuid>.<ext>",
"filename": "<uuid>.<ext>",
"original_filename": "<original>",
"size": 12345,
"content_type": "application/pdf"
}

The returned url is what you put into the form's responses payload for that field's UUID.

Reporting API

For querying submissions:

POST /api/form-submission-reporting/query

Body lets you specify form, columns, filters, sort, limit/offset for paginated reports. See Submissions → Dynamic Query API.

Workflows Variables Inside Forms

Inside the form builder itself, you can reference workflow-set variables on the lead via templating in places that support it (label text, statement bodies, ending screen titles). Use:

{{lead.first_name}}
{{lead.company}}

These render server-side when the form is fetched, so the visitor sees their personalized data on form load (only works for returning visitors with cached lead context).


Next Steps