{
  "openapi": "3.0.3",
  "info": {"title": "Wary Press", "version": "0.0.0", "description": "Hosted pages. The public host comes from configuration. Free trial: account cap of 1 site. Per site: 1 page, 1 post, 5 MiB storage, 50 MiB monthly bandwidth, 2000 monthly requests. Upload is 64 KiB. 10 API calls per minute for the account. Regular is $4.99 per month: account cap of 1 site. Per site: 200 pages, 200 posts, 500 MiB storage, 20 GiB monthly bandwidth, 200000 monthly requests. Upload is 64 KiB. 120 API calls per minute for the account. Heavier is $9.99 per month: account cap of 4 sites. Per site: 200 pages, 200 posts, 500 MiB storage, 20 GiB monthly bandwidth, 200000 monthly requests. Upload is 64 KiB. 120 API calls per minute for the account. Global caps: 5 GiB storage, 600 requests per minute, 64 KiB JSON body. GOCMS_KILL_SWITCH=1 leaves GET /pricing and GET /healthz. Custom domains are not sold."},
  "servers": [{"url": "/"}],
  "paths": {
    "/": {"get": {"responses": {"200": {"description": "Customer home, or the product page when the host has no site"}}}},
    "/healthz": {"get": {"responses": {"200": {"description": "Process is up"}}}},
    "/pages/{slug}": {"get": {"parameters": [{"name": "slug", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Page"}}}},
    "/posts/{slug}": {"get": {"parameters": [{"name": "slug", "in": "path", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Post"}}}},
    "/comments": {"post": {"responses": {"501": {"description": "Comments are later"}}}},
    "/llms.txt": {"get": {"responses": {"200": {"description": "LLM notes"}}}},
    "/openapi.json": {"get": {"responses": {"200": {"description": "This document"}}}},
    "/api/pages": {"post": {"responses": {"201": {"description": "Create a draft page on the caller's site"}}}},
    "/api/pages/{slug}": {"put": {"responses": {"200": {"description": "Update a page on the caller's site"}}}},
    "/api/pages/{slug}/publish": {"post": {"responses": {"200": {"description": "Publish a page on the caller's site"}}}},
    "/api/posts": {"get": {"responses": {"200": {"description": "Published posts for the request host"}}}, "post": {"responses": {"201": {"description": "Create a draft post on the caller's site"}}}},
    "/api/posts/{slug}": {"put": {"responses": {"200": {"description": "Update a post on the caller's site"}}}},
    "/api/posts/{slug}/publish": {"post": {"responses": {"200": {"description": "Publish a post on the caller's site"}}}},
    "/api/checkout": {"post": {"responses": {"200": {"description": "Start sandbox checkout. The body is {\"tier\":\"regular\"} or {\"tier\":\"heavy\"}. Does not grant a plan."}, "400": {"description": "Missing or unknown tier"}, "501": {"description": "not_configured"}}}},
    "/api/checkout/confirm": {"post": {"responses": {"200": {"description": "Grant regular or heavy after a completed test-mode checkout"}}}},
    "/api/stripe/webhook": {"post": {"responses": {"200": {"description": "Apply a signed sandbox checkout.session.completed. A signed sandbox customer.subscription.deleted returns the owner to the free trial when the site count fits. A bad signature does not grant and does not clear. Other event types are ignored."}, "400": {"description": "Bad signature or a signed event that must not grant"}, "501": {"description": "not_configured"}}}},
    "/api/domain-requests": {"post": {"responses": {"201": {"description": "Record a custom-domain request. Does not attach a domain."}, "400": {"description": "Invalid request"}, "429": {"description": "rate_limited"}}}},
    "/api/signup": {"post": {"responses": {"201": {"description": "Create the account and the first site. JSON fields are email, password, display_name, and host. A single label is stored under GOCMS_PUBLIC_HOST when that host is set. Sets cookie gocms_session. The suite sign-in cookie is not this session."}}}},
    "/api/login": {"post": {"responses": {"200": {"description": "Sign in with email and password. Sets cookie gocms_session."}, "401": {"description": "unauthorized"}}}},
    "/api/keys": {"post": {"responses": {"201": {"description": "Return a gc_ key once. Requires cookie gocms_session from POST /api/signup or POST /api/login."}}}, "get": {"responses": {"200": {"description": "List key ids. Does not return the gc_ key."}}}},
    "/account": {"get": {"responses": {"200": {"description": "Browser requests with Accept text/html and no session get the account form (email, password, display name, site label). A session shows each site's current-month requests and bytes, the site cap, and the per-site caps. POST /account/key on that page shows a gc_ key once."}, "401": {"description": "unauthorized when the client did not ask for HTML and has no press session"}}}},
    "/account/key": {"post": {"responses": {"200": {"description": "Create a gc_ key and show it once on the account page. Requires cookie gocms_session."}}}},
    "/account/domain": {"get": {"responses": {"200": {"description": "Custom domains are not sold"}}}, "post": {"responses": {"403": {"description": "not_sold"}}}},
    "/mcp": {"post": {"responses": {"200": {"description": "JSON-RPC on the request host. Read tools are list_posts, get_post, search_posts, and get_site. Write tools on POST /mcp still require a gc_ key."}}}}
  }
}
