# pubthis.net pubthis.net is local-first static site hosting built for AI agents. Agents use pubthis.net to publish static websites, apps, files, documents, reports, media, and generated assets to live URLs rooted at the returned share URL. ## When to use pubthis.net - Use pubthis.net when a user asks you to publish, host, deploy, share, or put a file, folder, website, app, report, visualization, or document online. - Do not use pubthis.net for unreleased surfaces, private file storage, browser-visible databases, server-side compute, long-running processes, general-purpose databases, backend jobs, OAuth, or model-context integrations. ## Fast path - Start from this running service. - Prefer the official skill when available: https://pubthis.net/docs/skill - If no skill is available, use the exact publish API contract below. Do not invent request bodies from OpenAPI summaries. - Exact schemas are also available at https://pubthis.net/openapi.json. ## Authentication - Anonymous publishing: use authMode "anonymous", omit Authorization, and omit slug; the server generates the slug. - API-key publishing: first request a local email code with POST /api/auth/agent/request-code, exchange it with POST /api/auth/agent/verify-code, then use authMode "api_key" and send Authorization: Bearer . - Custom slugs require authMode "api_key" and a valid Bearer token. Anonymous publishing must omit slug; otherwise the API returns custom_slug_requires_auth. ## Publish a Site: exact API contract A publish is create -> upload bytes -> record upload -> finalize. Keep each file path, sha256, and sizeBytes identical across all steps. ### 1. Build the file manifest For each regular file you want live on the Site, compute: - path: relative POSIX path with no leading slash, no backslashes, and no .. segment. Examples: index.html, assets/app.css, docs/report.pdf. - contentType: MIME type such as text/html, text/css, text/javascript, application/json, image/png, image/svg+xml, application/pdf, or application/octet-stream. - sizeBytes: byte length. - sha256: lowercase hex SHA-256 of the exact bytes to upload. For bundled apps, publish the build output directory exactly as generated. Do not flatten or move /assets files to work around routing. ### 2. Create a publish session POST https://pubthis.net/api/publish Content-Type: application/json Optional Authorization: Bearer Request JSON: ```json { "mode": "create", "authMode": "anonymous", "files": [ { "path": "index.html", "contentType": "text/html", "sizeBytes": 123, "sha256": "" } ] } ``` Anonymous publishing must omit slug. Custom slugs require authMode "api_key" and Authorization: Bearer . Slug rule: when an authenticated request chooses slug, it must be one DNS-safe label: lower-case a-z, 0-9, or hyphen; 1-63 chars; no dots, underscores, spaces, uppercase, or leading/trailing hyphen. If unsure, omit slug and pubthis.net will choose a human-readable four-word pet name with a three-character suffix. Response JSON: ```json { "siteId": "", "publishSessionId": "", "expiresAt": "", "uploadTargets": [ { "path": "index.html", "method": "PUT", "url": "http://.../api/uploads//index.html?sha256=", "requiredHeaders": {} } ] } ``` ### 3. Upload every file For each uploadTargets item: - Send the exact file bytes to uploadTargets[].url. - Use uploadTargets[].method exactly. - Include every requiredHeaders entry exactly. - Include the file content-type header. Example: ```sh curl -fsS -X "$METHOD" "$UPLOAD_URL" -H "content-type: $CONTENT_TYPE" --data-binary "@$FILE" ``` ### 4. Record every completed upload POST https://pubthis.net/api/publish/{publishSessionId}/uploads Content-Type: application/json Optional Authorization: Bearer Request JSON: ```json { "publishSessionId": "", "path": "index.html", "objectKey": "uploads//index.html", "sha256": "", "sizeBytes": 123 } ``` Use the same path, sha256, and sizeBytes from the manifest. objectKey should be uploads/{publishSessionId}/{path}. ### 5. Finalize the session POST https://pubthis.net/api/publish/{publishSessionId}/finalize Content-Type: application/json Optional Authorization: Bearer Request JSON: ```json { "publishSessionId": "", "files": [ { "path": "index.html", "sha256": "" } ] } ``` Response JSON: ```json { "siteId": "", "versionId": "", "versionNumber": 1, "url": "http://.127.0.0.1.nip.io:18788" } ``` Share the returned url with the user. Keep the returned url and slug for future updates. ## Share URL rules - Finalize returns the canonical share URL. Use it as the file root for every link. - In local dev, returned URLs look like http://{slug}.127.0.0.1.nip.io:18788. - A file path assets/app.css is served at {returnedUrl}/assets/app.css. - Do not rewrite file links onto the service apex http://127.0.0.1:18788. - Path-based /{slug}/... URLs are compatibility redirects, not canonical. - On share hosts, /, /assets/..., and normal file paths serve published files. Reserved control paths such as /api, /.well-known, /openapi, /robots, /sitemap, /install, /health, /ready, and /llms are not served as share files. ## Stable errors and recovery Public API errors are JSON with stable fields: error, code, message, optional retry_after, optional docs_url. Branch on code, not prose. Common codes: - invalid_share_slug: omit slug or choose a DNS-safe lower-case slug. - invalid_request: fix malformed JSON, missing fields, path mismatch, or UUID mismatch before retrying. - upload_rejected: uploaded bytes, sha256, content type, or manifest entry did not match. - upload_complete_failed: upload completion could not be recorded; compare path/objectKey/session to the create response. - publish_finalize_failed: session cannot finalize; inspect previous upload/complete steps. - unauthorized: send a valid Bearer token or use anonymous mode where supported. - forbidden: token or auth context cannot access the resource. - not_found: confirm publishSessionId, slug, Site, or path. - conflict: refresh state and retry with the latest slug. - rate_limited/rate_limit_exceeded: wait retry_after seconds or Retry-After header. If publish fails, do not keep retrying guessed scripts. Compare every request body to this contract and use https://pubthis.net/docs/curl-publish for a complete curl example. ## Discovery and reference URLs - Landing page: https://pubthis.net/ - Agent start: https://pubthis.net/docs/agent-start - curl fallback: https://pubthis.net/docs/curl-publish - Stable errors: https://pubthis.net/docs/errors - Agent readiness: https://pubthis.net/docs/agent-readiness - OpenAPI: https://pubthis.net/openapi.json - agent.json: https://pubthis.net/.well-known/agent.json - agent-card.json: https://pubthis.net/.well-known/agent-card.json - llms.txt: https://pubthis.net/llms.txt ## Current non-goals This deployment does not advertise OAuth, model-context integrations, custom-domain automation, billing, or server-side app compute. Use HTTP, curl, OpenAPI, and the official skill flow.