your plans shouldn't disappear with the chat.
POST once. Get a persistent URL.
It stays private until you share it. It stays up until you delete it or it passes the expiry you set.
$ curl plan.undeleted.sh/publish \ -H "Authorization: Bearer $PLAN_API_KEY" \ -H "X-Plan-Expires: 7d" \ --data-binary @plan.md { "id": "L7qx2Km9NvPd", "url": "https://plan.undeleted.sh/p/L7qx2Km9NvPd", "current_revision": 1, … }
import json, os, urllib.request req = urllib.request.Request( "https://plan.undeleted.sh/publish", data=open("plan.md", "rb").read(), headers={ "Authorization": "Bearer " + os.environ["PLAN_API_KEY"], "X-Plan-Expires": "7d", }, method="POST", ) print(json.load(urllib.request.urlopen(req))["url"])
import { readFile } from "node:fs/promises"; const res = await fetch("https://plan.undeleted.sh/publish", { method: "POST", headers: { Authorization: "Bearer " + process.env.PLAN_API_KEY, "X-Plan-Expires": "7d", }, body: await readFile("plan.md"), }); console.log(((await res.json()) as { url: string }).url);
what you get
nothing overwrites.
Every save is a new revision. You can open v2 after you ship v5.
share links expire.
A share link is signed and expires on a date you pick. Rotate the signing key and every old link stops working.
private until you share.
Plans start private. You turn on a public URL or a signed share link when you want one.
yours to keep.
It's markdown or HTML, not a proprietary format. Copy it, download it, take it with you.
examples.
A recipe for each kind of plan, with the request that publishes it.
markdown
Write it, publish it, get a link back.
See the recipe →markdown with images
Publish the plan, then upload a diagram or screenshot to it.
See the recipe →markdown with mermaid
Put a mermaid fence in the markdown. Readers see the drawn diagram, and you upload no image.
See the recipe →html
Publish a page as you wrote it, styles included.
See the recipe →html with images and styles
Upload the stylesheet and images next to the page instead of inlining them into one file.
See the recipe →