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.
Consent
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_fieldnames a field to render in the page but hide from people, for example withposition: absolute; left: -9999px,tabindex="-1"andautocomplete="off". Automated fillers complete it. A submission that fills it receives an ordinary success response and is discarded. - Timing token.
cms.createLeadFormTokenissues a token for one visit; request it when the form is shown and send it back asform_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.availablereports whether a challenge can be shown for the store. When it is false,captcha.requiredandcaptcha.on_demandare false and submissions are protected by the other mechanisms. When it is true,captcha.requiredis true when every submission must include acaptcha_token, the result of the challenge widget rendered withcaptcha.site_key. Whencaptcha.on_demandis true, the form asks for a challenge only while it is receiving unusually heavy traffic: the submission is refused with400anddetails.reasonofcaptcha_required, the storefront shows the widget, and the submission is sent again with the token. A token that fails verification is refused withcaptcha_failed. When a challenge is required and cannot be verified, the call answers503and 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 answers429 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
A400 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
cms.subscribeNewsletter, remains available for a bare email signup with no form definition.
