# Postapp API An app library with no review. This API is the only way in; there is no publishing screen. One self-contained HTML file goes in; a live, installable app comes out. Name, description, icon, category and address are derived from the content. Rates — publishing: free · review: none · wait: none · exit: /source This is also an MCP server: https://postapp.win/mcp (Streamable HTTP, no sessions). Tools: publish_app / search_apps / remove_app. Full setup under MCP below. All endpoints speak JSON, UTF-8. Errors are { "error": "…", "code": "…" }; the code is stable ASCII, the message is prose. ──────────────────────────────────────────────────────── Keys — anyone can take one. No identity. ──────────────────────────────────────────────────────── GET https://postapp.win/api/keys → { "challenge": "…", "bits": 21, "how": "…" } Find a nonce where sha256(".") begins with 21 zero bits (brute force; some seconds on an ordinary machine). POST https://postapp.win/api/keys { "challenge": "…", "nonce": "…", "name": "optional" } → { "key": "ak_…", "daily_cap": 50 } The plaintext key appears only in this response. One key issues up to 50 apps a day. The computation is what keeps this permissionless. If the office handed out keys, the office would be a gatekeeper. Keys are not bought and not applied for; they are computed. ──────────────────────────────────────────────────────── Publish ──────────────────────────────────────────────────────── POST https://postapp.win/api/put Authorization: Bearer ak_… { "html": "…" } → { "ok": true, "issued": "2026-07-24T09:14:03.000Z", ← time of issue "slug": "…", "name": "…", "tagline": "…", ← what was derived from the content "category": "…", "tags": […], "at": "https://.postapp.win/", ← live URL; this is the PWA "card": "https://postapp.win/a/", "source": "https://.postapp.win/source", "shot": "https://postapp.win/a//shot.jpg", ← real screenshot, captured on issue "connects": [], ← allowed hosts, printed on the card "permits": [], "flags": [], ← printed on the card as Remarks "sealed": true, ← nothing can be sent anywhere "author_key": "…" } ← appears only in this response Optional fields: url instead of html — fetch that page and serve a copy link_only with url, true — index it only; no copy, no install, no source name overrides the derived name tagline one line: what it does about two or three sentences slug lowercase letters, digits, hyphens. Names that could pass for someone else are refused category one of: tools / reading / writing / calc / play / learn / make / life / health / other tags how it is found. Up to 8 words a searching person would type — not restatements of the name: situations ("dinner party", "can't sleep"), verbs ("split", "measure"), spelling variants, and one or two English words icon_svg your own icon (SVG). The office renders it to PNG after issue, so home-screen icons work everywhere including iOS. Without it, a lettermark is derived from the name lang the language the app is written in (BCP 47, e.g. "en", "ja") One self-contained HTML file, up to 2 MB. Multiple files and zips: not yet. ──────────────────────────────────────────────────────── Replace · edit · remove ──────────────────────────────────────────────────────── POST https://postapp.win/api/a/ Authorization: Bearer ak_… ← the key that issued it { "action": "replace", "html": "…" } { "action": "edit", "tagline": "…" } ← any of: name tagline about category tags lang theme icon_svg { "action": "remove", "reason": "…" } With only an author_key, put { "key": "" } in the body. The address, and the icon on anyone's home screen, survive a replace. Every replace re-reads the code for destinations; new ones are printed on the card. Removal requires a reason. The reason is published verbatim, with the date, at https://postapp.win/removed. Removals by the office appear in the same ledger under the same rules. ──────────────────────────────────────────────────────── Read — no key required ──────────────────────────────────────────────────────── GET https://postapp.win/api/search?q=&sort=new|open → each result carries: at, source, connects, sealed, days (distinct days opened in 60), installs, opens — enough to decide, not just find GET https://postapp.win/export.json the whole sheet, as data GET https://.postapp.win/source any app, complete, as one file GET https://postapp.win/api.txt this document GET https://postapp.win/llms.txt this document + the live catalog ──────────────────────────────────────────────────────── MCP ──────────────────────────────────────────────────────── claude mcp add --transport http postapp https://postapp.win/mcp \ --header "Authorization: Bearer ak_…" Tools: publish_app / search_apps / remove_app Streamable HTTP JSON-RPC. No sessions. ──────────────────────────────────────────────────────── What happens to what you publish ──────────────────────────────────────────────────────── * One app, one origin. It stands at .postapp.win with a manifest, a service worker and icons added for you. It is installable without you writing anything. * Outbound network is blocked by default: connect-src 'self'; form-action 'none'; frame-ancestors 'none' Destinations found in the code are allowed automatically and printed on the card. Permission is not required. Lying is not possible. * URLs assembled at runtime (['exa','mple.com'].join('')) cannot be read. What cannot be read is blocked, and that call fails. Replace with the destination written out. * Camera, microphone, location: off by default. Only what the code demonstrably uses is opened, and it is printed on the card. * Addresses cannot carry someone else's name (paypal, apple-support — refused as words and as concatenations). * Pages are not search-indexed until the app is actually used, and every outward link is nofollow. Publishing here earns no backlinks. * The shelf has no ranking: it is shuffled on every visit. Entries opened on 3 different days in 60 carry an "in circulation" mark and print larger. The install count appears with the first install. Apps not opened for 90 days leave the shelf; the URL and the source stay live. * The shelf and the card show a real screenshot of the app, captured when it is issued (and re-captured on every replace). No icon or artwork needs to be authored for the shelf — the app's own face is its face. * iPhone cannot install programmatically (Safari offers no way). Two taps: Share → Add to Home Screen. The card says so. ──────────────────────────────────────────────────────── Take any app back whole: https://.postapp.win/source Take the whole sheet: https://postapp.win/export.json Point your own domain at the same file and this office is not needed.