{"openapi":"3.1.0","info":{"title":"BrewPage API","description":"Free instant hosting for HTML, Markdown, JSON, key-value stores, files and sites. REST omission defaults to the public namespace; MCP omission creates an unlisted namespace. Unlisted URLs are accessible to anyone with the link; use a password for access restrictions. Retain returned links and ownership tokens. Public discovery requires eligibility; protected and non-public publications are excluded.","version":"1.107.2"},"servers":[{"url":"https://brewpage.app","description":"Generated server url"}],"tags":[{"name":"KV","description":"Key-Value store with up to 1000 keys per store"},{"name":"preview","description":"Per-content OpenGraph image (1200×630 PNG)"},{"name":"Short Links","description":"Short URL resolver for sharing"},{"name":"Owner Check","description":"Lightweight owner-token probe; never increments views or returns content"},{"name":"HTML","description":"HTML page hosting with markdown support"},{"name":"Sites","description":"Multi-file HTML site hosting via ZIP or folder upload"},{"name":"Owner Token","description":"Mints a fresh owner token client-side; stateless, persists nothing"},{"name":"SEO","description":"Search engine optimization endpoints"},{"name":"Gallery","description":"Browse public content from the 'public' namespace without password protection"},{"name":"JSON","description":"JSON document store with up to 10,000 docs per collection"},{"name":"Stats","description":"Platform-wide usage statistics"},{"name":"Namespace","description":"Fresh, collision-free namespace suggestions"},{"name":"Hosting Management","description":"Owner-only publication delivery settings"},{"name":"preview","description":"OpenGraph metadata for social bots"},{"name":"Files","description":"File hosting up to 5 MB per file, 1000 files per namespace"},{"name":"Reports","description":"Abuse reports for hosted content"}],"paths":{"/api/sites/{ns}/{id}":{"get":{"tags":["Sites"],"summary":"Get site info","description":"Returns site metadata and file list. Requires owner token","operationId":"getSiteInfo","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Site info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteInfoResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"put":{"tags":["Sites"],"summary":"Update site","description":"Replaces the multi-file site bundle (ZIP archive or individual files with paths). Requires the owner token returned at creation. Password is preserved as-is (not changed in this operation).","operationId":"republishSite","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,portfolio"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omission preserves the original expiry; updates do not renew it.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"entry","in":"query","description":"Entry file path override (default: auto-detect index.html)","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update","required":true,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","anyOf":[{"type":"object","required":["archive"]},{"type":"object","required":["files"]}],"properties":{"archive":{"type":"string","format":"binary","description":"ZIP archive; takes precedence over individual files."},"files":{"type":"array","items":{"type":"string","format":"binary"},"minItems":1},"paths":{"type":"array","description":"Optional paths aligned with files; omitted paths use original filenames.","items":{"type":"string"}}}}}},"required":true},"responses":{"200":{"description":"Site updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteUpdateResponse"}}}},"400":{"description":"Invalid request, empty bundle, limits exceeded, or bad TTL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Site not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Site is no longer available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Unsupported file type in archive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"delete":{"tags":["Sites"],"summary":"Delete site","description":"Permanently removes the site and all its files from storage","operationId":"deleteSite","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Site deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Site not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/kv/{ns}/{id}/{key}":{"get":{"tags":["KV"],"summary":"Get key value","description":"Returns the value and last update timestamp for a specific key","operationId":"getKey","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key value","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvGetResponse"}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Store or key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]},"put":{"tags":["KV"],"summary":"Upsert key","description":"Creates or updates a key in the store; max 1000 keys per store","operationId":"upsertKey","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvUpsertKeyRequest"}}},"required":true},"responses":{"200":{"description":"Key upserted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvUpsertKeyResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Store not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Key limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"delete":{"tags":["KV"],"summary":"Delete key","description":"Removes a single key from the store; deleting the last key does not remove the store","operationId":"deleteKey","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Key deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Store or key not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/json/{ns}/{id}":{"get":{"tags":["JSON"],"summary":"Get JSON document","description":"Returns raw JSON content with application/json content type","operationId":"getById","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"JSON content","content":{"application/json":{"schema":{}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Document not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]},"put":{"tags":["JSON"],"summary":"Update JSON document","description":"Replaces document content; requires the owner token returned at creation","operationId":"update","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","description":"NEW publications require the hosting operation for mode changes","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Document updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonUpdateResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Document not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"delete":{"tags":["JSON"],"summary":"Delete JSON document","description":"Permanently removes the document","operationId":"delete","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Document deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Document not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/html/{ns}/{id}":{"get":{"tags":["HTML"],"summary":"Get HTML page","description":"Returns rendered HTML content. Protected OLD pages accept X-Password or ?p=; NEW pages use X-Password or a reader access cookie. The owner token bypasses password protection when no password is supplied.","operationId":"getById_1","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"HTML content","content":{"text/html":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/csv":{"schema":{"type":"string"}},"text/tab-separated-values":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"string"}},"text/xml":{"schema":{"type":"string"}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Page not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]},"put":{"tags":["HTML"],"summary":"Update HTML page","description":"Replaces page content; requires the owner token returned at creation. Also accepts raw text/* (HTML, Markdown, YAML, XML, CSV, code) bodies — see /llms-full.txt.","operationId":"update_1","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","description":"Optional new content format on republish. Accepts 'html', 'markdown'/'md', or any code format (yaml, json, xml, csv, tsv, log, toml, ini, sql, sh, bat, env, javascript, typescript, tsx, jsx, css, properties, docker, txt). When omitted, the row's stored format is preserved. Body field 'format' on HtmlUpdateRequest takes precedence over the query param when both are present.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HtmlUpdateRequest"}},"text/html":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/csv":{"schema":{"type":"string"}},"text/yaml":{"schema":{"type":"string"}},"text/css":{"schema":{"type":"string"}},"text/javascript":{"schema":{"type":"string"}},"text/x-toml":{"schema":{"type":"string"}},"text/xml":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}},"application/yaml":{"schema":{"type":"string"}},"application/x-yaml":{"schema":{"type":"string"}},"application/javascript":{"schema":{"type":"string"}},"application/toml":{"schema":{"type":"string"}}},"required":true},"responses":{"200":{"description":"Page updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HtmlUpdateResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Page not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"delete":{"tags":["HTML"],"summary":"Delete HTML page","description":"Permanently removes page and frees the short URL","operationId":"delete_1","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Page deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Page not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/{type}/{ns}/{id}/access/revoke":{"post":{"tags":["Hosting Management"],"summary":"Revoke reader access to a new protected publication","operationId":"revokeReaderAccess","parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string","enum":["html","files","json","kv","sites"]}},{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessRevokeResponse"}}}},"400":{"description":"Reader access revocation requires a NEW protected publication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Publication unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/sites":{"post":{"tags":["Sites"],"summary":"Upload site","description":"Upload a multi-file HTML site as a ZIP archive or as individual files with paths. Returns a link to the published site","operationId":"uploadSite","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,portfolio"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omitted or blank uses 15 days.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"entry","in":"query","description":"Entry file path override (default: auto-detect index.html)","required":false,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Reuse existing owner token to group entities under one owner","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","anyOf":[{"type":"object","required":["archive"]},{"type":"object","required":["files"]}],"properties":{"archive":{"type":"string","format":"binary","description":"ZIP archive; takes precedence over individual files."},"files":{"type":"array","items":{"type":"string","format":"binary"},"minItems":1},"paths":{"type":"array","description":"Optional paths aligned with files; omitted paths use original filenames.","items":{"type":"string"}}}}}},"required":true},"responses":{"201":{"description":"Site uploaded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteUploadResponse"}}}},"400":{"description":"Invalid request, no HTML files, or limits exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Unsupported file type in archive","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/reports":{"post":{"tags":["Reports"],"summary":"Submit abuse report","description":"Records a public report about a resource hosted on brewpage.app for moderator review","operationId":"submitReport","parameters":[{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}},"required":true},"responses":{"201":{"description":"Report accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportResponse"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/kv":{"get":{"tags":["KV"],"summary":"List KV stores","description":"Returns all KV stores owned by the given token in the namespace. Returns empty list without token","operationId":"listStores","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to filter by ownership. Without token returns empty list","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Store list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/KvStoreListResponse"}}}}}},"security":[{},{"OwnerToken":[]}]},"post":{"tags":["KV"],"summary":"Create KV store","description":"Creates a new store with an initial key-value pair and returns a shareable link. Reuse existing owner token to group entities under one owner","operationId":"createStore","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,test"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omitted or blank uses 15 days.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"X-Password","in":"header","description":"Access password; protected stores are unlisted. NEW browser links use trusted unlock; programmatic reads use X-Password","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Reuse existing owner token to group entities under one owner. If omitted, a new token is generated","required":false,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","description":"Delivery mode for a new store: path or subdomain","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvCreateStoreRequest"}}},"required":true},"responses":{"201":{"description":"Store created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvCreateStoreResponse"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/json":{"get":{"tags":["JSON"],"summary":"List JSON documents","description":"Returns documents owned by the given token. Empty list without token","operationId":"list","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to filter by ownership. Without token returns empty list","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Document list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/JsonListResponse"}}}}}},"security":[{},{"OwnerToken":[]}]},"post":{"tags":["JSON"],"summary":"Create JSON document","description":"Stores any valid JSON and returns a shareable link. Reuse existing owner token to group entities under one owner","operationId":"create","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,test"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omitted or blank uses 15 days.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"X-Password","in":"header","description":"Access password; protected documents are unlisted. NEW browser links use trusted unlock; programmatic reads accept X-Password","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Reuse existing owner token to group entities under one owner. If omitted, a new token is generated","required":false,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","description":"Delivery mode: path or subdomain; non-public namespaces require subdomain","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{}}},"required":true},"responses":{"201":{"description":"Document created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonCreateResponse"}}}},"400":{"description":"Invalid JSON or request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/html":{"post":{"tags":["HTML"],"summary":"Create HTML page","description":"Stores HTML or markdown content and returns a shareable link. Reuse existing owner token to group entities under one owner. Also accepts raw text/* (HTML, Markdown, YAML, XML, CSV, code) and application/octet-stream bodies — see /llms-full.txt.","operationId":"create_1","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,test"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omitted or blank uses 15 days.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"format","in":"query","description":"Content format. 'html' (default) — stored verbatim. 'markdown' / 'md' — rendered to styled HTML via github-markdown-css. Code/text languages stored and served raw with format-specific MIME (text/csv, application/json, text/xml, text/plain) plus X-Content-Type-Options: nosniff: yaml, json, xml, csv, tsv, log, toml, ini, sql, sh, bat, env, javascript, typescript, tsx, jsx, css, properties, docker, txt","required":false,"schema":{"type":"string","default":"html"}},{"name":"X-Password","in":"header","description":"Access password. Empty means no password restriction; public discovery additionally requires eligibility. Protected pages are hidden from the gallery. OLD links accept ?p=; NEW access uses X-Password or a reader access cookie after password entry.","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Reuse existing owner token to group entities under one owner. If omitted, a new token is generated","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","description":"NEW delivery preference: path or subdomain. Non-public namespaces require subdomain; omission allows smart selection.","required":false,"schema":{"type":"string","enum":["path","subdomain"]}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HtmlUploadRequest"}},"text/html":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/markdown":{"schema":{"type":"string"}},"text/csv":{"schema":{"type":"string"}},"text/yaml":{"schema":{"type":"string"}},"text/css":{"schema":{"type":"string"}},"text/javascript":{"schema":{"type":"string"}},"text/x-toml":{"schema":{"type":"string"}},"text/xml":{"schema":{"type":"string"}},"application/xml":{"schema":{"type":"string"}},"application/yaml":{"schema":{"type":"string"}},"application/x-yaml":{"schema":{"type":"string"}},"application/javascript":{"schema":{"type":"string"}},"application/toml":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"required":true},"responses":{"201":{"description":"Page created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HtmlUploadResponse"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/files":{"get":{"tags":["Files"],"summary":"List files","description":"Returns files owned by the given token. Empty list without token","operationId":"list_1","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to filter by ownership. Without token returns empty list","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"File list","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FileListResponse"}}}}}},"security":[{},{"OwnerToken":[]}]},"post":{"tags":["Files"],"summary":"Upload file","description":"Stores a file via multipart upload and returns a download link. Only safe file types accepted. Reuse existing owner token to group entities under one owner","operationId":"upload","parameters":[{"name":"ns","in":"query","description":"Namespace (default public). Custom namespaces are unlisted, accessible to anyone with the URL. Public discovery additionally requires eligibility and no password.","required":false,"schema":{"type":"string","default":"public","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"tags","in":"query","description":"Comma-separated tags","required":false,"schema":{"type":"string"},"example":"demo,test"},{"name":"ttl","in":"query","description":"TTL in integer days (1-30); accepts 15, 15d, 15 day or 15 days, case-insensitive. Omitted or blank uses 15 days.","required":false,"schema":{"type":"string","pattern":"^\\s*(?:\\d+\\s*(?:[dD]|[dD][aA][yY][sS]?)?)?\\s*$"}},{"name":"X-Password","in":"header","description":"Access password. Empty = public file visible in gallery. With password = hidden from gallery; readers unlock the publication or use X-Password for API access","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Reuse existing owner token to group entities under one owner. If omitted, a new token is generated","required":false,"schema":{"type":"string"}},{"name":"X-Delivery-Mode","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}},"required":true},"responses":{"201":{"description":"File uploaded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadResponse"}}}},"400":{"description":"Invalid request or file too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"Unsupported file type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/{type}/{ns}/{id}/hosting":{"get":{"tags":["Hosting Management"],"summary":"Read owner-only publication delivery settings","operationId":"getHosting","parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string","enum":["html","files","json","kv","sites"]}},{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostingProjection"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Publication unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]},"patch":{"tags":["Hosting Management"],"summary":"Change delivery mode for a new public publication","operationId":"updateHosting","parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string","enum":["html","files","json","kv"]}},{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostingUpdateRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostingProjection"}}}},"400":{"description":"Invalid mode/version or locked delivery mode","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Publication unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Hosting version conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Hosting changes temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/{ns}/{id}":{"get":{"tags":["Short Links"],"operationId":"resolve","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password for protected resources","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"dl","in":"query","description":"Force download as attachment","required":false,"schema":{"type":"boolean"}},{"name":"raw","in":"query","description":"Bypass SPA: stream raw bytes directly (used by <video src>, <iframe src> for PDF, embed cases)","required":false,"schema":{"type":"boolean"}},{"name":"inline","in":"query","description":"Legacy site wrapper bypass; NEW publications retain stored hosting and protection policies","required":false,"schema":{"type":"boolean"}},{"name":"Range","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Resolve","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token; when supplied, response carries X-Is-Owner: true on match","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"Accept","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]}},"/{ns}/{id}/{sub}":{"get":{"tags":["Short Links"],"operationId":"resolveWithSub","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"sub","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password for protected resources","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"dl","in":"query","description":"Force download as attachment","required":false,"schema":{"type":"boolean"}},{"name":"Range","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Resolve","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token; when supplied, response carries X-Is-Owner: true on match","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]}},"/{key}.txt":{"get":{"tags":["SEO"],"summary":"IndexNow key verification","description":"Serves the IndexNow verification key file for search engine crawlers","operationId":"serveKeyFile","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key file content","content":{"text/plain":{"schema":{"type":"string"}}}},"404":{"description":"Unknown key"}}}},"/preview/{ns}/{id}.png":{"get":{"tags":["preview"],"summary":"Per-content OG image","description":"Returns 1200×630 PNG, cached, with ETag/If-None-Match support; falls back to /og-image.png?v=2 on any failure","operationId":"preview","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"PNG image bytes","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"302":{"description":"Fallback to static og-image.png (flag off, no source, generation error, oversized)"},"304":{"description":"Not modified (If-None-Match matched current ETag)"},"429":{"description":"Per-IP rate limit exceeded"}}}},"/preview-html/{ns}/{id}":{"get":{"tags":["preview"],"summary":"OpenGraph HTML stub","description":"Tiny HTML response with og:title/og:description/og:image meta tags for social-bot unfurls","operationId":"previewHtml","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"HTML stub with OG meta (or generic stub when resource is missing)","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/galleries":{"get":{"tags":["SEO"],"summary":"Flat HTML index of all current public publications","description":"Renders a minimal, bot-friendly anchor index of every current public site, page, image and video. Sorted by popularity (top 50 by views) then by recency. Underlying data is cached for ~2h.","operationId":"galleries","responses":{"200":{"description":"HTML index page","content":{"*/*":{"schema":{"type":"string"}}}}}}},"/api/{ns}/{id}/owner-check":{"get":{"tags":["Owner Check"],"summary":"Verify whether the supplied X-Owner-Token owns the resource","description":"Returns `{isOwner, type}`, plus `format` for an `html`-type resource. Constant-time BCrypt match. 404 when the resource does not exist (or has expired). 200 with `isOwner:false` when the X-Owner-Token header is absent.","operationId":"ownerCheck","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to verify (constant-time match)","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerCheckResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/stats":{"get":{"tags":["Stats"],"summary":"Get platform stats","description":"Returns today's and all-time creation/view counts with per-type breakdown. Optional 'tz' query param (IANA id) controls the boundary of 'today'; defaults to UTC.","operationId":"getStats","parameters":[{"name":"tz","in":"query","description":"IANA timezone id for the 'today' boundary. Defaults to UTC. Example: Europe/Lisbon","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Platform statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}},"/api/sitemap.xml":{"get":{"tags":["SEO"],"summary":"Dynamic XML sitemap","description":"Generates sitemap with static pages and all public gallery entries. Caddy should route /sitemap.xml to this endpoint","operationId":"sitemap","responses":{"200":{"description":"Sitemap XML","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/api/sitemap-index.xml":{"get":{"tags":["SEO"],"summary":"Top-level sitemap index","description":"sitemaps.org 0.9 sitemapindex pointing at /sitemap.xml and /sitemap-images.xml. Advertised in robots.txt so crawlers discover both children from a single URL. Caddy should route /sitemap-index.xml to this endpoint.","operationId":"sitemapIndex","responses":{"200":{"description":"Sitemap index XML","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/api/sitemap-images.xml":{"get":{"tags":["SEO"],"summary":"Google image-sitemap","description":"Per-content OG preview URLs (sitemap-image/1.1) for every qualifying public HTML/site publication. Reuses the publishable-items Caffeine cache slot shared with /sitemap.xml. Caddy should route /sitemap-images.xml to this endpoint.","operationId":"sitemapImages","responses":{"200":{"description":"Image sitemap XML","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/api/owner-token":{"get":{"tags":["Owner Token"],"summary":"Mint a fresh owner token and its derived owner id","description":"Returns `{token, ownerId}` where `token` is a 32-char base62 owner token and `ownerId` is its 64-char lowercase SHA-256 hex. Stateless: nothing is persisted. Send the returned token as `X-Owner-Token` when publishing to claim ownership.","operationId":"generateOwnerToken","responses":{"200":{"description":"Fresh owner token minted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerTokenResponse"}}}},"429":{"description":"Rate limit exceeded for this IP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/namespace/random":{"get":{"tags":["Namespace"],"summary":"Suggest a random namespace","description":"Returns a fresh `<word>-<word>-NN` namespace from the EFF Short Wordlist that does not collide with any existing resource. Pure read; no resource is allocated.","operationId":"randomNamespace","responses":{"200":{"description":"Namespace suggested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RandomNamespaceResponse"}}}},"503":{"description":"Namespace pool exhausted — retry budget hit consecutive collisions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/kv/{ns}/{id}":{"get":{"tags":["KV"],"summary":"List keys","description":"Returns all key names and total count for a store","operationId":"listKeys","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KvListKeysResponse"}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Store not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]},"delete":{"tags":["KV"],"summary":"Delete entire KV bucket (all keys under ns/id)","description":"Permanently removes all keys in the store; requires the owner token returned at creation","operationId":"deleteKvStore","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Bucket deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Store not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/html/{ns}/{id}/source":{"get":{"tags":["HTML"],"summary":"Get HTML page raw source","description":"Returns the raw user-submitted content (pre-render, pre-sanitize) plus metadata for republish. Owner-only — requires the owner token returned at creation.","operationId":"getHtmlSource","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for source access","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Raw source body and metadata","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Owner token missing (code: OWNER_TOKEN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Wrong owner token"},"404":{"description":"Missing publication: empty body. An expired or unavailable NEW delivery returns the JSON ErrorResponse envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/html/{ns}/{id}/settings":{"get":{"tags":["HTML"],"summary":"Get HTML page settings","description":"Returns republish-prefill settings (namespace, ttlDays, hasPassword, showTopBar, format, title, filename, createdAt, expiresAt) without the content body. Owner-only — requires the owner token returned at creation.","operationId":"getHtmlSettings","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for settings access","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Settings projection","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Owner token missing (code: OWNER_TOKEN_REQUIRED)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Wrong owner token"},"404":{"description":"Missing publication: empty body. An expired or unavailable NEW delivery returns the JSON ErrorResponse envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/gallery":{"get":{"tags":["Gallery"],"summary":"Browse gallery","description":"Lists public pages (public namespace, no password) with optional case-insensitive search by title/tags. When `mine=true` and `X-Owner-Token` is supplied, results are restricted to the caller's own public publications.","operationId":"getGallery","parameters":[{"name":"q","in":"query","description":"Case-insensitive search by title or tags","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","format":"int32","default":1},"example":1},{"name":"size","in":"query","description":"Items per page (max 100)","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":20},{"name":"sort","in":"query","description":"Sort order: 'date' (newest first, default) or 'views' (most viewed first)","required":false,"schema":{"type":"string","default":"date"},"example":"date"},{"name":"mine","in":"query","description":"When true, restrict results to the caller's owner_id (requires X-Owner-Token)","required":false,"schema":{"type":"boolean"}},{"name":"X-Owner-Token","in":"header","description":"Owner token; required when mine=true","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated gallery items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GalleryResponse"}}}}},"security":[{},{"OwnerToken":[]}]}},"/api/files/{ns}/{id}":{"get":{"tags":["Files"],"summary":"Download file","description":"Returns file inline for previewable types (images, PDF, media) or as attachment. Add ?dl=1 to force download.","operationId":"download","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"dl","in":"query","description":"Force download as attachment","required":false,"schema":{"type":"boolean"}},{"name":"Range","in":"header","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"File content","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"File not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]},"delete":{"tags":["Files"],"summary":"Delete file","description":"Permanently removes the file from storage","operationId":"delete_2","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token returned at creation. Required for update and delete","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"File deleted"},"403":{"description":"Missing or wrong owner token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"File not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"OwnerToken":[]}]}},"/api/sites/{ns}/{id}/files/{filePath}":{"get":{"tags":["Sites"],"summary":"Serve site file","description":"Serves an individual file from the site with correct content type","operationId":"serveSiteFile","parameters":[{"name":"ns","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,32}$"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Password","in":"header","description":"Access password via header","required":false,"schema":{"type":"string"}},{"name":"p","in":"query","description":"Legacy-only query password; ignored for NEW publications. Programmatic access uses X-Password or the owner token.","required":false,"schema":{"type":"string"}},{"name":"User-Agent","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Owner-Token","in":"header","description":"Owner token to bypass password protection when no password supplied","required":false,"schema":{"type":"string"}},{"name":"Range","in":"header","required":false,"schema":{"type":"string"}},{"name":"filePath","in":"path","description":"Relative file path, including nested directories; encode each segment and retain slash separators.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File content","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Wrong password","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Site or file not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{},{"OwnerToken":[]},{"Password":[]}]}}},"components":{"schemas":{"AbuseResult":{"type":"object","properties":{"code":{"type":"string","enum":["success","duplicate","warned","failed"]},"action":{"type":"string","enum":["created","created_missing_assets","updated","merged","created_warned","unavailable","rate_limited","rejected"]},"reason":{"type":"string"},"extras":{"type":"object","additionalProperties":{}}},"required":["action","code"]},"SiteUpdateResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric site ID"},"namespace":{"type":"string"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access (info, update, delete)"},"entryFile":{"type":"string","description":"Entry HTML file resolved from the upload (e.g. index.html)"},"fileCount":{"type":"integer","format":"int32"},"totalSizeBytes":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"type":"string"}},"result":{"description":"Publication outcome envelope: code + action + optional reason.","oneOf":[{"$ref":"#/components/schemas/AbuseResult"}]},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","entryFile","expiresAt","fileCount","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","requestedDeliveryMode","routingCohort","tags","totalSizeBytes"]},"KvUpsertKeyRequest":{"type":"object","properties":{"value":{"type":"string","description":"New value for the key (max 1 MB)"}},"required":["value"]},"KvUpsertKeyResponse":{"type":"object","properties":{"id":{"type":"string"},"namespace":{"type":"string"},"key":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing of this key"},"ownerLink":{"type":"string","description":"API URL for programmatic access"},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","hostingVersion","id","key","link","managementLink","modeLocked","namespace","ownerLink","requestedDeliveryMode","routingCohort","sizeBytes"]},"JsonUpdateResponse":{"type":"object","properties":{"id":{"type":"string"},"namespace":{"type":"string"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access"},"sizeBytes":{"type":"integer","format":"int64"},"updatedAt":{"type":"string","format":"date-time"},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","requestedDeliveryMode","routingCohort","sizeBytes","updatedAt"]},"HtmlUpdateRequest":{"type":"object","properties":{"content":{"type":"string","description":"New HTML content to replace existing page"},"format":{"type":["string","null"],"description":"Optional new content format on republish. Accepts 'html', 'markdown'/'md', or any code format (yaml, json, xml, csv, tsv, log, toml, ini, sql, sh, bat, env, javascript, typescript, tsx, jsx, css, properties, docker, txt). When omitted, the row's stored format is preserved. Takes precedence over the 'format' query param when both are present."}},"required":["content"]},"HtmlUpdateResponse":{"type":"object","description":"HTML update result. NEW publications include hosting metadata; OLD publications omit it.","properties":{"id":{"type":"string"},"namespace":{"type":"string"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access"},"expiresAt":{"type":"string","format":"date-time"},"sizeBytes":{"type":"integer","format":"int64"},"result":{"description":"Publication outcome envelope: code + action + optional reason.","oneOf":[{"$ref":"#/components/schemas/AbuseResult"}]},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"deliveryModeReason":{"type":"string","description":"Set as 'advisory:<codes>' when the updated page stays on a BrewPage link but uses browser features that may not work fully there. An update never changes the delivery mode. Codes are comma-separated in a fixed order: storage, cookies, history, downloads, top-navigation, media-capture, pointer-lock, embeds, fullscreen. Absent when nothing applies."},"deliveryNotice":{"type":"string","description":"Human-readable explanation of deliveryModeReason. Absent whenever deliveryModeReason is absent."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["expiresAt","id","link","namespace","ownerLink","sizeBytes"]},"AccessRevokeResponse":{"type":"object","properties":{"revoked":{"type":"boolean"}}},"SiteUploadResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric site ID"},"namespace":{"type":"string"},"entryFile":{"type":"string","description":"Entry HTML file resolved from the upload (e.g. index.html)"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access (info, delete)"},"fileCount":{"type":"integer","format":"int32"},"totalSizeBytes":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"type":"string"}},"ownerToken":{"type":"string","description":"Secret token required for info and delete operations. Store it safely -- cannot be recovered"},"result":{"description":"Publication result envelope (code + action + optional reason). Created/Merged/CreatedWarned dispatched per silent-merge dedup decision.","oneOf":[{"$ref":"#/components/schemas/AbuseResult"}]},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","entryFile","expiresAt","fileCount","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","ownerToken","requestedDeliveryMode","routingCohort","tags","totalSizeBytes"]},"ReportRequest":{"type":"object","properties":{"reportedUrl":{"type":"string","description":"Full URL of the reported resource on brewpage.app or brewdata.app"},"category":{"type":"string","description":"Abuse category","enum":["cannot_delete","spam","phishing","malware","copyright","harassment","illegal","other"]},"description":{"type":"string","description":"Reporter description (10..5000 chars)"},"reporterEmail":{"type":["string","null"],"description":"Optional reporter email for follow-up"},"resourceNamespace":{"type":["string","null"],"description":"Optional namespace of the reported resource (e.g. 'public'). When supplied with resourceId takes priority over URL parsing."},"resourceId":{"type":["string","null"],"description":"Optional 10-character short ID of the reported resource. When supplied with resourceNamespace takes priority over URL parsing."}}},"ReportResponse":{"type":"object","properties":{"reportId":{"type":"string","description":"Unique 10-character alphanumeric report ID"},"receivedAt":{"type":"string","format":"date-time","description":"Server timestamp when the report was accepted"}}},"KvCreateStoreRequest":{"type":"object","properties":{"key":{"type":"string","description":"Initial key name"},"value":{"type":"string","description":"Value for the initial key (max 1 MB)"}},"required":["key","value"]},"KvCreateStoreResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric store ID"},"namespace":{"type":"string"},"key":{"type":"string"},"sizeBytes":{"type":"integer","format":"int64"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing of the initial key"},"ownerLink":{"type":"string","description":"API URL for programmatic access (upsert/delete)"},"expiresAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"type":"string"}},"ownerToken":{"type":"string","description":"Secret token required for upsert and delete operations. Store it safely -- cannot be recovered"},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","expiresAt","hostingVersion","id","key","link","managementLink","modeLocked","namespace","ownerLink","ownerToken","requestedDeliveryMode","routingCohort","sizeBytes","tags"]},"JsonCreateResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric document ID"},"namespace":{"type":"string"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access (update/delete)"},"sizeBytes":{"type":"integer","format":"int64"},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"type":"string"}},"ownerToken":{"type":"string","description":"Secret token required for update and delete operations. Store it safely -- cannot be recovered"},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","createdAt","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","expiresAt","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","ownerToken","requestedDeliveryMode","routingCohort","sizeBytes","tags"]},"HtmlUploadRequest":{"type":"object","properties":{"content":{"type":"string","description":"HTML or markdown content to publish"},"filename":{"type":["string","null"],"description":"Optional original filename used as the tab title fallback and download basename. Trimmed; rejected if it contains path separators or control characters, length > 200, or bare name shorter than 4 chars"},"showTopBar":{"type":["boolean","null"],"description":"Per-content toggle for the frontend top toolbar. null = use global default (app.ui.show-top-bar-default)"}},"required":["content"]},"HtmlUploadResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric page ID"},"namespace":{"type":"string"},"link":{"type":"string","description":"Primary URL returned for browser viewing and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access (update/delete)"},"expiresAt":{"type":"string","format":"date-time"},"sizeBytes":{"type":"integer","format":"int64"},"tags":{"type":"array","items":{"type":"string"}},"ownerToken":{"type":"string","description":"Secret token required for update and delete operations. Store it safely -- cannot be recovered"},"result":{"description":"Publication outcome envelope: code (success|duplicate|warned|failed) + action (created|updated|merged|created_warned|...) + optional reason. Present on every POST/PUT response.","oneOf":[{"$ref":"#/components/schemas/AbuseResult"}]},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"deliveryModeReason":{"type":"string","description":"Why the delivery mode was chosen or flagged. 'auto:<codes>' -- the page was published in subdomain mode automatically because it uses browser features a BrewPage link does not provide. 'advisory:<codes>' -- the mode was kept, but those features may not work fully on a BrewPage link. Codes are comma-separated in a fixed order: storage, cookies, history, downloads, top-navigation, media-capture, pointer-lock, embeds, fullscreen. Absent when nothing applies."},"deliveryNotice":{"type":"string","description":"Human-readable explanation of deliveryModeReason, including how to change the delivery mode. Absent whenever deliveryModeReason is absent."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","expiresAt","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","ownerToken","requestedDeliveryMode","routingCohort","sizeBytes","tags"]},"FileUploadResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric file ID"},"namespace":{"type":"string"},"filename":{"type":"string","description":"Original filename as uploaded"},"contentType":{"type":"string","description":"Detected MIME type (e.g. image/png)"},"sizeBytes":{"type":"integer","format":"int64"},"link":{"type":"string","description":"Primary URL returned for browser download and sharing"},"ownerLink":{"type":"string","description":"API URL for programmatic access (delete)"},"expiresAt":{"type":"string","format":"date-time"},"tags":{"type":"array","items":{"type":"string"}},"ownerToken":{"type":"string","description":"Secret token required for delete operation. Store it safely -- cannot be recovered"},"visibilityNotice":{"type":"string","description":"Human-readable explanation of link access and conditional public-discovery eligibility. Unlisted links are not secret; password protection applies when configured. No guarantee of listing, ranking or search-engine indexing."},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","expiresAt","filename","hostingVersion","id","link","managementLink","modeLocked","namespace","ownerLink","ownerToken","requestedDeliveryMode","routingCohort","sizeBytes","tags"]},"HostingUpdateRequest":{"type":"object","properties":{"deliveryMode":{"type":"string","enum":["path","subdomain"]},"expectedVersion":{"type":"integer","format":"int64","maximum":9223372036854775807,"minimum":1}},"required":["deliveryMode","expectedVersion"]},"HostingProjection":{"type":"object","properties":{"link":{"type":"string"},"ownerLink":{"type":"string"},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"requestedDeliveryMode":{"type":["string","null"]},"effectiveDeliveryMode":{"type":["string","null"]},"deliveryModeMatched":{"type":["boolean","null"]},"namespace":{"type":"string"},"access":{"type":"string"},"modeLocked":{"type":"boolean"},"hostingVersion":{"type":["integer","null"],"format":"int64"}},"required":["access","deliveryMode","deliveryModeMatched","effectiveDeliveryMode","hostingVersion","link","managementLink","modeLocked","namespace","ownerLink","requestedDeliveryMode","routingCohort"]},"OwnerCheckResponse":{"type":"object","properties":{"type":{"type":"string","description":"Resource type (html, kv, json, file, site)"},"format":{"type":["string","null"],"description":"Only for an `html`-type resource: `html` for an HTML page, `other` for any other stored format (Markdown, code or text). Absent for every other type","enum":["html","other"]},"owner":{"type":"boolean"}}},"StatsResponse":{"type":"object","properties":{"createdToday":{"type":"integer","format":"int64","description":"Resources created in the last 24 hours"},"totalCreated":{"type":"integer","format":"int64","description":"All-time resource count"},"viewsToday":{"type":"integer","format":"int64","description":"Views in the last 24 hours"},"totalViews":{"type":"integer","format":"int64","description":"All-time view count"},"breakdown":{"type":"array","description":"Per-type breakdown (html, json, kv, file, site)","items":{"$ref":"#/components/schemas/TypeBreakdown"}},"createdTodayPublic":{"type":["integer","null"],"format":"int64","description":"Resources created today in the public namespace"},"createdTodayPrivate":{"type":["integer","null"],"format":"int64","description":"Resources created today in private namespaces"},"viewsTodayPublic":{"type":["integer","null"],"format":"int64","description":"Views today on resources in the public namespace"},"viewsTodayPrivate":{"type":["integer","null"],"format":"int64","description":"Views today on resources in private namespaces"},"totalCreatedPublic":{"type":["integer","null"],"format":"int64","description":"All-time resources created in the public namespace"},"totalCreatedPrivate":{"type":["integer","null"],"format":"int64","description":"All-time resources created in private namespaces"},"totalViewsPublic":{"type":["integer","null"],"format":"int64","description":"All-time views on resources in the public namespace"},"totalViewsPrivate":{"type":["integer","null"],"format":"int64","description":"All-time views on resources in private namespaces"},"deletedToday":{"type":["integer","null"],"format":"int64","description":"Resources deleted in the last 24 hours"},"deletedTodayPublic":{"type":["integer","null"],"format":"int64","description":"Resources deleted today in the public namespace"},"deletedTodayPrivate":{"type":["integer","null"],"format":"int64","description":"Resources deleted today in private namespaces"},"totalDeleted":{"type":["integer","null"],"format":"int64","description":"All-time deleted resource count"},"totalDeletedPublic":{"type":["integer","null"],"format":"int64","description":"All-time deleted resources in the public namespace"},"totalDeletedPrivate":{"type":["integer","null"],"format":"int64","description":"All-time deleted resources in private namespaces"}}},"TypeBreakdown":{"type":"object","properties":{"type":{"type":"string","description":"Resource type: html, json, kv, file, or site"},"today":{"type":"integer","format":"int64","description":"Created in the last 24 hours"},"total":{"type":"integer","format":"int64","description":"All-time count"},"todayPublic":{"type":["integer","null"],"format":"int64","description":"Created today in the public namespace"},"todayPrivate":{"type":["integer","null"],"format":"int64","description":"Created today in private namespaces"},"totalPublic":{"type":["integer","null"],"format":"int64","description":"All-time count in the public namespace"},"totalPrivate":{"type":["integer","null"],"format":"int64","description":"All-time count in private namespaces"},"todayDeleted":{"type":["integer","null"],"format":"int64","description":"Deleted in the last 24 hours"},"todayDeletedPublic":{"type":["integer","null"],"format":"int64","description":"Deleted today in the public namespace"},"todayDeletedPrivate":{"type":["integer","null"],"format":"int64","description":"Deleted today in private namespaces"},"totalDeleted":{"type":["integer","null"],"format":"int64","description":"All-time deleted count"},"totalDeletedPublic":{"type":["integer","null"],"format":"int64","description":"All-time deleted in the public namespace"},"totalDeletedPrivate":{"type":["integer","null"],"format":"int64","description":"All-time deleted in private namespaces"}}},"SiteFileInfo":{"type":"object","properties":{"path":{"type":"string","description":"Relative file path within the site"},"contentType":{"type":"string","description":"Detected MIME type"},"sizeBytes":{"type":"integer","format":"int64"}},"required":["path","sizeBytes"]},"SiteInfoResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric site ID"},"namespace":{"type":"string"},"entryFile":{"type":"string","description":"Entry HTML file resolved from the upload"},"fileCount":{"type":"integer","format":"int32"},"totalSizeBytes":{"type":"integer","format":"int64"},"files":{"type":"array","description":"List of all files in the site","items":{"$ref":"#/components/schemas/SiteFileInfo"}},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"views":{"type":"integer","format":"int64"},"tags":{"type":"array","items":{"type":"string"}}},"required":["createdAt","entryFile","expiresAt","fileCount","files","id","namespace","tags","totalSizeBytes","views"]},"OwnerTokenResponse":{"type":"object","properties":{"token":{"type":"string"},"ownerId":{"type":"string"}}},"RandomNamespaceResponse":{"type":"object","properties":{"namespace":{"type":"string"}}},"KvStoreListResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric store ID"},"keyCount":{"type":"integer","format":"int32","description":"Number of keys in the store"},"createdAt":{"type":"string","format":"date-time","description":"When the first key in the store was created"}},"required":["createdAt","id","keyCount"]},"KvListKeysResponse":{"type":"object","properties":{"keys":{"type":"array","description":"All key names in the store","items":{"type":"string"}},"count":{"type":"integer","format":"int32","description":"Total number of keys"},"expiresAt":{"type":"string","format":"date-time","description":"When the store expires"},"views":{"type":"integer","format":"int64","description":"Aggregated views across all keys in this store"}},"required":["count","expiresAt","keys","views"]},"KvGetResponse":{"type":"object","properties":{"value":{"type":"string"},"updatedAt":{"type":"string","format":"date-time","description":"When the value was last written or updated"},"expiresAt":{"type":"string","format":"date-time","description":"When the value expires"},"views":{"type":"integer","format":"int64","description":"Total number of reads for this key (post-increment)"}},"required":["expiresAt","updatedAt","value","views"]},"JsonListResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric document ID"},"content":{"type":"string"},"size":{"type":"integer","format":"int64"},"createdAt":{"type":"string","format":"date-time"}},"required":["content","createdAt","id","size"]},"GalleryItem":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","description":"Resource type: html, json, kv, file, or site"},"title":{"type":"string","description":"Display title derived from content or filename"},"createdAt":{"type":"string","format":"date-time"},"views":{"type":"integer","format":"int64","description":"Total view count"},"visibility":{"type":["string","null"],"description":"Per-item visibility classification — public on default responses; my_public/my_public_password/my_private on mine=true","enum":["public","my_public","my_public_password","my_private"]},"namespace":{"type":["string","null"],"description":"Namespace the item lives in — 'public' on default responses; mine=true returns the real namespace (e.g. 'public', 'secret-ns') so the frontend can build correct /{ns}/{id} links"},"link":{"type":["string","null"]},"managementLink":{"type":["string","null"]},"routingCohort":{"type":"string"},"deliveryMode":{"type":["string","null"]},"hostingVersion":{"type":["integer","null"],"format":"int64"}}},"GalleryResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/GalleryItem"}},"total":{"type":"integer","format":"int64","description":"Total number of matching items across all pages"},"page":{"type":"integer","format":"int32","description":"Current page number (1-based)"},"size":{"type":"integer","format":"int32","description":"Items per page"}}},"FileListResponse":{"type":"object","properties":{"id":{"type":"string","description":"Unique 10-character alphanumeric file ID"},"filename":{"type":"string","description":"Original filename as uploaded"},"contentType":{"type":"string","description":"Detected MIME type (e.g. image/png)"},"size":{"type":"integer","format":"int64"},"link":{"type":"string","description":"Public short URL for browser download"},"createdAt":{"type":"string","format":"date-time"}},"required":["createdAt","filename","id","link","size"]},"ErrorResponse":{"type":"object","properties":{"status":{"type":"integer","format":"int32"},"error":{"type":"string"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"supportedTypes":{"type":"array","items":{"type":"string"}},"retryAfterSeconds":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int32"},"result":{"oneOf":[{"$ref":"#/components/schemas/AbuseResult"}]},"code":{"type":"string"}},"required":["error","message","status","timestamp"]}},"securitySchemes":{"OwnerToken":{"type":"apiKey","name":"X-Owner-Token","in":"header"},"Password":{"type":"apiKey","name":"X-Password","in":"header"}}}}