From Spreadsheet Chaos to a Working CRM: How a Non-Coder Built Internal Tools with Airtable, Make and n8n Using Prompts

Most operations managers don't have a budget for a dev team, but they do have a problem: data lives in five spreadsheets, three Google Forms, and someone's inbox. The gap between "I need a CRM" and "I can build a CRM" used to be a six-month engineering project. In 2026, that gap is a weekend and a well-written prompt.

This is the story of Marina, an operations manager at a 40-person logistics brokerage. She had no programming background — her last technical achievement was a VLOOKUP that broke every Monday morning. Over two weeks she shipped a working CRM on Airtable, automated weekly reporting through Make, and wired the whole thing to her invoicing stack with n8n. No developers were harmed in the making of this system.

Below is the exact collection of prompts she used, organized by difficulty. Each one includes the task, the prompt itself, and what the output actually looked like. Treat them as templates — the structure matters more than the specific wording.

The tooling landscape here is real and documented: Airtable's REST API (airtable.com/developers/web/api/introduction), Make's scenario builder (make.com/en/help), and n8n's node-based workflow engine (docs.n8n.io). Everything below uses features that exist in those products today.

Basic Level: Getting the Data Model Right

1. Turning a messy spreadsheet into a normalized Airtable schema

Task: You have a flat export with duplicated client names, inconsistent statuses, and no relations. You need a schema that Airtable can actually work with.

Prompt:

I have a CSV export with these columns:
client_name, contact_email, deal_stage, deal_value, last_contact_date, notes

The same client appears in multiple rows with slightly different spellings.
Design an Airtable base schema with proper normalization:
- Which tables do I need?
- What field types for each column (use Airtable's actual field types)?
- Which fields should be linked records vs. formulas vs. lookup fields?
- Give me a migration order: which table do I populate first?
Assume I'll import the CSV as-is into a staging table.

Example result: The model returned a three-table design: Clients, Deals, Interactions. It correctly specified that deal_stage should be a single-select with fixed options (not free text), that client_name in Deals should be a linked record to Clients, and that last_contact_date should be a rollup over Interactions rather than a manually edited field. It also flagged the deduplication step: import to a Staging table, use a formula field with TRIM(LOWER({client_name})) as a normalization key, then dedupe before creating linked records. That last detail is the kind of thing you learn after breaking a base once.

2. Writing Airtable formulas without memorizing the function list

Task: You need a computed status field, but Airtable's formula syntax is its own dialect.

Prompt:

In Airtable, I have a Deals table with fields:
- {Deal Value} (currency)
- {Close Date} (date)
- {Stage} (single select: Lead, Qualified, Proposal, Won, Lost)

Write a formula field called {Health} that returns:
- "At risk" if Stage is Lead or Qualified AND Close Date is more than 30 days in the past
- "Closing soon" if Close Date is within the next 7 days and Stage is not Won/Lost
- "On track" otherwise
Use only real Airtable formula functions. Explain any function that isn't obvious.

Example result: The output used DATETIME_DIFF(TODAY(), {Close Date}, 'days') and AND()/OR()/IF() nesting. It explained that TODAY() recalculates on base load, not in real time, and warned that comparing dates without DATETIME_DIFF silently fails because Airtable treats dates as strings in some contexts. That warning alone saved an afternoon of debugging.

3. Generating realistic test data for a base

Task: An empty base makes it impossible to test automations. You need ~200 plausible records.

Prompt:

Generate a CSV with 200 rows for a logistics CRM. Columns:
client_name, city, deal_value, deal_stage, created_date, contact_email
Rules:
- Cities: realistic US and EU freight hubs
- deal_value: $2,000–$80,000, weighted toward smaller deals
- deal_stage: distribution 40% Lead, 25% Qualified, 20% Proposal, 10% Won, 5% Lost
- created_date: spread over the last 180 days
- Emails must be syntactically valid and match the client name
Output raw CSV only, no commentary.

Example result: A clean 200-row CSV. The useful part was the explicit distribution instruction — without it, models default to uniform randomness, which makes funnel automations look broken because every stage has equal volume. Import this into a Staging table, verify the formulas fire correctly, then delete.

4. Debugging a Make scenario that fails silently

Task: A Make automation runs but produces no output. Make's error messages are often unhelpful.

Prompt:

My Make scenario has these modules in order:
1. Airtable "Watch Records" trigger
2. Router with two paths
3. Path A: Gmail "Send an Email"
4. Path B: Google Sheets "Add a Row"

The scenario shows "Success" in the history but nothing happens.
Walk me through the five most likely causes, in order of probability,
and tell me exactly which panel in Make to check for each one.

Example result: The top answer was correct and specific: the Airtable trigger was watching a view that filtered out the records being created, so the trigger never fired — Make reported success because the scenario executed with zero bundles. The other causes listed were real Make gotchas: a filter on a router path that evaluates to false, a module that succeeded but wrote to a test sheet, a trigger set to "Watch Records" instead of "Watch Records (by Created Time)" causing it to miss updates, and a schedule set to manual. Each came with a pointer to the exact Make UI panel.

Advanced Level: Cross-Service Automation

5. Designing an n8n workflow from a plain-language description

Task: You know what you want the workflow to do, but not which nodes to string together.

Prompt:

Design an n8n workflow that does this:
Every Monday at 8am, pull all Airtable records from the Deals table
where Stage = "Won" and Close Date is in the last 7 days.
For each one, create an invoice in Stripe, then post a summary message
to a Slack channel with the client name and amount.

Tell me:
- Exact node types in order
- Where I need a Code node vs. native nodes
- How to handle the Airtable pagination (the table has 4,000+ rows)
- What to do if Stripe returns an error for one record
Use n8n's actual node names.

Example result: The workflow used Schedule Trigger → Airtable (with the filterByFormula option) → Split In Batches → Stripe → Slack. The pagination advice was the valuable part: n8n's Airtable node handles pagination automatically when you use the "List" operation, but the filterByFormula should push the date filter to Airtable's API rather than filtering in n8n, because pulling 4,000 rows to discard 3,950 is slow and burns execution time. For error handling it recommended Continue On Fail on the Stripe node plus an IF node downstream to route failures to a separate Slack alert.

6. Writing a custom n8n Code node when native nodes fall short

Task: You need to reshape data in a way no built-in node handles cleanly.

Prompt:

Write an n8n Code node (JavaScript) that takes incoming items and:
- Groups them by the "client_id" field
- Sums "amount" within each group
- Outputs one item per client with fields: client_id, total_amount, deal_count
- Skips clients with total_amount = 0

Use n8n's Code node API: items array, return format, $input.all() or similar.
Include a comment explaining what each block does.

Example result: A working Code node using $input.all(), a reduce into a Map, and a return of [{ json: {...} }] objects. The model correctly noted that in recent n8n versions the Code node runs in a sandboxed environment where require is restricted, so you can't pull in external npm packages — a constraint that trips up people who expect a full Node.js runtime.

7. Building a two-way sync between Airtable and a Google Sheet

Task: Finance insists on working in Sheets. You refuse to maintain two sources of truth.

Prompt:

I need a two-way sync between an Airtable table and a Google Sheet.
Direction A: Airtable record created/updated → upsert row in Sheet.
Direction B: Sheet row edited → update corresponding Airtable record.

How do I prevent infinite loops where A changes B which changes A?
Explain the mechanism, not just "add a flag".
Which tool should I use — Make or n8n — and why?

Example result: The loop-prevention explanation was the payoff. The recommended pattern: maintain a last_synced_at timestamp field on both sides. Before writing, compare the incoming record's modification time against last_synced_at; if the change originated from the sync itself, skip. It also noted that Google Sheets has no reliable "last modified" timestamp per row, so you need a hidden helper column populated by the automation. On tool choice it recommended Make for this case because its Google Sheets modules handle row-matching more gracefully than n8n's, but noted n8n is better if you need to self-host for data-residency reasons.

8. Rate-limit-safe bulk operations

Task: You need to update 3,000 Airtable records, but the API will throttle you.

Prompt:

I need to update 3,000 records in Airtable via API.
Airtable's rate limit is 5 requests per second per base.
Design a batching strategy:
- How many records per request?
- How to handle 429 responses?
- Should this run in n8n, Make, or a standalone script?
Give me pseudocode for the retry logic with exponential backoff.

Example result: Airtable's batch update endpoint accepts up to 10 records per request, so 3,000 records means 300 requests — at 5/sec that's 60 seconds minimum. The model recommended Split In Batches with a batch size of 10 in n8n, plus a Wait node set to 250ms between batches to stay under the limit, and a retry on 429 with exponential backoff starting at 1s, doubling up to 32s, max 5 attempts. This is the correct shape for Airtable's documented limit.

9. Turning a Make scenario into a documented runbook

Task: You built something clever six months ago and now can't remember how it works.

Prompt:

Here's the JSON export of my Make scenario [paste JSON].
Write a runbook for a colleague who has never seen it. Include:
- What triggers it and when
- What each module does in plain English
- What happens on failure and who gets notified
- What to check first if it stops working
- Any hard-coded values that would need changing if we rename a field

Example result: A two-page Markdown document. The genuinely useful output was the last section — the model scanned the JSON and flagged three hard-coded references to field names and one hard-coded Slack channel ID that would silently break if anyone reorganized the Airtable base. Nobody writes that section voluntarily.

Expert Level: Architecture and Governance

10. Choosing between Make, n8n, and Zapier for a specific workload

Task: Every article says "it depends." You need an actual decision.

Prompt:

I'm building internal tooling for a 40-person company.
Workloads: (1) CRM sync between Airtable and HubSpot,
(2) weekly PDF report generation from Airtable data,
(3) invoice creation in Stripe triggered by Airtable status change,
(4) Slack notifications from all of the above.
Total monthly task volume: roughly 15,000 operations.

Compare Make, n8n, and Zapier for this specific mix.
Include: pricing model implications at this volume,
self-hosting tradeoffs, error-handling capabilities,
and which workload belongs on which platform if I use more than one.

Example result: The recommendation split the workloads. Zapier was ruled out on cost at 15,000 tasks — its per-task pricing scales steeply, while Make counts operations and n8n self-hosted has no per-execution cost. The PDF generation was flagged as a poor fit for all three natively and recommended as an n8n Code node calling a library, or a separate service. The CRM sync was recommended for Make because of its mature HubSpot modules. The key insight: don't pick one platform dogmatically; pick per-workload and let them talk to each other via webhooks.

11. Designing for data residency and access control

Task: Legal asks where the customer data physically lives.

Prompt:

Our automation stack handles customer PII: names, emails, deal values.
It runs across Airtable, Make, and n8n.

Map out the data residency and access-control implications:
- Where does data physically reside in each tool's default configuration?
- What changes if we self-host n8n?
- Which access controls should we configure on each platform?
- What should we document for a GDPR-style audit?
Be specific about which settings exist in each product.

Example result: A structured breakdown. Airtable data resides in US regions by default for most plans, with EU hosting available on enterprise agreements. Make stores scenario data on its EU infrastructure for EU accounts. Self-hosted n8n keeps all execution data on your own infrastructure, which is the cleanest answer for residency but shifts backup and uptime responsibility to you. On access control it listed Airtable's granular sharing and API token scoping, Make's team roles, and n8n's user management — and recommended documenting the data flow as a diagram for the audit, since auditors ask for flow, not tool names.

12. Building an idempotency layer so retries don't duplicate data

Task: When a workflow fails halfway and retries, you get duplicate invoices. Finance is unhappy.

Prompt:

My n8n workflow creates Stripe invoices from Airtable records.
If it fails after creating an invoice but before updating Airtable,
a retry creates a duplicate invoice.

Design an idempotency solution:
- Where should the idempotency key live?
- How do I check it before creating the invoice?
- How does this interact with Stripe's own idempotency support?
Give me the node sequence.

Example result: The correct answer uses Stripe's native idempotency keys — the API accepts an Idempotency-Key header, and reusing the same key returns the original response instead of creating a duplicate. The design: generate a deterministic key from the Airtable record ID (e.g., invoice-{record_id}), pass it to the Stripe node, and additionally store the resulting Stripe invoice ID back in Airtable as a guard. Both layers together mean even a crash mid-workflow can't duplicate. This is a real Stripe feature, documented in their API reference.

13. Auditing an automation stack for single points of failure

Task: Everything works — until one API key expires and the whole company stops.

Prompt:

Here's my full automation architecture:
- Airtable as the database
- Make scenarios for CRM sync and reporting
- n8n for invoicing and Slack alerts
- All connected with personal API keys

Do a failure-mode analysis. For each component:
- What breaks if it goes down?
- What breaks if a credential expires?
- What's the recovery procedure?
Prioritize by business impact.

Example result: The highest-impact finding was the personal API keys. Every credential was tied to one employee's account, meaning a departure or a password reset would silently break every automation. The fix: migrate to service accounts or dedicated integration users where the platform supports it, and document credential ownership. Second-highest was the lack of alerting on failed executions — Make and n8n both have failure notifications, but they weren't configured, so failures were discovered by users complaining. Both are real, configurable features in each platform.

14. Generating a cost model before you build

Task: You need to justify the tooling spend before committing.

Prompt:

Estimate monthly cost for this stack at 15,000 operations/month:
- Airtable (Team plan, 5 users, ~50,000 records)
- Make (Core plan or above as needed)
- n8n (self-hosted on a $20/month VPS vs. n8n Cloud)
- Stripe (standard transaction fees)

Show the math for each. Flag where I'm likely to exceed a plan tier
and what the next tier costs. Don't guess at prices — state your
assumptions and tell me which numbers I need to verify on each vendor's pricing page.

Example result: The model refused to invent prices, which is the correct behavior — it laid out the calculation structure and listed exactly which pricing pages to check: Airtable's pricing page for per-seat and per-record limits, Make's operations-based tiers, n8n's cloud vs. self-hosted comparison, and Stripe's standard fee schedule. It flagged the most likely tier breach: Airtable record limits, since 50,000 records sits near a common plan boundary. The value here is the structure, not the numbers — always verify current pricing directly.

15. Writing the prompt that writes the next prompt

Task: You've built the stack. Now you want to extend it without re-learning everything.

Prompt:

You are helping me extend an existing automation stack.
Context: Airtable (Clients, Deals, Interactions tables),
Make (CRM sync), n8n (invoicing).

I want to add [new feature].
Before answering, ask me the three questions you need answered
to give a correct design. Then give the design.
Assume I know Airtable formulas but not API details.

Example result: This is the meta-prompt, and it's the most reused one. Instead of generating a plausible-but-wrong design, the model asks clarifying questions first — typically: what triggers the feature, what's the expected volume, and what happens on failure. Those three questions catch the majority of design mistakes before a single node is built. Marina's note after two weeks: "The prompts didn't write the system. They stopped me from building the wrong one."

What Actually Made This Work

The prompts above are useful, but the pattern behind them matters more. Three things separated this from a stack of abandoned half-built automations.

First, describe the outcome, not the implementation. "Design a schema with proper normalization" beats "make me some tables." The model knows more about Airtable's field types than you do — let it propose, then correct it.

Second, ask for the failure mode explicitly. Almost every prompt above includes a line about what breaks. That single habit caught the silent Make trigger, the duplicate invoices, and the personal API keys — three problems that would each have cost days.

Third, verify anything numeric against the vendor's own documentation. Models are reliable on structure and unreliable on prices, limits, and version-specific behavior. Airtable's API docs, Make's help center, and n8n's documentation are the sources of truth; the prompt is the accelerator, not the authority.

Marina's stack has been running for months. It handles client records, weekly reports, and invoicing for a 40-person company, maintained by one person who still can't write a for-loop. The tools were always capable of this. The prompts are what made them accessible.

If you're staring at five spreadsheets and a broken VLOOKUP, start with prompt #1. You don't need to plan the whole architecture — you need to fix the data model first. Everything else follows.

← All posts

Comments