# qyvr > Agent-first static HTML hosting. Publish one self-contained HTML file, get a permanent public URL with version history. ## Docs - [Agent protocol](https://qyvr.ai/api/onboard): the complete contract — auth, publish, iterate, limits, errors. JSON by default, Markdown via `?format=md`. - [OpenAPI 3.1](https://qyvr.ai/openapi.json): every API route with schemas and error codes. - [Patterns](https://qyvr.ai/.well-known/patterns/index.json): `page-explainer`, `plan-spec`, `link-roundup` — read one before authoring HTML. - [Agent skill](https://qyvr.ai/.well-known/agent-skills/index.json): the `qyvr-publish` skill. ## How it works 1. `POST /api/auth/start` → open `verification_url`, sign in with GitHub once → poll `GET /api/auth/poll?token=…` until `verified`. The token (`hb_…`) is revealed exactly once. 2. `POST /api/drops` with `Authorization: Bearer hb_…` and `{"title": "…", "html": "…"}` → `201` with the Drop object; hand `url` to the human. 3. `PUT /api/drops/:slug` mints a new version (old ones at `?v=N`); `PATCH` edits title/description/metadata without one. ## Limits 2 MB per drop · 200 versions per drop · 500 drops per account · 60 writes/min/token · passcode gates (soft, not encryption) · owner-side metadata tags. 25 MB per file upload · 1 GB of files per account · one `.qyvr.ai` page per GitHub login. ## Serving `/p/:slug` is a sandboxed viewer (no storage APIs inside); `/p/:slug/raw` serves the HTML directly (storage works, origin shared across drops — namespace keys). The Drop's `url` is `https://.qyvr.ai/d/:slug` — the link to hand out. `https://.qyvr.ai/` is your public page (drops + files). Files upload via `POST /api/blobs?filename=` (raw bytes) and serve at `https://.qyvr.ai/b/:id` — images inline, everything else downloads. Every error looks like `{"error":{"code":"…","message":"…"}}` — switch on `code`.