# I put a real n8n workflow behind a public button: 7 APIs, merge, LLM, live replay

**URL:** <https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544>\
**Category:** Built with n8n\
**Tags:** workflow-building, http-request, webhook, code, ai\
**Created:** [November 13, 2026, 3:06pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544 "2026-11-13T15:06:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![MikwebDesign2026](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/mikwebdesign2026/32/199589_2.png) [@MikwebDesign2026](https://community.n8n.io/u/MikwebDesign2026)\
**Post date:** [November 13, 2026, 3:06pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/1 "2026-11-13T15:06:02Z")

</div>

I wanted to show what workflow automation looks like without a sales demo, so I put a real n8n workflow behind a public button.

One click runs this on my self-hosted instance:

1. Webhook receives the request
2. Seven HTTP Request nodes call public APIs in parallel: ISS position, USGS earthquakes, Hacker News, Wikipedia, Open-Meteo, GitHub and my own status monitor
3. Merge + Code nodes normalize the responses
4. An LLM creates a two-sentence bulletin
5. A validation step rejects malformed output and uses a deterministic fallback
6. The result is posted back and the page replays the execution node by node

The source nodes use continue-on-fail, so one unavailable API does not kill the whole run. The public endpoint is rate-limited: one global run every three minutes, three per visitor per hour and 150 per day.

\*\*Live demo:\*\* [n8n live: start a real workflow with one click](https://daniele-michelin.com/en/n8n-live/)

\*\*Importable workflow JSON:\*\* [https://daniele-michelin.com/assets/n8n/internet-puls.json](https://daniele-michelin.com/assets/n8n/internet-puls.json)

I also documented the workflow and the failure-handling choices here: [n8n workflow of the week: 20 automations to rebuild](https://daniele-michelin.com/en/n8n-workflows/)

I built this and run it on my own server. Feedback on the error handling and the public-webhook guardrails is welcome.

---

<div class="post-metadata">

**Author:** ![sameday](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/sameday/32/195873_2.png) [@sameday](https://community.n8n.io/u/sameday)\
**Post date:** [November 14, 2026, 9:12pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/2 "2026-11-14T21:12:39Z")

</div>

I tried two synthetic inputs against the Code nodes in the downloadable workflow, without calling the live demo. An HTTP error from Wikipedia reached the fallback. A successful response with a valid article but no `content_urls` stopped `Daten bündeln` before the fallback: `Cannot read properties of undefined (reading 'desktop')`.

I’d keep the article’s title and views and make its link optional: `arts[0].content_urls?.desktop?.page ?? null`. One other check: `Antwort prüfen` accepts `{"de":1,"en":["x"],"it":{"text":"x"}}` because all three values are truthy. Check for non-empty strings (and the 240-character limit) before accepting the bulletin. Both inputs would make useful regression cases for the fallback.

---

<div class="post-metadata">

**Author:** ![MikwebDesign2026](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/mikwebdesign2026/32/199589_2.png) [@MikwebDesign2026](https://community.n8n.io/u/MikwebDesign2026)\
**Post date:** [November 14, 2026, 9:34pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/3 "2026-11-14T21:34:43Z")

</div>

Thanks for actually running synthetic inputs against the Code nodes, that is exactly the kind of review I was hoping for. Both findings were real, and I have fixed them in the live workflow and in the downloadable JSON:

Daten bündeln: a valid Wikipedia article without content\_urls threw Cannot read properties of undefined (reading ‘desktop’) and stopped the run before the fallback. The link is now optional: arts[0].content\_urls?.desktop?.page ?? null. The title and views are kept, and the page and the ingest endpoint already render a card without a link.  
Antwort prüfen: you are right that {“de”:1,“en”:[“x”],“it”:{“text”:“x”}} passed because all three values are truthy. It now accepts the model answer only if de, en and it are non-empty strings of at most 240 characters (trimmed). Anything else, numbers, arrays, objects, empty or too long text, goes to the deterministic fallback.  
I re-ran your two inputs (and a valid answer) through the new node code locally: the missing link gives url: null with the run continuing, the wrong types and the 241-character text both produce the fallback bulletin, and a valid answer passes unchanged. A live run on the server after the update also completed normally.

The lesson for me: “continue on fail” on the HTTP nodes only covers the transport. A 200 with an unexpected shape is a different failure and needs its own guard in the Code node, so I will check my other public workflows for the same gap. Your two inputs make good regression cases.

Updated JSON (same URL): [https://daniele-michelin.com/assets/n8n/internet-puls.json](https://daniele-michelin.com/assets/n8n/internet-puls.json)

If you see more edge cases, for example the USGS or GitHub responses with missing fields, I would be glad to hear them.

---

<div class="post-metadata">

**Author:** ![sameday](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/sameday/32/195873_2.png) [@sameday](https://community.n8n.io/u/sameday)\
**Post date:** [November 14, 2026, 9:56pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/4 "2026-11-14T21:56:04Z")

</div>

Thanks for shipping the fixes. They both pass against the updated download. I tried the two sources you mentioned, with synthetic inputs only:

- **USGS:** One feature missing `geometry` still stops `Daten bündeln`, even with a valid quake alongside it. A feature with `mag: null` reaches the model as `Mnull`. I’d filter for finite magnitudes and coordinate pairs before mapping. Keep the good rows and report a rejected count, so an incomplete feed isn’t mistaken for an empty one.
- **GitHub:** The truthiness check drops a valid `stargazers_count: 0` but accepts a string like `"123"`. A non-negative `Number.isSafeInteger` check preserves zero and rejects the string.

Here’s the [runnable replay](https://gist.github.com/epistemedeus/beb21762842a49b14a78714dd7db2c16): it checks your shipped fixes, reproduces the new cases, then runs them against a small candidate. It doesn’t call your webhook or the model.

---

<div class="post-metadata">

**Author:** ![Tonylw14](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/tonylw14/32/182940_2.png) [@Tonylw14](https://community.n8n.io/u/Tonylw14)\
**Post date:** [November 14, 2026, 11:00pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/5 "2026-11-14T23:00:05Z")

</div>

cool build. sameday also covered the data side pretty well so i looked at the model output instead.  
your prompt says keep numbers exact, don’t invent stuff, no jokes about disasters. but antwort prüfen only checks that it’s 3 strings under 240 chars, so none of that actually gets checked.

i rebuilt the antwort prüfen check from the JSON and ran some fake answers through it, no model calls. wrong quake magnitude, a made-up death count, a joke about the quake, and one following an injected HN title. all of them passed.  
a number check won’t fully fix it either. de/it write 4,3 not 4.3, and if the model just swaps real numbers around it still slips through.

does your ingest endpoint check anything on top of this?

---

<div class="post-metadata">

**Author:** ![sameday](https://dub1.discourse-cdn.com/n8n/user_avatar/community.n8n.io/sameday/32/195873_2.png) [@sameday](https://community.n8n.io/u/sameday)\
**Post date:** [November 14, 2026, 11:23pm UTC](https://community.n8n.io/t/i-put-a-real-n8n-workflow-behind-a-public-button-7-apis-merge-llm-live-replay/328544/6 "2026-11-14T23:23:36Z")

</div>

Good point about the same number appearing in different facts. I checked the workflow export, not the ingest service. One option is to have the model return only something like `{"facts":["quake","github"]}`, then render those facts from `data.sources` in the Code node. The model can pick which facts to include, but it never supplies the numbers or the prose.

I tried a synthetic 4.3 reading with a 9.6 model reply. The current node forwarded 9.6; the candidate rendered 4.3 in English, 4,3 in German and Italian, and kept a valid zero star count. Unknown or missing selections use the deterministic fallback.

[Runnable example and tests](https://gist.github.com/epistemedeus/8cb0d73c0906b4284f24330965967f73). No webhook or model calls.
