The first n8n workflow I teach is two nodes and no other apps:

  1. On form submission hosts a form with two questions: Name and What do you need help with?
  2. Edit Fields (Set) writes a one-line summary of each inquiry.

The made-up business is a bookkeeping firm that gets new client inquiries by phone, email and sticky note, and loses some. The fix is one form that catches all of them.

It's a good first workflow because the only "code" in it is one expression, and that one expression teaches the thing that confuses most beginners: why $json.Name works and $json.What do you need help with? doesn't.

Build it

  1. Add first step... → On form submission.
  2. Form Title: New client inquiry.
  3. Add Form Element → Text Input, Label Name.
  4. Add Form Element → Label What do you need help with?
  5. Click Execute step. n8n starts listening and opens the test form. Fill it in (I used Dana Ortiz and Monthly bookkeeping for my design studio) and submit.

The OUTPUT panel now shows 1 item. That's the first concept worth getting straight.

Items: one per record

Data moves between n8n nodes as items. Each item is a JSON object. One form submission is one item, with one field per question:

[ { "Name": "Dana Ortiz", "What do you need help with?": "Monthly bookkeeping for my design studio", "submittedAt": "..." } ] 

Every node after the trigger runs once per item. If ten people submit, the next node handles ten items. You almost never write a loop.

The expression

Click the + after the trigger, search Edit, pick Edit Fields (Set), then Add Field. Name it summary, set it to String, and in the value, either drag the fields in from the INPUT panel or type:

{{ $json.Name }} needs help with: {{ $json['What do you need help with?'] }} 

The preview underneath shows:

Dana Ortiz needs help with: Monthly bookkeeping for my design studio 

Dot vs bracket notation

Everything inside {{ }} is JavaScript. $json is the current item's data as a plain object. So the normal JavaScript rules for property access apply:

  • Dot notation works when the key is a valid identifier: letters, digits, _ and $, not starting with a digit. Name qualifies, so $json.Name works.
  • Bracket notation works for any key. What do you need help with? has spaces and a ?, so it has to be $json['What do you need help with?'].

If you drag the field from the INPUT panel, n8n picks the right notation for you. That's the best habit: drag first, then read what n8n wrote, and you'll learn the rule without memorizing it.

The same applies to anything that comes from a human-labelled source: Google Sheets headers (Call to Action), CSV columns (Order #), form questions. Rename the source to something boring if you can. If you can't, use brackets.

Three habits that save debugging time

1. Give missing values a default. Optional questions come through empty or missing. Optional chaining and nullish coalescing keep the summary readable:

{{ $json['Phone']?.trim() || 'no phone given' }} 

2. Reference an earlier node by name when $json isn't enough. $json is only the item coming into the current node. Two or three nodes later, once a node in between has replaced the data, reach back explicitly:

{{ $('On form submission').item.json.Name }} 

.item follows the item lineage, so you get the name that belongs to this inquiry, not the first one in the run.

3. Read the preview, not the expression. The green preview under the field is the evaluated result for the current test item. If it says undefined, the key is misspelled (case matters, and so does a trailing space in a sheet header). If it's red, the JavaScript itself is broken.

Check the runs

Every run, test or real, is saved under the Executions tab, with the input and output of each node. When a summary comes out wrong next week, that's where you find the item that caused it.

One more thing to know before you share the form: the address shown while you test (/form-test/...) only listens while you're testing in the editor. The production address (/form/...) works all the time, but only after you publish the workflow.

You can build this exact workflow click by click in a free practice copy of the n8n editor (28 checked steps, about 8 minutes, no account): n8n Tutorial for Beginners: Your First Workflow.