openapi: 3.1.0
info:
title: BrewPage API
description: "Free instant hosting for HTML, Markdown, AI artifacts and files"
version: 1.51.1
servers:
- url: https://brewpage.app
description: Generated server url
tags:
- 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: KV
description: Key-Value store with up to 1000 keys per namespace
- name: Sites
description: Multi-file HTML site hosting via ZIP or folder upload
- 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: 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/kv/{ns}/{id}/{key}:
get:
tags:
- KV
summary: BrewPage 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: Access password via query param (alternative to X-Password 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: Key value
content:
'*/*':
schema:
$ref: "#/components/schemas/KvGetResponse"
"403":
description: Wrong password
content:
'*/*':
schema:
$ref: "#/components/schemas/KvGetResponse"
"404":
description: Store or key not found
content:
'*/*':
schema:
$ref: "#/components/schemas/KvGetResponse"
put:
tags:
- KV
summary: BrewPage 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
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/KvUpsertKeyRequest"
required: true
responses:
"200":
description: Key upserted
content:
'*/*':
schema:
$ref: "#/components/schemas/KvUpsertKeyResponse"
"403":
description: Missing or wrong owner token
content:
'*/*':
schema:
$ref: "#/components/schemas/KvUpsertKeyResponse"
"404":
description: Store not found or expired
content:
'*/*':
schema:
$ref: "#/components/schemas/KvUpsertKeyResponse"
"409":
description: Key limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/KvUpsertKeyResponse"
delete:
tags:
- KV
summary: BrewPage 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
"404":
description: Store or key not found
/api/json/{ns}/{id}:
get:
tags:
- JSON
summary: BrewPage 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: Access password via query param (alternative to X-Password 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: JSON content
content:
'*/*':
schema:
type: string
"403":
description: Wrong password
content:
'*/*':
schema:
type: string
"404":
description: Document not found or expired
content:
'*/*':
schema:
type: string
put:
tags:
- JSON
summary: BrewPage 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
requestBody:
content:
application/json:
schema:
type: string
required: true
responses:
"200":
description: Document updated
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonUpdateResponse"
"403":
description: Missing or wrong owner token
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonUpdateResponse"
"404":
description: Document not found or expired
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonUpdateResponse"
delete:
tags:
- JSON
summary: BrewPage 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
"404":
description: Document not found or expired
/api/html/{ns}/{id}:
get:
tags:
- HTML
summary: BrewPage Get HTML Page
description: Returns rendered HTML content; password-protected pages require X-Password header or ?p= query param
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: Access password via query param (alternative to X-Password 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: HTML content
content:
'*/*':
schema:
type: string
"403":
description: Wrong password
content:
'*/*':
schema:
type: string
"404":
description: Page not found or expired
content:
'*/*':
schema:
type: string
put:
tags:
- HTML
summary: BrewPage 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"
required: true
responses:
"200":
description: Page updated
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUpdateResponse"
"403":
description: Missing or wrong owner token
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUpdateResponse"
"404":
description: Page not found or expired
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUpdateResponse"
delete:
tags:
- HTML
summary: BrewPage 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
"404":
description: Page not found or expired
/api/sites:
post:
tags:
- Sites
summary: BrewPage 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: upload
parameters:
- name: files
in: query
description: Individual files (alternative to archive)
required: false
schema:
type: array
items:
type: string
format: binary
- name: paths
in: query
description: Relative paths for each file (must match files order)
required: false
schema:
type: array
items:
type: string
- name: ns
in: query
description: "Namespace. Default: public"
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: "Time to live in days (1-30, default 15). Site auto-deletes after expiry. Accepts '15', '15d' or '15 days'"
required: false
schema:
type: string
- 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
requestBody:
content:
application/json:
schema:
type: object
properties:
archive:
type: string
format: binary
description: ZIP archive containing site files
responses:
"201":
description: Site uploaded
content:
'*/*':
schema:
$ref: "#/components/schemas/SiteUploadResponse"
"400":
description: "Invalid request, no HTML files, or limits exceeded"
content:
'*/*':
schema:
$ref: "#/components/schemas/SiteUploadResponse"
"415":
description: Unsupported file type in archive
content:
'*/*':
schema:
$ref: "#/components/schemas/SiteUploadResponse"
"429":
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/SiteUploadResponse"
/api/reports:
post:
tags:
- Reports
summary: BrewPage Submit Abuse Report
description: Records a public report about a resource hosted on brewpage.app for moderator review
operationId: create
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:
'*/*':
schema:
$ref: "#/components/schemas/ReportResponse"
"400":
description: Invalid request parameters
content:
'*/*':
schema:
$ref: "#/components/schemas/ReportResponse"
/api/kv:
get:
tags:
- KV
summary: BrewPage 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
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:
'*/*':
schema:
type: array
items:
$ref: "#/components/schemas/KvStoreListResponse"
post:
tags:
- KV
summary: BrewPage 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. Pages in 'public' without password appear in gallery. Custom namespace is created automatically"
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: "Time to live in days (1-30, default 15). Store auto-deletes after expiry. Accepts '15', '15d' or '15 days'"
required: false
schema:
type: string
- name: X-Password
in: header
description: "Access password. Empty = public store visible in gallery. With password = hidden from gallery, viewers must enter password or pass ?p= in URL"
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
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/KvCreateStoreRequest"
required: true
responses:
"201":
description: Store created
content:
'*/*':
schema:
$ref: "#/components/schemas/KvCreateStoreResponse"
"400":
description: Invalid request parameters
content:
'*/*':
schema:
$ref: "#/components/schemas/KvCreateStoreResponse"
"429":
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/KvCreateStoreResponse"
/api/json:
get:
tags:
- JSON
summary: BrewPage List JSON Documents
description: Returns documents owned by the given token. Empty list without token
operationId: list
parameters:
- name: ns
in: query
description: Namespace
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:
'*/*':
schema:
type: array
items:
$ref: "#/components/schemas/JsonListResponse"
post:
tags:
- JSON
summary: BrewPage 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_1
parameters:
- name: ns
in: query
description: "Namespace. Default: public. Pages in 'public' without password appear in gallery. Custom namespace is created automatically"
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: "Time to live in days (1-30, default 15). Document auto-deletes after expiry. Accepts '15', '15d' or '15 days'"
required: false
schema:
type: string
- name: X-Password
in: header
description: "Access password. Empty = public document visible in gallery. With password = hidden from gallery, viewers must enter password or pass ?p= in URL"
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
requestBody:
content:
application/json:
schema:
type: string
required: true
responses:
"201":
description: Document created
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonCreateResponse"
"400":
description: Invalid JSON or request parameters
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonCreateResponse"
"429":
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/JsonCreateResponse"
/api/html:
post:
tags:
- HTML
summary: BrewPage 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_2
parameters:
- name: ns
in: query
description: "Namespace. Default: public. Pages in 'public' without password appear in gallery. Custom namespace is created automatically"
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: "Time to live in days (1-30, default 15). Page auto-deletes after expiry. Accepts '15', '15d' or '15 days'"
required: false
schema:
type: string
- 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 = public page visible in gallery. With password = hidden from gallery, viewers must enter password or pass ?p= in URL"
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
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/HtmlUploadRequest"
required: true
responses:
"201":
description: Page created
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUploadResponse"
"400":
description: Invalid request parameters
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUploadResponse"
"429":
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/HtmlUploadResponse"
/api/files:
get:
tags:
- Files
summary: BrewPage List Files
description: Returns files owned by the given token. Empty list without token
operationId: list_1
parameters:
- name: ns
in: query
description: Namespace
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:
'*/*':
schema:
type: array
items:
$ref: "#/components/schemas/FileListResponse"
post:
tags:
- Files
summary: BrewPage 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_1
parameters:
- name: ns
in: query
description: "Namespace. Default: public. Pages in 'public' without password appear in gallery. Custom namespace is created automatically"
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: "Time to live in days (1-30, default 15). File auto-deletes after expiry. Accepts '15', '15d' or '15 days'"
required: false
schema:
type: string
- name: X-Password
in: header
description: "Access password. Empty = public file visible in gallery. With password = hidden from gallery, viewers must enter password or pass ?p= in URL"
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
requestBody:
content:
application/json:
schema:
type: object
properties:
file:
type: string
format: binary
required:
- file
responses:
"201":
description: File uploaded
content:
'*/*':
schema:
$ref: "#/components/schemas/FileUploadResponse"
"400":
description: Invalid request or file too large
content:
'*/*':
schema:
$ref: "#/components/schemas/FileUploadResponse"
"415":
description: Unsupported file type
content:
'*/*':
schema:
$ref: "#/components/schemas/FileUploadResponse"
"429":
description: Rate limit exceeded
content:
'*/*':
schema:
$ref: "#/components/schemas/FileUploadResponse"
/{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: Access password (query alternative to X-Password header)
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
/{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: Access password (query alternative to X-Password header)
required: false
schema:
type: string
- name: dl
in: query
description: Force download as attachment
required: false
schema:
type: boolean
- name: X-Resolve
in: header
r
# --- truncated at 32 KB (67 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/brewpage/refs/heads/main/openapi/brewpage-openapi.yml