Automating the publish step is easy on the first run. The decision appears on the second: mint a fresh URL, or replace the contents at the old one. One of those quietly rots every link you've already sent, and nothing warns you.
The first run is the easy one. The workflow generates the report, posts it somewhere, returns a URL, and you send it on.
The decision you didn't know you were making shows up on the second run.
Automating the last mile got much easier through 2026. Publishing endpoints, workflow nodes, and agent-facing tools arrived across this category, and the effect is real: a pipeline that renders an HTML artifact can now put it at an openable address in the same step that produced it, without anybody dragging a file anywhere.
What that removed was the screen. And the screen is where you used to see, without thinking about it, that publishing something is an action with a result — this file, at this address, from now on.
Run it on a schedule and the action repeats. The generated file is new every time. Whether the address is new every time is a separate question, and almost nothing asks it out loud, because on the first run there's no difference between the two behaviours.
Create a new page each run. Each execution produces a distinct artifact at a distinct URL. Monday's report and next Monday's report are separate objects that both keep existing.
Replace the contents at the same page. The address is fixed. Each run swaps what's behind it. There is one report, and it's current.
Both are legitimate, and which one is right is genuinely situational rather than one being the grown-up option.
If the workflow's output goes into a channel, an email, or a ticket fresh each run, new pages are the better shape. Each run's artifact is separable, addressable, and comparable — you can link to the March 4th run specifically, because it still exists at its own address. Nothing rots, because nobody was relying on an address to mean "the latest".
This is also the right shape when the runs are genuinely different artifacts rather than versions of one thing: per-client reports, per-build previews, one page per row of some input.
The moment the URL becomes something a person keeps rather than receives.
That transition is easy to miss because it doesn't involve you. You send a link once. The recipient bookmarks it, or pastes it into their own team's channel, or attaches it to a recurring calendar invite — all of which are the correct reaction to being handed a useful weekly report. Now the address means "the report" to somebody, and your workflow is minting a new one every Monday.
Nothing breaks. That's the problem. The saved URL keeps resolving to a real, well-formed, entirely plausible page that stopped being true weeks ago.
A dead link is self-correcting. Your recipient hits a 404, messages you, and you send the current address. Mildly irritating, fully resolved in one exchange.
A stale link has no such mechanism. There's nothing in the page to indicate it's the sixth-most-recent version. The numbers look like numbers. The person acts on them and, if you're unlucky, repeats them to somebody else.
This is the same property that makes the revise question the one to settle before a link ever goes out — and putting the publish step inside a scheduler multiplies it, because the divergence now happens on a timer whether or not anyone touched anything.
Less than it sounds. The workflow needs to remember one value.
The shape is:
Where you persist it depends on your platform — most automation tools have some form of static data or variable storage; otherwise a database row, or simply pasting the value into the workflow as a constant once the first run has happened, which is perfectly reasonable for a fixed weekly artifact.
The prerequisite is that the service you're publishing to has an update operation that accepts an existing page as the target. Some publishing endpoints are create-only, and that's a deliberate fit for their main use case — an agent or build loop producing throwaway previews, where keeping every one forever would be the wrong behaviour. It just means a create-only endpoint can't be the persistence layer for a link you've handed out, and you'd want to check that before designing around it.
miinideck's API takes a file from any HTTP step in your workflow and returns a private, unguessable, no-index URL — and a later run can replace the contents at that same address, so the link you gave someone in January is still the link in June and still shows this week's numbers.
A manual upload shows you the settings. An API call or workflow node doesn't, so it applies whatever that path defaults to — and those defaults often assume automated traffic means disposable traffic.
For a recurring report the failure is almost comic: a weekly artifact on a short window disappears shortly before it's next needed, so the link is dead exactly when someone finally goes looking. Worth setting explicitly in the call rather than inheriting.
On our side the relevant shape is that Free keeps one always-on link, with other links defaulting to a seven-day expiry; Solo ($4.99/mo) makes links permanent and adds the detailed access log, which for a recurring report is the thing that tells you whether anybody actually opens it. If nobody has opened the last six, that's worth knowing before you spend another quarter generating it.
That's usually the point — but if you need the history, get it from somewhere other than old URLs. Have the workflow write each generated file to storage before it publishes. Using abandoned links as your archive works right up until the moment you tidy up, and it makes "what did we send them in March" depend on a hosting account rather than a file.
If the page your workflow generates needs to accept form submissions, sign anybody in, or query a database when the visitor opens it, none of the above applies, because that's an application and not a document. Put it on a platform built to run server code — Vercel and Netlify both do this properly — and send that link.
The case covered here is the narrower one, which is also the more common one: the workflow renders something finished and self-contained, and it needs an address a human can open. A weekly summary, a rendered dashboard, a client-facing digest, a status page built from an API response. Those are documents that happen to be regenerated, and for documents the whole question is just whether the address is allowed to move.
Automating the publish step solves how do I get a link. Running it on a schedule creates a new question one step downstream — is it the same link? — and nothing in the tooling asks it, because on the run where you set it up there's no observable difference.
Answer it on run one. It costs a stored identifier. Answering it later costs an email explaining that the report they've been reading is out of date, and there's no way to know how long that was true.
For the related case where you want the link out before the work is finished rather than after, sending first and updating in place is the same mechanism pointed at a different problem — and what a view on a shared link actually tells you covers reading the access data a recurring report generates.
Client-side encryption tools turn your page into an encrypted file, so the protection and the artifact are the same object — every edit means re-running the tool and re-uploading. What that actually costs, the salt setting that decides whether your old share links survive, and when a hosted password is the better trade.
Running the studio out of one folder per client is a good structure for making the work. It stops at the point where the client has to open it — a private repo needs a GitHub account, and Pages built from one is public by default. What the handover step actually needs, and how to add it without breaking the folder.
A .json Lottie is not a page — hand it to a client and they get a wall of numbers. What it takes to turn one into something that opens in any browser, and why the answer is smaller than the tooling suggests.
miinideck turns a single HTML file into an unguessable link with optional password and expiry. Default-private, never indexed.