Before you start
You need an API key. The form carries it in the page source, so it is a public value by design, and the only thing it can do is subscribe someone.Create an API key
Website form, then select Create key.Copy the key immediately
Install
Copy the snippet
Paste it into your page
Replace the key
Restrict which websites can submit
Test it
Form attributes
Every attribute goes on the<form> element itself.
Thanks for subscribing.We could not subscribe you. Please try again.footer-signup. Stored on the
contact as the embeddedFormId property so you can tell your forms apart
later. Max 120 characters. It is a label you set in your own page source,
so anyone can change it. Treat it as a reporting convenience, never as a
restriction, which is why the allowed-websites list below is set once for
the whole workspace rather than per form.<div data-senderz-msg></div> wherever you want the confirmation or error text to appear. If you leave it out, the script appends one to the end of the form, which is usually below your button.
Field names decide where a value lands
This is the part worth getting right. The script reads thename attribute of every input and decides what to do with the value.
- An input named
emailbecomes the contact’s email address. - An input named
phoneorsmsbecomes the contact’s phone number. - Every other named input is matched against the built-in contact properties. A match is stored on the contact. A name that matches nothing is silently discarded.
tagsis parsed and then dropped. Tag people with an automation step instead.- Consent flag inputs such as
accepts email marketingare dropped. Consent on an embedded form is decided by the submission itself, not by a field value.
What a submission does
Match or create the contact
Subscribe the channels that were supplied
phone or sms input subscribes the SMS channel as well.Record the opt-in
Fill in the blanks
Fire your automations
It does not add anyone to a list
Despite the trigger being called Added to list, an embedded form does not put the contact into any Senderz list. It only fires the trigger. If you want form subscribers to end up in a specific list, build an automation on the Added to list trigger with an Update in list step that adds them. Filter that automation if the same trigger is used elsewhere in your workspace.What is not stored
The page URL the form was submitted from is sent with every entry, but Senderz does not currently keep it. You cannot segment or report on which page somebody signed up from. Usedata-form-id for that instead: it is stored, and it is per form rather than per page.
Allowed websites
Settings → Embedded Forms → Allowed websites restricts which sites may submit through your key.- Leave the box empty to accept submissions from any website. This is the default.
- Add one origin per line to restrict it. Up to 20 entries.
- A full origin such as
https://example.commust match exactly, including the scheme and the port. - A bare host such as
example.commatches eitherhttporhttps. - Entries are lowercased and de-duplicated when you save. Anything that is not a valid web address is dropped silently on save, so re-open the box after saving to confirm what stuck.
403: a submission from a site that is not listed, and a submission that arrives with no origin at all, such as a plain curl call from a terminal.
Submissions sent by the Senderz WordPress plugin are not checked against this list. They come from your server rather than from a browser, so there is no origin to check. See WordPress sites.
Styling
The script adds asenderz-form class to your form and a small stylesheet with sensible defaults. Override any of it from your own CSS.
Sending…. The original label comes back when the request finishes, whether it succeeded or not. On success the form is also reset, so the fields clear.
Hook the success event
The form dispatches asenderz:subscribed event when a submission succeeds. It bubbles, so you can listen on the form or on the document.
email only.
Forms added after page load
The script watches the page for new content, so a form rendered later by your site’s JavaScript, a single-page app route change, or a popup library is picked up automatically. There is nothing to call and nothing to re-initialise.Phone-only forms
The shipped script requires an email address. A visitor who fills in only the phone field seesPlease enter your email address. and the form does not submit.
The underlying API is happy to take a phone number with no email. If you need a phone-only signup form, post to https://api.senderz.app/api/v1/forms/subscribe from your own code rather than using the script. See the Forms API for the request shape.
Phone numbers are read as Israeli by default. A local number such as 052-123-4567 is understood. For an international number, ask visitors to include the country code with a leading +.
Rate limit
Submissions are limited to 10 per minute per visitor IP address. A visitor over the limit gets a429 and the form shows its error message.
This is per visitor, not per workspace, so a busy page is unaffected. It does mean that testing the form ten times in quick succession from your own machine will lock you out for the rest of the minute.
WordPress sites
If your site runs WordPress, you do not need this snippet. The Senderz WordPress plugin can capture submissions from the form plugin you already use, with no HTML to paste and no API key in your page source. Go to Senderz Marketing → Forms in your WordPress admin. Supported form plugins are Contact Form 7, WPForms, Gravity Forms, Elementor Pro Forms, Fluent Forms, Formidable Forms and Ninja Forms. Submit each form once so its fields are detected, then map them. Two differences are worth knowing:- You map fields to Email, Phone, First name, Last name or a Marketing consent checkbox. That is the whole list. Anything else is not sent.
- Consent is opt-in only, and you choose per form: never subscribe and capture the contact only, treat the whole form as a marketing opt-in, or subscribe only when the consent checkbox is ticked. Contacts are captured either way.
Troubleshooting
The form only ever shows a generic error message, on purpose, because a visitor cannot act on a status code. To see the real reason, open your browser’s developer tools, go to the Network tab, submit the form, and inspect thesubscribe request.
Nothing happens when I submit, and no request is sent
Nothing happens when I submit, and no request is sent
<form> element
carries data-senderz-form, and that the script tag is present on the
page and loading without an error in the Console tab.If the message element shows Form is not configured, the script found
your form but data-tenant or data-key is missing.The request returns 401
The request returns 401
The request returns 403
The request returns 403
https://www.example.com does not match an entry of
https://example.com. If your list is empty and you still get a 403,
contact support.The request returns 429
The request returns 429
The request returns 400
The request returns 400
The contact appears but a field is empty
The contact appears but a field is empty
name attribute against the table in
Field names decide where a value lands.The other cause is that the contact already had a value for that
property. A form fills blanks, it does not overwrite.The phone number saved but the contact is not subscribed to SMS
The phone number saved but the contact is not subscribed to SMS
phone or sms. A name
like mobile or tel still matches the phone property, so the number is
stored, but only phone and sms count as a deliberate SMS opt-in.
Rename the input to phone.My welcome automation did not fire
My welcome automation did not fire
Subscribers are not showing up in my list
Subscribers are not showing up in my list

