Browse documentation
Contacts & audiences
Collect signups from a Webflow site
5 min read · Updated
Keep the form you designed in Webflow. One attribute on the form and one line of code on the site send every address to your contacts, with consent recorded, the lists you choose joined, and any automation waiting for a new subscriber started.
How it works
A native Webflow form posts to Webflow’s own servers, and Webflow offers no server-side hook to change that. The submission is taken in the visitor’s browser instead.
- The script you paste watches only the forms you marked, so your contact form and search box are untouched.
- On submit it reads the fields the form actually has and posts them to a Contact webhook — a URL that can add a subscriber and nothing else.
- Sendtim creates or updates the contact, records consent, adds them to your lists, and enrolls them in any matching automation.
- Your form’s own Success or Error state is then shown, so what you styled in Webflow is what visitors see.
No API key goes near the website. A key can do everything an admin can and anything in a published site can be read by every visitor; a webhook URL can only append a contact, and it can be paused or rotated at any time.
Submissions no longer reach Webflow, so they do not appear in Webflow’s form submissions and do not count against its submission limit. Sendtim is the record.
Set it up
- In Sendtim, open Settings → Integrations → Webflow. If you have no endpoint yet, select Create a Webflow endpoint.
- In the Webflow Designer, select the Form element itself — not the block around it. Under Element settings → Custom attributes, add
data-sendtimwith an empty value. - Make sure the email input is required. Webflow names a field after its label, so a field called “Email” is already recognised.
- Back in Sendtim, tick the lists new signups should join and copy the generated snippet. It already contains your endpoint.
- In Webflow, open Site settings → Custom code, paste the snippet into Footer code (the box labelled Before </body> tag) and save.
- Select Publish, then submit the form once on your live site. The contact appears under Contacts.
Where the script goes
Always the body box, never the head: the script attaches to forms, so the markup has to exist first. Webflow documents both boxes in Custom code in head and body tags and Custom code in Site settings.
| Put it in | When |
|---|---|
| Site settings → Footer code | The usual choice: it runs on every page, so a footer newsletter form works wherever it appears. Webflow requires a paid Site plan for custom code. |
| Page settings → Before </body> tag | One landing page only. Page code runs after site code and both can be present. |
| An embed element on the canvas | Works, but ties the script to that element: remove it and signups stop silently. Prefer the settings boxes. |
Custom code in Site settings runs on the published site only — not in the Designer and not in Preview. A form that seems to do nothing while you are designing is expected.
How fields are matched
Field names are matched loosely: case, spaces, hyphens and underscores are ignored, and anything starting with email is the address.
| Field name in Webflow | Becomes |
|---|---|
| Email, Email Address | The contact’s email address. Required. |
| First Name, Last Name, Surname | First and last name |
| Name, Full Name | Split on the first space into first and last name |
| Company, Organization, Job Title, Role | Company and job title |
| Phone, Mobile, Country, City | Phone, country and city |
| Consent, GDPR, Opt-in, Terms | The consent tick. Its label is stored as the wording agreed to. |
| Lists, Groups | Checkbox values are read as list ids |
| Anything else | A custom contact property named after the field: “Plan Size” becomes plan_size. Hidden fields included. |
Nothing is guessed when you say otherwise: data-sendtim-field on an input pins what it is (email, firstName, consent, ignore and so on), and data-sendtim-property="plan" sends it under exactly that name.
Lists, and letting visitors choose
- Fixed: the endpoint’s own list plus anything you ticked when generating the snippet. Everyone who signs up joins these.
- Chosen by the visitor: add a checkbox group named Lists to the form and set each checkbox’s value to a list id. Only the ticked ones are joined.
A list can only be named by a page once Allow website signups is turned on for it, in the list’s own settings. Those ids travel through the visitor’s browser where anyone can change them, so without that switch a leaked snippet could file signups into any list in the workspace — including one a campaign is about to send to.
An id that is not open is ignored and the signup still succeeds: a subscriber is never thrown away over a misconfigured checkbox. The setup page’s Recent submissions panel names the ignored ids, which is where to look when a checkbox appears to do nothing.
Consent and spam
Submitting a signup form is the consent act, so a form without a tick box still records consent against the contact. Add a consent checkbox and mark it required when you need explicit consent — its label is then stored verbatim on the submission, so the record shows what the person actually agreed to rather than what the form says a year later.
The script adds a hidden field no person can see, and a submission completed faster than two seconds is treated as automated. Both are answered with an ordinary success and stored nowhere. Someone who unsubscribed or hard-bounced is never resubscribed by a form on a website, and the visitor still sees your success message — the endpoint never reveals who is already known.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| Webflow’s success message shows but no contact arrives | The script did not take the form over, so Webflow handled it. Check the form carries data-sendtim, that the snippet is in the footer box, and that the site has been published since. |
| Nothing happens at all | Open the browser console. “no email field found” means the address input’s name was not recognised — add data-sendtim-field="email" to it. |
| The error state shows every time | The console logs the status and the reason. A 403 means a paused endpoint or a website that is not allowed; a 429 means the rate limit. |
| A returning contact’s name did not change | Deliberate. An address that is already a contact keeps what it has and gains only what it was missing, because a value your team typed must not be overwritten from a public form. |
Add data-sendtim-debug="true" to the script tag to log the form it took over and the payload it sent. Every submission, rejections included, is listed under Settings → Integrations → Webflow with its outcome and reason.
More in Contacts & audiences
- Contacts & audiences
Import contacts from a CSV file
Upload a CSV of up to 200 MB, map its columns to contact fields, and add everyone to lists in one pass.
- Contacts & audiences
Organize contacts with lists and segments
When to use a static list and when a segment that updates itself, and how to build both.
- Contacts & audiences
Collect signups with a form
Build a signup form, choose the list it feeds, record consent, and publish it.
