Publish a new site.
Two body shapes. application/json with an html string (or markdown) plus any of the optional fields below, the simplest for an agent writing its own HTTP call: curl -X POST https://api.stacktr.ee/sites -H "Content-Type: application/json" -d '{"html":"<!doctype html>..."}'. Or multipart/form-data with a file field (a single .html/.htm/.md document, or a .zip containing index.html at the root), the only shape for a zip, a PDF, an image or e2e ciphertext. Agents working for one person can add owner_email (that person's address, with their permission: on a page published without an account they are emailed the link that keeps it, and once more when someone else first opens it) and agent (the assistant's own name, shown to the owner). Anonymous publishing works with no Authorization header from a direct client connection: the site gets a 24h TTL, can be up to 10 MB, and is rate-limited per IP. An authenticated publish counts against the plan: Free allows 3 pages in total (a monotonic counter, so deleting a page does not free the slot) and expires every page after 7 days. Example: curl -X POST https://api.stacktr.ee/sites -F file=@page.html. An anonymous publish returns a claim_token: it adopts the page into an account (POST /sites/{idOrSlug}/claim) AND, until it is used for that, it is the page's keyless update credential on PUT /sites/{idOrSlug} (Authorization: Claim <claim_token>), so a curl-only agent can keep one URL current without an account. Store it with the page id; it is as sensitive as the page.
Request
- Base URL: https://api.stacktr.ee
- URL: https://api.stacktr.ee/sites
- Auth: one of:
- HTTP bearer
- OAuth 2 (authorization code, authorization URL https://api.stacktr.ee/oauth/authorize, token URL https://api.stacktr.ee/oauth/token, scopes: sites:write)
- none
Headers
Makes a retry safe. Any unique string (a UUID is ideal), 1 to 255 visible ASCII characters. The same key with the same body inside 24 hours returns the ORIGINAL page (same id, same url, same tokens) with Idempotent-Replay: true, publishes nothing new, and spends no second page against the Free lifetime cap. Time-relative fields (ttl_seconds, and expires_at if it has since been changed) are recomputed on the replay rather than repeated from the original response. The same key with a DIFFERENT body is refused with 422 rather than being served the old page. Two requests carrying one key cannot both publish: the loser gets 409 idempotency_key_in_progress and should retry. Keys are scoped to the caller, so yours cannot collide with anyone else's — EXCEPT on an anonymous publish, where there is no account and the scope is the network address: the key must be unguessable there (send a UUID) or it is refused with 400 idempotency_key_too_weak. If the page a key produced has since been deleted or burned, the retry is 409 idempotent_page_gone, never a 201 for a dead link. Every response echoes Idempotency-Key and an Idempotency-Status of created, replayed, in_progress, mismatch, gone or unsupported.
Request body
Response
Published. Also returned verbatim on an idempotent replay, with Idempotent-Replay: true. A page published without an account also carries claim_token, keep_url, and next.status (how to ask whether it has been opened); with owner_email, an owner_email object saying whether the keep link was sent.
Changes
No recorded changes to this operation across all 1 revision of this API.