When you want a site off the internet, you ask your assistant to call unpublish_site. Visitors stop getting the site at once and see a 404. Nothing is deleted: every stored version stays, the database is untouched, and the site id is still yours. publish_deploy puts it back on the version that was live.
That is the decision. The rest of this post is why it is a tool of its own, what it costs to come back, and the two bugs we found while building it.
Every lever pointed one way
For a while the platform could put a site up and could put an older version up. Nothing let the person who owns a site stop serving it. The mechanism existed, and it had exactly one caller: a sign-in only the operator has.
So the only self-service answer to "take my shop down" was to deploy a page that says closed. That is a different act from stopping a site. The old page is still stored, still reachable to anyone who kept the URL, and still what a search engine has indexed. And it is a deploy, which is the last thing a customer in that moment wants to be doing.
The documents that asked for this feature also asked for a delete_site. We will not build one. What was missing was never deletion. It was the difference between deleting and stopping, which the terms already drew: your stored versions remain stored, and they simply stop being served.
Stopping is the same act for you and for us
There is one mechanism, with two callers, and the record it leaves says which one pressed it. The sequence is fixed:
- Read the live version first, because once the site is stopped nothing is running to ask.
- Take the site off the air.
- Forget the site's secret values, only after that succeeded.
- Record who did it and which version was live.
The order carries reasons. A record cleared in front of a failed withdrawal would take a serving site's own keys off its next deploy for nothing. And the "newest stored version" is the one version nobody meant to put back, which is why the live one is recorded.
There is no republish_site. Putting a site back is publish_deploy, which already publishes a stored version and already is how a rollback happens. A second tool doing the same job is exactly what makes a tool list expensive to change afterwards.
What does not survive, and who is told
Two things do not come back, and the tool's description says both before it is called, so an assistant can tell you first.
- Secret values lived on the running script, and the platform never held a copy. The reply lists them by name, and you set them again after the site is serving. Routes that read them fail until then.
- A site whose database was handed over, or set by hand, has its connection string only on the running script. Stopping it destroys the only copy, so that one case refuses unless the call passes
accept_credential_loss.
A custom domain keeps pointing at the platform and answers 404 while the site is off. The tool carries the destructive annotation. It deletes nothing, but it changes what strangers get to nothing, and a client that pauses before destructive calls should pause here.
Two bugs we found by building it
A takedown could be undone by its subject. If the operator stopped a site under the terms, without suspending the account, the owner could call publish_deploy and put it straight back. The gate now reads whether a site is off the air and who stopped it. A site this platform stopped refuses deploy_site and publish_deploy, and says that a person has to change it.
A stopped site with a secret could not be resumed. The secret values died with the script while the record went on saying they were set. The failure showed up only at the resume, looking like a deploy error. The record is now cleared when the script goes, and the names stay, waiting for a value.
Two smaller rules follow. Lifting a suspension restores only what the operator stopped, so a shop its owner closed on purpose is not reopened by someone else's act. And setting a secret on a stopped site is refused, because writing it republishes the script and would put the site back on the air as a side effect of pasting a key.
What is not decided
- A visitor to a stopped site is told it "has not been deployed", which is the answer for a missing script and is slightly wrong here. Telling the two apart needs a lookup on every request, and this decision does not change that.
- A real stop followed by a real republish of a site carrying a secret has not been recorded in production. The claim that the way back needs the values set again rests on the design, not on that run.
The rule, once
Stopping a site is not deleting it: visitors get a 404, every version and the database stay, and publish_deploy brings the site back. The tools and their limits are listed in the docs.