Your n8n Workflow Can Finally Branch on Whether the App Actually Opened
Every link tool's n8n node fires on a click. Zippy's fires on the outcome — the real native app opened, the tap died in a webview, or the hand-off broke. Here's the recipe that works today with stock n8n nodes, and the official nodes that are built but not yet published.


⚡ Zippy: a click is not an outcome. your automation deserves to know the difference.
Put a link tool in n8n and you get a node that can create a short link and, if you're lucky, a trigger that fires when someone clicks it.
Here's the problem with that trigger: a click is the last thing it knows. Whether the tap landed in the person's real app — where they're logged in, where their card is saved — or died in Instagram's in-app browser is exactly the information your workflow needed, and it's the information nobody exports.
Zippy exports it. That's the whole post.
Three outcomes, not one event
When a Zippy link is tapped, the redirect engine hands the destination to the operating system and then watches what the device did with it. One of three things comes back:
| Event | What actually happened |
|---|---|
app.opened | The destination app came to the foreground. The tap worked. |
app.browser | The tap got trapped in an in-app or mobile browser instead. |
app.broken | The deep hand-off failed outright. |
These are observations forwarded from a beacon on the device, not an inference from a user-agent string. Which means they're something a workflow can branch on and be right.
Branches that were previously impossible to write:
- If the last twenty taps on this link came back
app.browser, swap the destination and DM me. Something changed on the platform's side — better to find out from a workflow than from a flat sales week. - If a tap from a paid campaign returns
app.opened, write the row to the sheet. Your attribution stops counting taps that went nowhere. - If
app.brokenfires at all, page someone. That's a genuinely broken destination.
The competing version of that last one is "someone clicked" — which fires just as enthusiastically when the click accomplished nothing.
The version that works today (no install)
We built official n8n nodes. They're not on npm yet — more on that below. You don't need them, because Zippy's side is a plain HTTP API and n8n ships with everything else.
Make a link mid-workflow. One HTTP Request node:
- Method:
POST· URL:https://api.zipthe.link/v1/links - Auth: a Header Auth credential — name
Authorization, valueBearer zip_… - Body (JSON):
{"url": "{{ $json.destination }}", "tags": ["n8n"]}
Then read {{ $json.shortUrl }} in the next node. It comes back as the finished URL on
purpose — there's nothing to assemble out of a slug and a hostname.
Trigger on the outcome. A Webhook node, plus a Zippy webhook subscription:
- Copy the Webhook node's production URL. It has to be
https://and publicly reachable — Zippy refuses loopback and private-range callbacks, since registering a webhook means our API will be making requests to it. - Register it in Zippy (dashboard → Webhooks, or
POST /v1/webhooks) subscribed toapp.opened,app.browser,app.broken. - Verify the signature. That URL is public, so the
x-zippy-signatureHMAC is the only thing between your workflow and anyone who can send a POST. Enable Raw Body on the Webhook node and check the HMAC in a Code node before you trust anything. - Branch with an IF or Switch node on
event.
Each delivery arrives as { event, ts, data }, where data carries slug, platformKey,
sourceApp, country, city and device. sourceApp is the in-app browser the tap
escaped from; platformKey is where it was headed.
And note what this recipe isn't: a Schedule trigger polling a stats endpoint every five minutes. It's push. An idle workflow makes zero requests to us, and no event falls into the gap between two polls.
The official nodes: built, tested, not published
There are two of them, and the second is the reason for the first.
Zippy Trigger turns those three setup steps into a checkbox list. Activating the workflow
registers the subscription; deactivating removes it; editing the event list patches the
existing subscription rather than burning another of your five. It does the HMAC check
itself, in constant time, and answers an unsigned or tampered delivery 401 without starting
your workflow. It also flattens the envelope so an IF node reads one field — outcome is
opened, browser or broken.
Zippy is the action node: Link create/list/update/archive, the app-open analytics including per-variant A/B results, the link-in-bio page, and captured contacts — as dropdowns instead of URLs.
They are not installable yet. @zippy/n8n-nodes-zippy isn't on npm, so n8n's community
node dialog can't find it and npm install resolves to nothing. The package is built and
tested — 47 tests, one of which checks every operation's route against the API's own router
so a renamed endpoint fails our build instead of 404ing inside your automation — but
publishing is a decision that hasn't been made yet.
We're saying that plainly rather than shipping you an install command that doesn't work.
Nothing above needs the nodes, and when they publish, the workflows you build today keep
working: the nodes call the same /v1 routes your HTTP Request nodes call.
Read the numbers the way they're meant to be read
The analytics endpoints hand back sampled estimates, not an audit log. If you're going to automate on them:
- Branch on a trend or a whole-number rate. Never on a decimal difference between two runs.
appOpenRateisnull— never0— when nothing has been measured yet.nullmeans no data. A workflow that treats it as0will page you about silence.configured: falsemeans outcome collection isn't wired up upstream, and every number in that response is a placeholder.
Webhook deliveries are the exception: those are individual events, one per tap, not a sample.
One thing your automation can't do
Archive a link and it disappears from your workspace list and frees a slot against your plan cap. It keeps redirecting. There is no node, endpoint, or workflow that kills a Zippy link — links resolve forever, by design, and that includes the ones your automations made at 3am. If you need a link truly dead, the honest answer is that we can't do it.
FAQ
How do I use my link shortener in n8n?
With the stock HTTP Request node against https://api.zipthe.link/v1/links, using a
Header Auth credential that sends Bearer zip_…. The response's shortUrl is the finished
link, ready for the next node. An official community node exists but isn't published yet, so
the HTTP Request route is the one that works today.
Can n8n trigger when someone actually opens my app?
Yes — this is the one thing only Zippy can do. Point an n8n Webhook node at a Zippy
subscription for app.opened, app.browser and app.broken, and every tap arrives as an
event saying which of the three happened on the device. Other link tools' triggers fire on a
click, which can't distinguish "opened the real app" from "stranded in a webview".
Do I have to install a community node?
No. Everything in this post uses nodes that ship with n8n. The Zippy nodes are convenience — and they aren't on npm yet regardless.
Why did Zippy reject my n8n webhook URL?
It wasn't https:// on a publicly reachable host. Localhost and private-range addresses are
refused by design, because registering a webhook means our API will make requests to that
URL. Set WEBHOOK_URL to your public n8n address, or put n8n behind a tunnel.
What plan do I need for this?
Legend — that's the tier with API keys and webhook subscriptions. The opened/browser/ broken split inside analytics responses needs Hero or above; below that you get totals.
The actual point
Automation platforms are full of triggers that fire on something happened. The valuable ones fire on something worked.
Your link is usually the last step before the money — the DM, the checkout, the app install — and until now it was the step your automation was blindest about. It doesn't have to be.
Start free at app.zipthe.link — no card, and every link you make outlives the plan you made it on.
Related
- n8n docs — the HTTP Request recipe, the webhook setup, and every operation the nodes expose.
- Webhooks — the event stream underneath it, plus the HMAC verification recipe.
- The Zippy API — every
/v1route, keys, rate limits. - MCP server — the same API driven by conversation instead of a canvas.
- A/B split testing — per-variant app-open rates, readable from a workflow.
- Every link tool has an API. This one tells your automation whether the app opened.
- ManyChat links dying in the in-app browser?
- Changelog: The n8n nodes