An n8n workflow turns an event into explicit state transitions. Your first workflow should be deterministic, synthetic, and observable: a manual trigger creates input, a transformation validates it, and the final node produces a reviewable output.
Define the Contract
Use this sample input:
{
"lead_id": "sample-001",
"name": "Sample Customer",
"city": "Lahore",
"interest": "website audit",
"consent_followup": false
}
Goal: normalize allowed fields and create a DRAFT lead summary. Excluded: messaging, CRM writes, real customer data, and marketing.
Build:
Manual Trigger
→ Edit Fields/Set: create sample item
→ validation/IF: required values and allowed city format
→ transformation: create summary and workflow version
→ final output: display draft JSON
n8n passes arrays of items between nodes. Inspect each node’s input and output rather than assuming the shape. Use expressions for simple references; use a Code node only when clearer, tested logic justifies it.
Add Failure Behavior
Create an invalid sample missing lead_id. Route it to an explicit rejected output with error code and safe message. Do not let the main branch continue. Name nodes by business action, not Set1 or IF2.
Pin the workflow version in output and add a note explaining authority. The workflow creates a draft, not a qualified lead or permission to contact.
Worked Example
Valid sample becomes:
{
"lead_id": "sample-001",
"city": "lahore",
"summary": "Website audit enquiry — Lahore",
"status": "DRAFT",
"workflow_version": "lead-normalize-v1"
}
The invalid sample returns MISSING_LEAD_ID. Execution history shows which branch ran. Re-execution creates no external side effect, so iteration is safe.
Failure Cases to Diagnose
- Real contact pasted into tutorial: replace with synthetic fixture.
- Expression references wrong item: inspect input/output and item linking.
- Missing field becomes
undefinedprose: validate before transform. - Draft labelled “qualified”: preserve truthful states.
- Every operation in Code node: prefer visible native nodes where clearer.
- No version/naming: future operators cannot compare behavior.
🇵🇰 Pakistan Angle
Normalize a customer-supplied city only for routing; do not infer province, language, income, or quality from phone prefix or name. Use explicit language preference if needed.
Keep PKR amounts as exact data and separate subtotal, delivery, tax, and pending fees. A first workflow should never calculate a real invoice or send a WhatsApp message without the later validation, consent, idempotency, and approval controls.
Hands-On Exercise
- Build the four-stage workflow.
- Run valid and missing-ID fixtures.
- inspect every node’s data.
- rename nodes and add workflow version.
- export the credential-free workflow JSON for review.
Completion Rubric
- Trigger, input, transform, and output are explicit.
- Fixtures are synthetic.
- Invalid input stops safely.
- Node names express business actions.
- Output state is truthful and versioned.
- Export contains no credentials or private data.
Sources
Key takeaway: begin with a synthetic, deterministic trigger-to-output contract and make invalid state visible before adding any real connector or effect.