Create and manage sites programmatically, from a script, CI, or an AI agent. Everything you can do in the web app, you can do over the API.
The API is a standard REST service. You authenticate with a short-lived Bearer JWT, which you obtain by exchanging an API key. A key acts as you: sites you create with it are owned by and visible to your account, exactly like a web upload.
First, generate an API key (shown once, so copy it). It looks like pagegoat_….
Exchange your API key for an access token at the identity server. The token is a JWT valid for ~1 hour; cache it and re-exchange when it expires.
curl -X POST https://auth.pagegoat.com/api/keys/token \
-H "Authorization: Bearer pagegoat_your_key_here"
# → { "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600 }Then call the API with that token in the Authorization header:
TOKEN=$(curl -s -X POST https://auth.pagegoat.com/api/keys/token \
-H "Authorization: Bearer pagegoat_your_key_here" | jq -r .access_token)
curl https://api.pagegoat.com/api/sites -H "Authorization: Bearer $TOKEN"Upload a single HTML file or a ZIP bundle (must contain an index.html) as multipart form data.
curl -X POST https://api.pagegoat.com/api/sites \
-H "Authorization: Bearer $TOKEN" \
-F "title=My site" \
-F "slug=my-site" \
-F "file=@./site.zip"
# → { "slug": "my-site", "currentVersion": 1, ... }# List your sites
curl https://api.pagegoat.com/api/sites -H "Authorization: Bearer $TOKEN"
# Re-upload a new version
curl -X PUT https://api.pagegoat.com/api/sites/my-site/content \
-H "Authorization: Bearer $TOKEN" -F "file=@./site.zip"
# Rename it, or move it to a different slug (the old URL stops working)
curl -X PATCH https://api.pagegoat.com/api/sites/my-site \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Q3 review","slug":"q3-review"}'
# Make it public
curl -X PUT https://api.pagegoat.com/api/sites/my-site/visibility \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"visibility":"public","publicRole":"viewer"}'
# Or put it behind a password instead
curl -X PUT https://api.pagegoat.com/api/sites/my-site/visibility \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"visibility":"password","publicRole":"viewer","password":"mR7k-qP2w-vT9x"}'
# Or ask every visitor for an email address first, confirmed by a 6-digit code.
# captureReverifyDays: 30 | 7 | 0 (0 = every visit). captureDomains: comma-separated,
# or "" for any domain. Requires CAPTURE_EMAILS on the deployment; a 400 names the switch.
curl -X PUT https://api.pagegoat.com/api/sites/my-site/visibility \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"visibility":"capture","publicRole":"viewer","captureOtp":true,
"captureReverifyDays":30,"captureDomains":"acme.com"}'
# Delete it
curl -X DELETE https://api.pagegoat.com/api/sites/my-site -H "Authorization: Bearer $TOKEN"The full, always-current contract is published as an OpenAPI 3 spec. Use it to explore endpoints interactively or to generate a typed client in any language.
openapi-generator or a ChatGPT custom action.Connect Pagegoat to an AI assistant and it can publish pages for you on request: “host this report and send me the link”. There is one URL to paste, and it works the same everywhere:
https://mcp.pagegoat.com/mcpAuthorization is OAuth: you approve once in your browser, and the assistant is issued its own scoped credential. No API key is ever typed into a chat, and no credential reaches the model, which is the reason to prefer this over the REST API above when you have the choice.
Claude.ai, ChatGPT, Gemini: add a custom connector in settings and paste that URL. (ChatGPT needs developer mode enabled.)
Claude Code:
claude mcp add --transport http pagegoat https://mcp.pagegoat.com/mcpCodex CLI / Gemini CLI: add it as a remote (streamable HTTP) MCP server pointing at the same URL.
Then just ask:
"Publish this report to Pagegoat and give me the link."The assistant calls create_site with the HTML and hands back the URL. Also available: update_site, list_sites, get_site, set_visibility, delete_site and get_account_status. Publishing needs a paid plan; on a free account the assistant is told so and given the upgrade link.