{
  "slug": "api-endpoints",
  "title": "API Endpoints Reference",
  "description": "Complete reference of all 136 REST API endpoints in the CMS admin.",
  "category": "api-reference",
  "order": 1,
  "locale": "en",
  "translationGroup": "35e054ea-d805-46c3-9dcf-c497654b7728",
  "helpCardId": null,
  "content": "## Overview\n\nThe CMS admin exposes **136 API endpoints** across 4 categories. All endpoints under `/api/cms/`, `/api/admin/`, and `/api/media/` require authentication via session cookie or API key.\n\n## Admin API\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET, POST | `/api/admin/ai-config` |  |\n| GET, POST | `/api/admin/analytics` | GET /api/admin/analytics |\n| GET, POST | `/api/admin/backups` |  |\n| GET, POST, DELETE | `/api/admin/backups/:id` |  |\n| GET, POST | `/api/admin/deploy` |  |\n| GET | `/api/admin/deploy/can-deploy` |  |\n| POST | `/api/admin/email-test` |  |\n| POST | `/api/admin/github-service-token` | POST /api/admin/github-service-token |\n| GET, POST | `/api/admin/invitations` |  |\n| DELETE | `/api/admin/invitations/:id` |  |\n| POST | `/api/admin/invitations/accept` |  |\n| GET | `/api/admin/invitations/validate` |  |\n| GET, POST | `/api/admin/mcp-config` |  |\n| GET | `/api/admin/my-sites` |  |\n| GET, POST | `/api/admin/org-settings` |  |\n| GET | `/api/admin/probe-url` | GET /api/admin/probe-url?url=<encoded-url> |\n| GET, POST | `/api/admin/profile` |  |\n| GET | `/api/admin/scheduler-events` |  |\n| GET | `/api/admin/scheduler-stream` |  |\n| POST | `/api/admin/scheduler-test` |  |\n| GET | `/api/admin/seo` | GET /api/admin/seo |\n| GET | `/api/admin/seo/export` | GET /api/admin/seo/export?format=csv|json |\n| GET, POST | `/api/admin/seo/keywords` | GET /api/admin/seo/keywords |\n| POST | `/api/admin/seo/og-image` | POST /api/admin/seo/og-image |\n| POST | `/api/admin/seo/optimize-bulk` | POST /api/admin/seo/optimize-bulk |\n| GET, POST, PATCH | `/api/admin/site-config` |  |\n| GET | `/api/admin/site-health` |  |\n| POST | `/api/admin/translate-bulk` | POST /api/admin/translate-bulk |\n| GET, POST, PATCH | `/api/admin/user-state` |  |\n| GET | `/api/admin/users` |  |\n| PATCH, DELETE | `/api/admin/users/:id` |  |\n| GET | `/api/admin/users/available` | GET /api/admin/users/available |\n| POST | `/api/mcp/admin/message` |  |\n\n## Authentication\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `/api/auth/github` | GET /api/auth/github — Redirect to GitHub OAuth authorize page. |\n| GET | `/api/auth/github/callback` | GET /api/auth/github/callback — Exchange OAuth code for access token. |\n| POST | `/api/auth/login` |  |\n| POST | `/api/auth/logout` |  |\n| GET | `/api/auth/me` |  |\n| GET, POST | `/api/auth/setup` |  |\n\n## Content API\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET, POST | `/api/check-links` | POST /api/check-links |\n| POST | `/api/check-links/apply-fix` |  |\n| POST | `/api/check-links/fix` |  |\n| GET | `/api/check-links/last` |  |\n| GET, POST | `/api/cms/:collection` |  |\n| GET, POST, PATCH, DELETE | `/api/cms/:collection/:slug` |  |\n| GET | `/api/cms/:collection/:slug/revisions` |  |\n| POST | `/api/cms/:collection/:slug/revisions/:index` | POST /api/cms/{collection}/{slug}/revisions/{index}/restore |\n| POST | `/api/cms/:collection/:slug/translate` |  |\n| GET, POST | `/api/cms/agents` |  |\n| GET, PUT, DELETE | `/api/cms/agents/:id` |  |\n| POST | `/api/cms/agents/:id/clone` |  |\n| POST | `/api/cms/agents/:id/run` |  |\n| POST | `/api/cms/agents/create-from-description` |  |\n| POST | `/api/cms/agents/generate-prompt` |  |\n| POST | `/api/cms/ai/chat` |  |\n| POST | `/api/cms/ai/generate` |  |\n| POST | `/api/cms/ai/htmldoc` |  |\n| GET, PUT | `/api/cms/ai/prompts` |  |\n| POST | `/api/cms/ai/proofread` |  |\n| POST | `/api/cms/ai/rewrite` |  |\n| GET, POST | `/api/cms/brand-voice` |  |\n| POST | `/api/cms/brand-voice/chat` |  |\n| POST | `/api/cms/brand-voice/translate` |  |\n| PATCH | `/api/cms/brand-voice/versions/:id` |  |\n| POST | `/api/cms/chat` |  |\n| GET, POST | `/api/cms/chat/conversations` |  |\n| GET, DELETE | `/api/cms/chat/conversations/:id` |  |\n| GET | `/api/cms/chat/export` |  |\n| POST | `/api/cms/chat/import` |  |\n| GET, POST | `/api/cms/chat/memory` |  |\n| PATCH, DELETE | `/api/cms/chat/memory/:id` |  |\n| GET | `/api/cms/chat/memory/export` |  |\n| POST | `/api/cms/chat/memory/extract` |  |\n| POST | `/api/cms/chat/memory/import` |  |\n| GET | `/api/cms/chat/memory/search` |  |\n| GET | `/api/cms/collections` |  |\n| GET | `/api/cms/collections/:name/schema` |  |\n| GET, POST | `/api/cms/command` |  |\n| POST | `/api/cms/command/sync` |  |\n| GET | `/api/cms/curation` |  |\n| GET, PATCH | `/api/cms/curation/:id` |  |\n| POST | `/api/cms/curation/:id/approve` |  |\n| POST | `/api/cms/curation/:id/reject` |  |\n| GET, POST | `/api/cms/folder-picker` | POST /api/cms/folder-picker |\n| GET | `/api/cms/heartbeat` | GET /api/cms/heartbeat |\n| GET, POST, PUT, DELETE | `/api/cms/mcp-servers` |  |\n| GET, POST, PUT, DELETE | `/api/cms/registry` |  |\n| POST | `/api/cms/registry/import` | POST /api/cms/registry/import |\n| POST | `/api/cms/registry/move-site` |  |\n| POST | `/api/cms/registry/rename` |  |\n| GET | `/api/cms/registry/stats` |  |\n| POST | `/api/cms/registry/validate` | POST /api/cms/registry/validate |\n| GET, POST | `/api/cms/revalidation` | GET /api/cms/revalidation — get revalidation settings + recent log for active site |\n| GET | `/api/cms/scheduled` |  |\n| GET | `/api/cms/scheduled/calendar.ics` | GET /api/cms/scheduled/calendar.ics?token=<hmac>&org=<orgId>&site=<siteId> |\n| GET | `/api/cms/schema-drift` | GET /api/cms/schema-drift |\n| POST | `/api/cms/schema-drift/fix` | POST /api/cms/schema-drift/fix |\n| POST | `/api/extract-text` | POST /api/extract-text |\n| GET, POST, DELETE | `/api/github` | GET /api/github?action=status|orgs|repos&org=... |\n| GET, POST | `/api/interactives` |  |\n| GET, PUT, DELETE | `/api/interactives/:id` |  |\n| GET | `/api/interactives/:id/preview` |  |\n| POST | `/api/interactives/:id/translate` | POST /api/interactives/[id]/translate |\n| GET | `/api/internal-links` | GET /api/internal-links?q=query |\n| GET | `/api/mcp` |  |\n| GET | `/api/mcp/admin` |  |\n| GET | `/api/mcp/info` |  |\n| POST | `/api/mcp/message` |  |\n| GET | `/api/media` |  |\n| POST | `/api/preview-build` | POST /api/preview-build |\n| POST | `/api/preview-serve` | Starts (or reuses) a lightweight static file server for the active site's dist/ directory. |\n| GET | `/api/preview-site-root` | Serve dist/index.html for the root path of the preview site. |\n| GET | `/api/preview-site/:...path` | Serve static files from the active site's dist/ directory. |\n| POST | `/api/publish-scheduled` | POST /api/publish-scheduled |\n| GET | `/api/schema` |  |\n| PUT, DELETE | `/api/schema/:collection` |  |\n| GET, POST | `/api/schema/collections` |  |\n| GET | `/api/search` | GET /api/search?q=query |\n| GET | `/api/site-file/:...path` | Serve static files from the site's public/ directory or proxy from previewUrl. |\n| GET, DELETE | `/api/trash` |  |\n| POST | `/api/upload` |  |\n| GET | `/api/uploads/:...path` |  |\n\n## Media API\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET | `/api/cms/media/usage` | GET /api/cms/media/usage |\n| DELETE | `/api/media/:...path` |  |\n| GET | `/api/media/ai-analyzed` |  |\n| GET | `/api/media/ai-meta` |  |\n| POST | `/api/media/analyze` |  |\n| POST | `/api/media/analyze-batch` |  |\n| POST | `/api/media/analyze-test` |  |\n| GET | `/api/media/exif` | GET /api/media/exif?file=/uploads/IMG_0051.jpeg |\n| POST | `/api/media/optimize-batch` | POST /api/media/optimize-batch — Generate WebP variants for all images in uploads/ |\n| POST | `/api/media/rename` | POST /api/media/rename |\n| POST | `/api/media/restore` |  |\n| POST | `/api/media/rotate` | POST /api/media/rotate |\n| GET, PATCH | `/api/media/tags` |  |\n| GET | `/api/media/video-thumb` | GET /api/media/video-thumb?file=/uploads/VIDEO.MOV |\n\n## Authentication\n\nAll protected endpoints require one of:\n- **Session cookie** — set after login via `POST /api/auth/login`\n- **API key** — passed in `Authorization: Bearer <key>` header\n\nPublic endpoints: `/api/auth/login`, `/api/auth/setup`, `/api/auth/me`\n\n## Rate Limits\n\nNo rate limits are enforced in the self-hosted CMS admin. The API is designed for single-tenant use.\n\n## Content Push Webhook\n\nWhen content is saved, the CMS can push updates to your site via webhook:\n\n```json\n{\n  \"event\": \"content.revalidate\",\n  \"collection\": \"posts\",\n  \"slug\": \"hello-world\",\n  \"action\": \"published\",\n  \"document\": { \"id\": \"...\", \"slug\": \"...\", \"data\": { ... } },\n  \"paths\": [\"/blog/hello-world\", \"/blog\"]\n}\n```\n\nHeader `X-CMS-Signature: sha256=<hmac>` is computed using your shared secret.",
  "excerpt": "Overview\n\nThe CMS admin exposes 136 API endpoints across 4 categories. All endpoints under /api/cms/, /api/admin/, and /api/media/ require authentication via session cookie or API key.\n\n Admin API\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| GET, POST | /api/admin/ai-co",
  "seo": {
    "metaTitle": "API Endpoints Reference — webhouse.app Docs",
    "metaDescription": "Complete reference of all 136 REST API endpoints in the CMS admin.",
    "keywords": [
      "webhouse",
      "cms",
      "api",
      "rest",
      "endpoints"
    ]
  },
  "createdAt": "2026-03-29T21:59:02.872Z",
  "updatedAt": "2026-03-29T21:59:02.872Z"
}