Skip to main content

Lead Forms

A lead form is a signup form a merchant defines in their dashboard: an email address plus any questions they want answered (a name, a phone number, a preference, a date), and the consent checkboxes that apply. A storefront reads the form’s definition from the API and renders it, so a merchant can change the questions without a storefront release. Each submission adds the shopper to the store’s subscribers and keeps their answers. Two calls cover the storefront side: Both accept publishable and secret keys. A form is addressed by its slug, which the merchant sets (for example spring-lookbook). A form that is a draft, archived or unavailable on the store’s plan answers 404.

The form definition

getLeadForm returns the title, description, button label, success message and the fields in display order. The email address is always collected and is not listed. Each field also carries label, required, and optionally help_text and placeholder. consents holds the wording for up to two checkboxes. consents.email is the email consent text and consents.sms the text-message consent text; a key is absent when the form does not ask for it. The submission carries only the shopper’s choice, consents: { email: true, sms: false }. The wording stored with the submission is the form’s own at that moment, so a later edit by the merchant does not change what a past shopper agreed to. Email and SMS are independent: ticking one does not imply the other. When the form asks for SMS consent, a phone answer is required to receive texts. When double_opt_in is true, the response to a submission has pending_confirmation: true and the shopper is subscribed once they confirm from an email.

Spam protection

Three mechanisms apply to every form.
  • Hidden field. hp_field names a field to render in the page but hide from people, for example with position: absolute; left: -9999px, tabindex="-1" and autocomplete="off". Automated fillers complete it. A submission that fills it receives an ordinary success response and is discarded.
  • Timing token. cms.createLeadFormToken issues a token for one visit; request it when the form is shown and send it back as form_token. A submission carrying a token that is not valid for this form, or that arrives within two seconds of the token being issued, receives an ordinary success response and is discarded.
  • Challenge. captcha.available reports whether a challenge can be shown for the store. When it is false, captcha.required and captcha.on_demand are false and submissions are protected by the other mechanisms. When it is true, captcha.required is true when every submission must include a captcha_token, the result of the challenge widget rendered with captcha.site_key. When captcha.on_demand is true, the form asks for a challenge only while it is receiving unusually heavy traffic: the submission is refused with 400 and details.reason of captcha_required, the storefront shows the widget, and the submission is sent again with the token. A token that fails verification is refused with captcha_failed. When a challenge is required and cannot be verified, the call answers 503 and nothing is recorded.

Limits and idempotency

Submissions are limited per address and per form, and the same email address is slowed after repeated submissions to one form. A limited call answers 429 with a Retry-After header. A body is limited to 16 KB and 30 answers. A secret key is used from a server, where every request arrives from the server’s own address. The server passes the shopper’s address as xForwardedShopperIp so limits apply per shopper; the value is ignored on a publishable key. An idempotencyKey makes a retried submission safe: the same key with the same body returns the original result and records one submission, and the same key with a different body answers 409.

Refusals

A 400 names the answer in details.field and the cause in details.reason. A 403 with details.reason of plan_required is returned when the store’s plan does not include lead forms.

Example

The newsletter call, cms.subscribeNewsletter, remains available for a bare email signup with no form definition.