Documentation

Workflow Events

QA workflow — events explained

Step-by-step walkthrough of every node in n8n-gumroad-qa-workflow.json. The visual layout is in workflow-diagram.svg (open in any browser). Each node is numbered to match the badge in the diagram.

The workflow is organized into four lanes:

  1. Spec phase — read GumRoad.md and confirm the spec hasn't drifted
  2. Live data — fetch real product data from Gumroad + the deployed website
  3. Validation — run every check, tag each one with its GumRoad.md section
  4. Report — Slack + Notion

Lane 1 · Spec phase (the runner reads its own spec)

1 · Manual Trigger

The operator clicks Execute workflow in the n8n UI. No payload — config lives in the next node.

When else does it fire? If you wire a Schedule Trigger as a sibling, the workflow can run on a cron (e.g., daily) for continuous post-launch monitoring. Just connect the schedule node to step 2 alongside the manual trigger.

2 · Config: which product to QA

Code node. Sets the per-product config: - permalink — the Gumroad slug to look up (e.g., voice-automation-suite) - site_base + website_path — where the product page lives on meerkat-llc.com - expected_price_cents — the price the runner will assert against - required_root_files + required_subfolder_indexes — entry-point files derived from GumRoad.md § Buyer entry-point checklist - gumroad_md_url — where to read the canonical spec (default: file:///Users/.../GumRoad.md; override via $vars.GUMROAD_MD_URL if you serve the spec via HTTPS)

Adding a new product? Duplicate this block in the Code node or accept a permalink param via the Manual Trigger UI.

3 · Read GumRoad.md spec

HTTP Request, GET. Returns the raw markdown of GumRoad.md as a text body. Step 4 parses it.

Why? This workflow's whole reason for existing is to validate Gumroad products against the canonical checklist. If we hardcoded that checklist into the workflow, it would silently drift from the real spec. Reading GumRoad.md at runtime makes the spec the source of truth.

4 · Validate spec + extract canon

Code node. Three jobs: 1. Section sanity check — confirms GumRoad.md still has every expected section (Phase 3 setup, Buyer entry-point checklist, Common gotchas, etc.). If any are missing, that's spec drift and the runner flags it. 2. Cross-check the runner's config against the spec — every file in required_root_files must be mentioned somewhere in GumRoad.md. If you add a launcher file to the spec but forget to add it here (or vice versa), it fails. 3. Cross-check post-purchase URL paramssale_id, email, price, license_key are all expected to be documented in GumRoad.md.

Output: an array of spec_checks that gets merged into the final report. Each one is tagged with section: 'spec'.


Lane 2 · Live data (talk to Gumroad + the deployed site)

5 · Gumroad: list my products

HTTP Request, GET https://api.gumroad.com/v2/products. Bearer-token auth via the Gumroad credential. Returns every product in your account.

Why list, not get-by-ID? Gumroad's get-by-ID endpoint requires the product's internal GUID, which we don't have. Listing all products and filtering by permalink is the API-correct way.

6 · Pick matching product

Code node. Filters the list down to the one matching cfg.permalink. Throws a hard error if not found — the rest of the run is meaningless without it. The error message tells you which permalink couldn't be located so you can debug Gumroad-side.

7 · Probe: site product folder

HTTP Request, HEAD against https://meerkat-llc.com/voice-automation-suite/. Just confirms the deployed folder is reachable (status 200). Cheap pre-check before fetching the full HTML.

8 · Fetch: index.html source

HTTP Request, GET. Pulls the full HTML body of the product landing page. Step 11 greps it for the Stripe placeholder, Gumroad host, and permalink path to verify the Buy button wiring.

9 · Fan out HEAD probes

Code node that emits one item per required entry-point file: - 6 root files: index.html, START-HERE.html, the three OS launchers, the Meerkat logo - 8 subfolder indexes: docs/index.html, workflows/index.html, voice-fixtures/index.html, etc.

Total: 14 parallel HEAD probes queued for the next node.

10 · HEAD probe each entry-point

HTTP Request, HEAD. n8n runs all 14 in parallel. A 200 means the file ships and is reachable; a 404 means it's missing — which is exactly the failure mode that produced the file:// directory listing bug GumRoad.md documents.


Lane 3 · Validation (run every check, tag each with its section)

11 · Product checks

Code node. The big one. Runs ~12 distinct checks against the Gumroad product data (from step 6) and the site HTML (from step 8). Each check tagged with the GumRoad.md section it derives from:

Section tag Checks
Phase 3 setup Product published · Has uploaded file · Cover image set · Price > 0 · Price matches expected · Description ≥ 200 chars
Gotcha: Custom Receipt URL Custom Receipt URL is set · URL points at /voice-automation-suite/thank-you.html
Spec: license_key support Whether license keys are enabled (informational)
Phase 3 buy buttons Site reachable · No Stripe placeholder remains · Buy button host matches Gumroad · Buy button uses correct permalink

Output: a checks[] array, each entry {section, check, ok, detail}.

12 · Combine + summarize

Code node. Merges three sources into one report: - spec_checks from step 4 - product checks from step 11 - HEAD probe results from step 10

Then computes: - pass / fail counts - ready_to_launch: bool (fail === 0) - by_section roll-up — how many passed/failed in each GumRoad.md section - ran_at timestamp + spec_source URL — useful for the Notion audit log

13 · Pass or fail?

n8n Switch node. Routes on ready_to_launch. If true, goes to step 14 (Slack pass). If false, goes to step 15 (format failures), then step 16 (Slack fail).

Both branches eventually feed step 17 so every run gets logged to Notion regardless of outcome.


Lane 4 · Report (Slack + Notion)

14 · Slack: pass

Slack node. Posts a green-check message to the QA channel: "✅ Voice Automation Suite — pre-launch QA PASSED (24/24)". Includes the product name and a link.

Use a dedicated #meerkat-qa channel — the volume is low (one message per QA run) but you want it visually distinct from launch announcements.

15 · Format failure list (by section)

Code node. Runs only on the fail branch. Groups the failed checks by their GumRoad.md section so the Slack message is structured:

🚨 Voice Automation Suite — pre-launch QA FAILED (3/24 checks failed)

GumRoad.md § Gotcha: Custom Receipt URL
  • Custom Receipt URL set — Not set — silent failure

GumRoad.md § Buyer entry-point checklist
  • Root file: Open-Suite.command — HTTP 404
  • Subfolder index: voice-fixtures/ — HTTP 404

The grouping makes it obvious which section of GumRoad.md to consult to fix each issue.

16 · Slack: fail

Slack node. Posts the formatted failure body to the QA channel. The message tells you exactly which spec section to read for context.

17 · Notion: log run

Notion node. Appends a row to the QA log database with: - Product name + permalink - Spec source URL (so you can audit which version of GumRoad.md was used) - Result (PASS / FAIL) - Pass count + Fail count - Ran At timestamp - Full check detail as JSON (for forensic review weeks later)

Why log even on PASS? The run history shows when the product last passed QA. If a buyer reports a broken page two weeks after launch, you can cross-reference the QA log to confirm it was passing on launch day — and if subsequent runs caught the regression.


Total event sequence (happy path)

1. Manual Trigger
2. Config (which product)
3. Read GumRoad.md
4. Validate spec + canon         ─┐
                                   ├─→ 12. Combine + summarize
5. Gumroad list                    │       ↓
6. Pick matching product           │   13. Pass/fail?
7. Probe site                      │       ├─ pass → 14. Slack pass ─┐
8. Fetch index.html ────→ 11. ─────┘       └─ fail → 15. Format     │
9. Fan out HEAD                            │              ↓         │
10. HEAD each entry-point ─────────────────┘         16. Slack fail │
                                                         ↓          ↓
                                                     17. Notion: log run

Failure modes the workflow itself catches

If this fails… Probable cause Where to look
Step 3 returns empty / 404 GumRoad.md not at expected path Update gumroad_md_url in step 2 config
Step 4 reports "missing section" Spec drift — someone removed a section from GumRoad.md Restore the section or update the runner's expected list
Step 5 returns 401 Wrong / expired Gumroad token Settings → Advanced → Applications → regenerate
Step 6 throws "not found" Permalink mismatch Confirm cfg.permalink matches the Gumroad product's custom permalink exactly
Step 10 reports HTTP 404 on an entry-point Missing file on the deployed site, OR stale deploy.sh exclude Re-run ./deploy.sh after fixing the package
Step 11 reports "Buy button uses correct permalink: false" Stale homepage / package landing page Search-replace the placeholder Gumroad URL and re-deploy

Cost + latency


"Meerkat LLC" and the Professor Meerkat mascot are marks of Meerkat LLC.

© 2026 Meerkat LLC · meerkat-llc.com · support@meerkat-llc.com · built with care in Anna, Texas