EvoHub DocsEvoHub Docs Sign in

Docs and Changelog API

Use with AI
View as MarkdownThis page as plain text, for pasting into an AI tool Open in ClaudeAsk Claude questions about this page Open in ChatGPTAsk ChatGPT questions about this page
Connect to Cursor / VS Code / ClaudeSearch and read these docs from your AI tool (MCP server)

MCP server URL

https://docs.evohub.io/mcp

Claude Code

claude mcp add --transport http evohub-docs https://docs.evohub.io/mcp

Claude (claude.ai and Claude Desktop): Settings → Connectors → Add custom connector, and paste the URL above.

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "evohub-docs": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://docs.evohub.io/mcp"
      ]
    }
  }
}

Cursor — ~/.cursor/mcp.json

{
  "mcpServers": {
    "evohub-docs": {
      "url": "https://docs.evohub.io/mcp"
    }
  }
}

VS Code — .vscode/mcp.json

{
  "servers": {
    "evohub-docs": {
      "type": "http",
      "url": "https://docs.evohub.io/mcp"
    }
  }
}

Scripts and CI jobs can do most of what the Docs and Changelog consoles do: create and configure sites, write and publish pages and entries, upload files, manage domains, read analytics and the activity log. A full API reference for these two products is not published yet. The endpoints on this page are stable and work with an API key today; this page lists them by task, with the scope each one needs.

Paths below are relative to https://evohub.io. Requests need an API key, sent as described in API overview. Answers use the same envelope as the rest of the API: {"data": ...} on success and an error object on failure. See Errors.

Scopes

Each endpoint needs one scope. Give a key only the ones its job needs.

To Docs Changelog
Read sites and everything on them: pages or entries, revisions, analytics, feedback, activity docs:site:read changelog:site:read
Create and configure sites: settings, domain, logo, access, versions or categories, redirects, GitHub repository, integrations docs:site:write changelog:site:write
Delete a site docs:site:delete changelog:site:delete
Write: pages and sections, or entries; files; imports; opening change requests or submitting for review docs:page:write changelog:entry:write
Put writing live: publish, unpublish, schedule docs:page:publish changelog:entry:publish

The activity log of a site, and of the organization, is read with the site read scope.

A key without the scope gets 403 FORBIDDEN, never 401. A key sees organization-wide sites and, for a personal key, your teams' sites; an organization key scoped to a team sees that team's. A site it cannot see answers 404, the same as one that does not exist. See API keys and scopes.

Docs

Sites

Method Path Scope What it does
GET /api/v1/docs/sites docs:site:read List the sites the key can see
GET /api/v1/docs/sites/overview docs:site:read The list's figures for every site at once
POST /api/v1/docs/sites docs:site:write Create a site
GET /api/v1/docs/templates docs:site:read List the site templates
POST /api/v1/docs/sites/from-template docs:site:write Create a site from a template
GET /api/v1/docs/starter.zip docs:site:read Download the starter project
GET /api/v1/docs/sites/{siteID} docs:site:read Read a site and its settings
PATCH /api/v1/docs/sites/{siteID} docs:site:write Change a site's settings; only the fields you send change
DELETE /api/v1/docs/sites/{siteID} docs:site:delete Delete a site with all its pages and files
POST /api/v1/docs/sites/{siteID}/publish docs:site:write Put the site online or take it offline: {"published": true}
POST /api/v1/docs/sites/{siteID}/preview docs:site:read Create a private preview link of the live site
POST /api/v1/docs/sites/{siteID}/logo docs:site:write Upload the logo
DELETE /api/v1/docs/sites/{siteID}/logo docs:site:write Remove the logo
POST /api/v1/docs/sites/{siteID}/logo/dark docs:site:write Upload the dark-mode logo
DELETE /api/v1/docs/sites/{siteID}/logo/dark docs:site:write Remove the dark-mode logo
GET /api/v1/docs/sites/{siteID}/export docs:site:read Download the whole site as a zip

Versions and languages

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/versions docs:site:read List the site's versions
POST /api/v1/docs/sites/{siteID}/versions docs:site:write Create a version
PATCH /api/v1/docs/versions/{versionID} docs:site:write Change a version
DELETE /api/v1/docs/versions/{versionID} docs:site:write Delete a version
GET /api/v1/docs/sites/{siteID}/translations docs:site:read How far each language's translation has come
GET /api/v1/docs/pages/{pageID}/translations docs:site:read List a page's translations
POST /api/v1/docs/pages/{pageID}/translations docs:page:write Start a translation of a page

Sections and pages

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/tree docs:site:read The navigation: sections and pages in order
PUT /api/v1/docs/sites/{siteID}/order docs:page:write Reorder the navigation, and move pages between sections
POST /api/v1/docs/sites/{siteID}/sections docs:page:write Create a section
PATCH /api/v1/docs/sections/{sectionID} docs:page:write Rename a section
DELETE /api/v1/docs/sections/{sectionID} docs:page:write Delete a section
POST /api/v1/docs/sites/{siteID}/pages docs:page:write Create a page; it starts as a draft
GET /api/v1/docs/pages/{pageID} docs:site:read Read a page: its draft and what is live
PATCH /api/v1/docs/pages/{pageID} docs:page:write Edit a page's draft
DELETE /api/v1/docs/pages/{pageID} docs:page:write Delete a page; a published one also needs docs:page:publish
POST /api/v1/docs/pages/{pageID}/git/resolve docs:page:write Settle a conflict between the page and its GitHub file

Publishing

Method Path Scope What it does
POST /api/v1/docs/pages/{pageID}/publish docs:page:publish Publish the page's draft
POST /api/v1/docs/pages/{pageID}/unpublish docs:page:publish Take the page off the live site

On a site that requires review, publishing goes through change requests and these answer 409 REVIEW_REQUIRED. Open a change request instead (below); a person approves and merges it.

Revisions

Method Path Scope What it does
GET /api/v1/docs/pages/{pageID}/revisions docs:site:read List a page's revisions, newest first
GET /api/v1/docs/pages/{pageID}/revisions/{revisionID} docs:site:read Read one revision
POST /api/v1/docs/pages/{pageID}/revisions/{revisionID}/restore docs:page:write Put a revision back into the draft
POST /api/v1/docs/pages/{pageID}/revisions/{revisionID}/rollback docs:page:write Make an earlier publish live again; also needs docs:page:publish, except on a site that requires review, where it opens a change request instead

Change requests

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/changes docs:site:read What is waiting to go live
GET /api/v1/docs/sites/{siteID}/change-requests docs:site:read List change requests
POST /api/v1/docs/sites/{siteID}/change-requests docs:page:write Open a change request
GET /api/v1/docs/change-requests/{crID} docs:site:read Read a change request
PATCH /api/v1/docs/change-requests/{crID} docs:page:write Change its title, description, items or reviewers
GET /api/v1/docs/change-requests/{crID}/diff docs:site:read What it changes, against the live site
POST /api/v1/docs/change-requests/{crID}/close docs:page:write Close it without merging
POST /api/v1/docs/change-requests/{crID}/reopen docs:page:write Reopen a closed one
POST /api/v1/docs/change-requests/{crID}/refresh docs:page:write Bring its items up to date with their drafts
GET /api/v1/docs/change-requests/{crID}/comments docs:site:read List its comments
POST /api/v1/docs/change-requests/{crID}/comments docs:page:write or docs:page:publish Comment on it
DELETE /api/v1/docs/comments/{commentID} docs:site:read Delete one of the key's own comments
POST /api/v1/docs/change-requests/{crID}/preview docs:page:write Create a preview link of the change request
DELETE /api/v1/docs/change-requests/{crID}/preview docs:page:write Withdraw its preview link

Snippets and API references

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/snippets docs:site:read List reusable snippets
POST /api/v1/docs/sites/{siteID}/snippets docs:page:write Create a snippet
GET /api/v1/docs/snippets/{snippetID} docs:site:read Read a snippet
PATCH /api/v1/docs/snippets/{snippetID} docs:page:write Edit a snippet's draft
DELETE /api/v1/docs/snippets/{snippetID} docs:page:write Delete a snippet
POST /api/v1/docs/snippets/{snippetID}/publish docs:page:publish Publish a snippet
POST /api/v1/docs/snippets/{snippetID}/unpublish docs:page:publish Unpublish a snippet
GET /api/v1/docs/sites/{siteID}/api-specs docs:site:read List API references
POST /api/v1/docs/sites/{siteID}/api-specs docs:page:write Add an API reference from an OpenAPI document
GET /api/v1/docs/api-specs/{specID} docs:site:read Read an API reference
PATCH /api/v1/docs/api-specs/{specID} docs:page:write Change an API reference's settings
DELETE /api/v1/docs/api-specs/{specID} docs:page:write Delete an API reference
GET /api/v1/docs/api-specs/{specID}/file docs:site:read Download its OpenAPI document
PUT /api/v1/docs/api-specs/{specID}/file docs:page:write Replace its OpenAPI document, for example from CI
POST /api/v1/docs/api-specs/{specID}/publish docs:page:publish Publish the API reference
POST /api/v1/docs/api-specs/{specID}/unpublish docs:page:publish Unpublish the API reference

Files and redirects

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/assets docs:site:read List uploaded files
POST /api/v1/docs/sites/{siteID}/assets docs:page:write Upload a file
DELETE /api/v1/docs/assets/{assetID} docs:page:write Delete a file
GET /api/v1/docs/sites/{siteID}/redirects docs:site:read List redirects
POST /api/v1/docs/sites/{siteID}/redirects docs:site:write Create a redirect
PATCH /api/v1/docs/redirects/{redirectID} docs:site:write Change a redirect
DELETE /api/v1/docs/redirects/{redirectID} docs:site:write Delete a redirect

Import and GitHub

Method Path Scope What it does
POST /api/v1/docs/imports docs:page:write Upload content from another tool and get a preview
GET /api/v1/docs/imports/{importID} docs:site:read Read an import and its preview
POST /api/v1/docs/imports/{importID}/commit docs:page:write Import it into a site
DELETE /api/v1/docs/imports/{importID} docs:page:write Discard an import
GET /api/v1/docs/git/config docs:site:read Whether GitHub sync is available
GET /api/v1/docs/sites/{siteID}/git docs:site:read The site's GitHub connection
GET /api/v1/docs/sites/{siteID}/git/repos docs:site:write Repositories the connection can use
GET /api/v1/docs/sites/{siteID}/git/branches docs:site:write Branches of a repository
PUT /api/v1/docs/sites/{siteID}/git docs:site:write Choose the repository, branch, folder and format
DELETE /api/v1/docs/sites/{siteID}/git docs:site:write Disconnect the site from GitHub
POST /api/v1/docs/sites/{siteID}/git/sync docs:page:write Sync from the repository now

Connecting a site to GitHub in the first place is done by a person in the console. See GitHub sync and Import and export.

Domain and access

Method Path Scope What it does
GET /api/v1/docs/sites/{siteID}/domain docs:site:read The custom domain and its verification state
PUT /api/v1/docs/sites/{siteID}/domain docs:site:write Set the custom domain
DELETE /api/v1/docs/sites/{siteID}/domain docs:site:write Remove the custom domain
GET /api/v1/docs/sites/{siteID}/access docs:site:read Who may read the published site
PUT /api/v1/docs/sites/{siteID}/access docs:site:write Change who may read it
PUT /api/v1/docs/sites/{siteID}/access/password docs:site:write Set the site's password
POST /api/v1/docs/sites/{siteID}/access/jwt/verify docs:site:write Check a reader token against the site's settings
POST /api/v1/docs/sites/{siteID}/access/sign-out docs:site:write Sign every reader out
GET /api/v1/docs/sites/{siteID}/access/read-tokens docs:site:write List read tokens
DELETE /api/v1/docs/sites/{siteID}/access/read-tokens/{tokenID} docs:site:write Revoke a read token

See Custom domain and Private docs.

Method Path Scope What it does
GET /api/v1/docs/analytics docs:site:read Analytics for every site the key can see
GET /api/v1/docs/sites/{siteID}/analytics docs:site:read A site's page views and readers
GET /api/v1/docs/sites/{siteID}/analytics/search docs:site:read What readers searched for
GET /api/v1/docs/sites/{siteID}/analytics/ai docs:site:read Visits from AI assistants and crawlers
GET /api/v1/docs/sites/{siteID}/analytics/gaps docs:site:read Searches that found nothing
GET /api/v1/docs/sites/{siteID}/analytics/export.csv docs:site:read Download analytics as CSV
GET /api/v1/docs/sites/{siteID}/feedback docs:site:read List readers' feedback
PATCH /api/v1/docs/feedback/{feedbackID} docs:page:write Resolve or reopen feedback
DELETE /api/v1/docs/feedback/{feedbackID} docs:page:write Delete feedback
GET /api/v1/docs/sites/{siteID}/health docs:site:read The live site's link report
POST /api/v1/docs/sites/{siteID}/health/check docs:page:write Check the links again now

Activity log

Method Path Scope What it does
GET /api/v1/docs/activity docs:site:read What happened across every site the key can see
GET /api/v1/docs/sites/{siteID}/activity docs:site:read What happened on one site

Changelog

Sites

Method Path Scope What it does
GET /api/v1/changelog/sites changelog:site:read List the changelogs the key can see
GET /api/v1/changelog/sites/overview changelog:site:read The list's figures for every changelog at once
POST /api/v1/changelog/sites changelog:site:write Create a changelog
GET /api/v1/changelog/sites/{siteID} changelog:site:read Read a changelog and its settings
PATCH /api/v1/changelog/sites/{siteID} changelog:site:write Change its settings; only the fields you send change
DELETE /api/v1/changelog/sites/{siteID} changelog:site:delete Delete a changelog with every entry on it
POST /api/v1/changelog/sites/{siteID}/publish changelog:site:write Put the changelog online or take it offline: {"published": true}
POST /api/v1/changelog/sites/{siteID}/preview changelog:site:read Create a private preview link of the live changelog
POST /api/v1/changelog/sites/{siteID}/logo changelog:site:write Upload the logo
DELETE /api/v1/changelog/sites/{siteID}/logo changelog:site:write Remove the logo
POST /api/v1/changelog/sites/{siteID}/logo/dark changelog:site:write Upload the dark-mode logo
DELETE /api/v1/changelog/sites/{siteID}/logo/dark changelog:site:write Remove the dark-mode logo

Categories

Method Path Scope What it does
GET /api/v1/changelog/sites/{siteID}/categories changelog:site:read List categories
POST /api/v1/changelog/sites/{siteID}/categories changelog:site:write Create a category
PUT /api/v1/changelog/sites/{siteID}/categories/order changelog:site:write Reorder categories
PATCH /api/v1/changelog/categories/{categoryID} changelog:site:write Change a category
DELETE /api/v1/changelog/categories/{categoryID} changelog:site:write Delete a category

Entries

Method Path Scope What it does
GET /api/v1/changelog/sites/{siteID}/entries changelog:site:read List entries; filter with status, category, tag and q
POST /api/v1/changelog/sites/{siteID}/entries changelog:entry:write Create an entry; it starts as a draft
GET /api/v1/changelog/entries/{entryID} changelog:site:read Read an entry with its review state
PATCH /api/v1/changelog/entries/{entryID} changelog:entry:write Edit an entry's draft
DELETE /api/v1/changelog/entries/{entryID} changelog:entry:write Delete an entry; a published one also needs changelog:entry:publish

Publishing

Method Path Scope What it does
POST /api/v1/changelog/entries/{entryID}/submit changelog:entry:write Submit the draft for review
POST /api/v1/changelog/entries/{entryID}/publish changelog:entry:publish Publish the draft now
POST /api/v1/changelog/entries/{entryID}/schedule changelog:entry:publish Publish at a later time: {"publish_at": "…"}
POST /api/v1/changelog/entries/{entryID}/unschedule changelog:entry:publish Cancel a scheduled publish
POST /api/v1/changelog/entries/{entryID}/unpublish changelog:entry:publish Take the entry off the changelog
POST /api/v1/changelog/entries/{entryID}/git/resolve changelog:entry:publish Settle a conflict between the entry and its GitHub file

On a changelog that requires review, publishing and scheduling need the approvals first and otherwise answer 409 REVIEW_REQUIRED. A key can submit an entry; a person approves it. See Writing entries.

Revisions and images

Method Path Scope What it does
GET /api/v1/changelog/entries/{entryID}/revisions changelog:site:read List an entry's revisions
GET /api/v1/changelog/entries/{entryID}/revisions/{revisionID} changelog:site:read Read one revision
POST /api/v1/changelog/entries/{entryID}/revisions/{revisionID}/restore changelog:entry:write Put a revision back into the draft
GET /api/v1/changelog/sites/{siteID}/assets changelog:site:read List uploaded images
POST /api/v1/changelog/sites/{siteID}/assets changelog:entry:write Upload an image
DELETE /api/v1/changelog/assets/{assetID} changelog:entry:write Delete an image

Subscribers

Method Path Scope What it does
GET /api/v1/changelog/sites/{siteID}/email changelog:site:read How email goes out to subscribers
GET /api/v1/changelog/sites/{siteID}/subscribers changelog:site:read List subscribers
GET /api/v1/changelog/sites/{siteID}/subscribers/export.csv changelog:site:write Download subscribers as CSV
DELETE /api/v1/changelog/subscribers/{subscriberID} changelog:site:write Remove a subscriber

Slack and webhooks

Method Path Scope What it does
GET /api/v1/changelog/chat-channels changelog:site:write Chat app channels an integration can post to
GET /api/v1/changelog/sites/{siteID}/webhooks changelog:site:write List integrations
POST /api/v1/changelog/sites/{siteID}/webhooks changelog:site:write Create an integration
PATCH /api/v1/changelog/webhooks/{webhookID} changelog:site:write Change an integration
DELETE /api/v1/changelog/webhooks/{webhookID} changelog:site:write Delete an integration
POST /api/v1/changelog/webhooks/{webhookID}/test changelog:site:write Send a test delivery
POST /api/v1/changelog/webhooks/{webhookID}/rotate-secret changelog:site:write Replace the signing secret
GET /api/v1/changelog/webhooks/{webhookID}/deliveries changelog:site:write Recent deliveries and their results

See Reaching readers.

GitHub

Method Path Scope What it does
GET /api/v1/changelog/git/config changelog:site:read Whether GitHub sync is available
GET /api/v1/changelog/sites/{siteID}/git changelog:site:read The changelog's GitHub connection
GET /api/v1/changelog/sites/{siteID}/git/repos changelog:site:write Repositories the connection can use
GET /api/v1/changelog/sites/{siteID}/git/branches changelog:site:write Branches of a repository
PUT /api/v1/changelog/sites/{siteID}/git changelog:site:write Choose the repository and branch
DELETE /api/v1/changelog/sites/{siteID}/git changelog:site:write Disconnect from GitHub
POST /api/v1/changelog/sites/{siteID}/git/sync changelog:entry:write Sync from the repository now
POST /api/v1/changelog/sites/{siteID}/imports/github changelog:entry:write Import GitHub releases as entries

Connecting a changelog to GitHub in the first place is done by a person in the console. See GitHub.

Domain and access

Method Path Scope What it does
GET /api/v1/changelog/sites/{siteID}/domain changelog:site:read The custom domain and its verification state
PUT /api/v1/changelog/sites/{siteID}/domain changelog:site:write Set the custom domain
DELETE /api/v1/changelog/sites/{siteID}/domain changelog:site:write Remove the custom domain
GET /api/v1/changelog/sites/{siteID}/access changelog:site:read Who may read the changelog
PUT /api/v1/changelog/sites/{siteID}/access changelog:site:write Change who may read it
PUT /api/v1/changelog/sites/{siteID}/access/password changelog:site:write Set the changelog's password
POST /api/v1/changelog/sites/{siteID}/access/sign-out changelog:site:write Sign every reader out

Analytics and feedback

Method Path Scope What it does
GET /api/v1/changelog/analytics changelog:site:read Analytics for every changelog the key can see
GET /api/v1/changelog/sites/{siteID}/analytics changelog:site:read A changelog's views and readers
GET /api/v1/changelog/sites/{siteID}/analytics/export.csv changelog:site:read Download analytics as CSV
GET /api/v1/changelog/sites/{siteID}/feedback changelog:site:read List readers' feedback
PATCH /api/v1/changelog/feedback/{feedbackID} changelog:site:write Resolve or reopen feedback
DELETE /api/v1/changelog/feedback/{feedbackID} changelog:site:write Delete feedback

Activity log

Method Path Scope What it does
GET /api/v1/changelog/activity changelog:site:read What happened across every changelog the key can see
GET /api/v1/changelog/sites/{siteID}/activity changelog:site:read What happened on one changelog

Create and publish a changelog entry

A release pipeline can write the entry and publish it in two calls. The key needs changelog:entry:write and changelog:entry:publish.

# 1. Create the entry (a draft)
curl https://evohub.io/api/v1/changelog/sites/$SITE_ID/entries \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Faster exports",
    "summary": "CSV exports now finish in seconds.",
    "body_md": "Exports of large projects used to take minutes. They now stream as they are built.",
    "version": "2.4.0",
    "category_ids": ["'"$CATEGORY_ID"'"],
    "tags": ["exports"]
  }'

# 2. Publish it, and tell subscribers and integrations
curl -X POST https://evohub.io/api/v1/changelog/entries/$ENTRY_ID/publish \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"notify": true}'

title is required; a blank slug is made from the title. The answer to the first call is the entry, with its id. notify is optional; leave it out to keep the entry's setting. To publish later instead, call /schedule with {"publish_at": "2026-12-01T09:00:00Z"}. Entry fields also include cover_image_url, pinned, author_name and date.

Update and publish a docs page

# 1. Edit the draft; only the fields you send change
curl -X PATCH https://evohub.io/api/v1/docs/pages/$PAGE_ID \
  -H "Authorization: Bearer $EVOHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -H 'If-Match: "7"' \
  -d '{"title": "Install the CLI", "body_md": "Run `brew install acme` and sign in."}'

# 2. Publish the draft
curl -X POST https://evohub.io/api/v1/docs/pages/$PAGE_ID/publish \
  -H "Authorization: Bearer $EVOHUB_API_KEY"

Every save answers with an ETag holding the page's version. Send it back as If-Match (or as version in the body) and a save made over someone else's newer edit is refused with 409 EDIT_CONFLICT, carrying the page as it now stands; leave both out to overwrite. A page's section is changed with PUT /api/v1/docs/sites/{siteID}/order, not on the page. To create a page, POST /api/v1/docs/sites/{siteID}/pages with title, and optionally slug, body_md and section_id; ?version= picks the docs version, and the default version is used without it.

On a site that requires review, step 2 answers 409 REVIEW_REQUIRED: open a change request for the page with POST /api/v1/docs/sites/{siteID}/change-requests and a title, and a person approves and merges it.

What is not part of the API

  • Reserved for a person. Approving, requesting changes on, merging and reverting docs change requests and approving changelog entries; connecting a docs site or a changelog to GitHub; and issuing private docs credentials (a new reader-token signing secret, a test token, a read token) are done by a person in the console. A key gets 403 PERSON_REQUIRED. See What a key can never do.
  • Public-site routes. The addresses under /api/v1/docs/public/ and /api/v1/changelog/public/ serve your published sites to their visitors. They are not part of the API, may change without notice, and do not take an API key.
  • Console-only helpers such as the console home, notifications and who-is-editing indicators are left out here.
Last updated Powered by