Formstep

Send the form already filled in.

A request carries what you already know about the person: their name, their company, the amount on the invoice. They check it, correct what changed and add what is missing, and what must not change is locked.

Updated

What the recipient sees

Your form, in your brand and their language, with their values already in the fields. A prefilled answer is editable, so they correct what changed since you last heard from them. A locked answer shows the value with the note “Filled in by the sender”, and nothing they do changes it. There is no account and no captcha: the link already knows who it is for.

A form as the recipient opens it: the name filled in and marked Filled in by the sender, the email filled in and editable, and two empty questions below
The name is locked, the email is prefilled and editable, and the rest is theirs to answer.

Four kinds of value

A request carries four kinds of value. Each answers a different question, and mixing them up is the most common first mistake.

Value What it is for The recipient Comes back
Prefill Starting answers for visible questions: the company name from your CRM, last year’s figures Sees it and can change it As an answer
Locked field A prefilled answer they only confirm: a contract number, an agreed price Sees it and cannot change it As an answer
Request context Values for hidden fields, such as a case number, that logic, calculations and email text can use Sees it only where you mention it Unchanged, with the answers
Request metadata Your own bookkeeping: a workflow run id, a CRM record id Never sees it In every callback

Where the values come from

  • Typed in. The New request sheet lists the form’s fields under What they see. Fill in what you know, and select Lock on anything that must not change.
  • A list. A bulk send takes a CSV whose columns are named after field keys, so each person on the list gets their own values. Up to 500 people per send, on Pro and Business.
  • A workflow. An n8n workflow or a Zap reads the person in your CRM and passes the values when it creates the request. The two-form workflow templates do exactly that, from HubSpot.
  • Code or an AI agent. fields.list returns the form’s field keys, what each one takes and the option keys of every choice. requests.create sends the request with prefill, readonly and context. An agent uses the same two calls over MCP.
The New request sheet: a recipient's email and name, then What they see with the company name filled in and locked, the contact name empty, and a hidden case id

The New request sheet: two of three fields filled in, the company name locked, and a hidden case id the person never sees.

{
  "method": "requests.create",
  "params": {
    "formId": "j57...",
    "recipient": { "email": "ada@acme.example", "name": "Ada Lovelace" },
    "prefill": { "company_name": "Acme Ltd", "contact_email": "ada@acme.example" },
    "readonly": ["company_name"],
    "context": { "case_id": "CASE-4471" },
    "delivery": "email",
    "callbackUrl": "https://automation.example/webhook/CASE-4471"
  }
}

Most form tools prefill through the address: ?name=Ada&amount=1420 on a public link. Three things go wrong. Anyone who has the link can change the values. The values are visible to anyone the link is forwarded to. And the form still has no idea who answered, so your workflow matches the submission back to the person by hand.

A request link is for one person. It ignores URL parameters, the prefill travels with the request rather than in the address, and the answers come back tied to that recipient. Why not just use a form builder? goes through the six gaps one by one.

What cannot be prefilled

Files, signatures, payments, bookings and the documents you ask them to read: the recipient supplies those. A calculated field works out its own value, and a hidden field takes request context instead. Text, numbers, dates and times, choices, switches, matrices and repeating groups all take prefill. Creating a request lists what each field type takes.

What comes back

Every answer returns under its field key, whether the person typed it or you sent it, together with the context unchanged and your metadata. On the request page, a prefilled answer carries a Prefilled mark, so an operator can see what came from you. The same keys arrive on every request of that form, in every language, so the step after the form never needs to change.

Start from a template

Questions about prefilled forms

Something else on your mind? The docs cover every setting, and we answer email.

Read the docs

Yes, unless you lock the field. A locked field shows the value with the note "Filled in by the sender" and cannot be edited. Locking is set per request, not on the form, and a locked required field must have a value, so the person can always submit.

A share link can fill hidden fields from its URL, which is right for tracking where a response came from. Values about one person belong on a request: they travel with the request, not in the address bar, and a request link ignores URL parameters, so nobody can change them.

Yes. Prefill, locked fields and request context are on every plan, from the dashboard, the API, MCP, n8n and Zapier. Invitation and reminder emails are Pro and Business; on Free you send the link yourself.

Send the option key, not its label. fields.list returns both for every choice question, and a column in a bulk-send CSV takes either one. Option keys do not change when you reword or translate a label.

Formstep does not read your CRM. A workflow looks the contact up in its own HubSpot step and passes the values as prefill. In the New request sheet, picking a HubSpot contact fills in their name and email. With the HubSpot integration, the answers update that same contact.

Collect information from anyone.

Publish a sample form, answer it as your recipient would, and watch the answers come back. No account needed.

Read the docs