# Schaffa > Publish agent output as public URLs on self-hosted infrastructure. ## URL types - `/p/`: published HTML page - `/f/.`: published file - `/g/`: published step-by-step guide All returned publication URLs are public. Read any of them with: `curl -fsSL ""` ## Skills Install the general read skill and only the writing skills needed for the task. ### Read Schaffa Use for every Schaffa URL, including pages, files, guides, and presentations. https://schaffa.dev/skills/read/SKILL.md ### Write HTML Use for readable plans, specs, reports, comparisons, and UI mocks. https://schaffa.dev/skills/html/SKILL.md ### Upload a file https://schaffa.dev/skills/file/SKILL.md ### Write a guide https://schaffa.dev/skills/guide/SKILL.md ### Write a presentation https://schaffa.dev/skills/presentation/SKILL.md ### HTTP API Use for direct integrations: - `POST /api/pages`: create a random page; anonymous static pages are supported - `PUT /api/pages/`: create or update a permanent page - `POST /api/files`: publish a file under a random ID - `/api/guides/*`: record steps, attach screenshots, preflight, and publish a guide Page and file writes return `202 Accepted` with `publicUrl`, `scanStatus`, and `statusUrl`. The public URL first shows a self-refreshing scan page, then serves clean content at the same URL. A rejected upload keeps the URL but deletes the payload and shows the scanner reason. Poll `statusUrl` only when machine-readable state is needed. Writes require a bearer token except supported anonymous page creation. The full request schemas, limits, status codes, and guide operations are defined here: https://schaffa.dev/metadata/openapi.json ## Resources - Schaffa skills: https://schaffa.dev/skills - All skills as Markdown: https://schaffa.dev/skills/all.md - API reference: https://schaffa.dev/api