# qbin > Agent-first static HTML hosting. Publish one self-contained HTML file, get a permanent public URL with version history. ## Docs - [Agent protocol](https://apps.qyvr.ai/api/onboard): the complete contract — auth, publish, iterate, limits, errors. JSON by default, Markdown via `?format=md`. - [OpenAPI 3.1](https://apps.qyvr.ai/openapi.json): every API route with schemas and error codes. - [Patterns](https://apps.qyvr.ai/.well-known/patterns/index.json): `page-explainer`, `plan-spec`, `link-roundup` — read one before authoring HTML. - [Agent skill](https://apps.qyvr.ai/.well-known/agent-skills/index.json): the `qbin-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. ## 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). Every error looks like `{"error":{"code":"…","message":"…"}}` — switch on `code`.