AI Page Building Guide
This guide defines the safe workflow for trusted AI/operator tools that build WebBlocks CMS pages through the Internal Content API. It is generic CMS product guidance. Do not add site-specific import, sync, or scraping behavior to CMS core.
External AI/operator tools do not need local filesystem access to the CMS repository or installed package docs. Start with the live API discovery endpoint:
GET /webadmin/api
In installed package-native sites, this guide also ships inside the Composer package at:
vendor/fklavyenet/webblocks-cms/docs/ai-page-building-guide.md
Purpose
Trusted AI/operator tools can inspect a CMS install, build a structured draft content plan, validate it, create a separate draft page, replace specific page-owned slots on an existing draft page after explicit user approval, or call explicit publish endpoints when the token has content.publish. The normal page-building workflow is draft-first and API-first. Content apply does not publish content, overwrite published pages, clear Shared Slot-backed slots, fetch remote websites, or import media.
Token Setup
Create API tokens from the CMS admin panel:
System -> API Tokens
The plain token is shown once immediately after creation. Store it in a trusted operator secret store and never paste a real token into prompts, documentation, logs, screenshots, tickets, or release reports.
Use the API discovery base URL in local tool configuration:
WEBBLOCKS_CMS_API_URL=https://example.com/webadmin/api
WEBBLOCKS_CMS_API_TOKEN=...
For normal page-building tools, keep the default page-building capabilities selected. Grant advanced publish or page-delete capabilities only to trusted operator tools that explicitly need them.
API requests use:
Authorization: Bearer <token>
Accept: application/json
Content-Type: application/json
First Discovery Calls
Start with API discovery. The first call is:
GET /webadmin/api
Without a valid token, this endpoint returns only minimal public-safe bootstrap JSON. With a valid Bearer token, it returns links to the OpenAPI schema, AI guide, content contract, examples, validate/apply endpoints, pages, navigation, and Shared Slots.
Then follow the returned links. Common token-protected endpoints live under /webadmin/api:
GET /webadmin/api/openapi.json
GET /webadmin/api/ai-guide
GET /webadmin/api/examples/contact-page
GET /webadmin/api/sites
GET /webadmin/api/locales
GET /webadmin/api/page-layouts
GET /webadmin/api/block-types
GET /webadmin/api/content-contract
GET /webadmin/api/navigation-menus
GET /webadmin/api/shared-slots
GET /webadmin/api/pages
Use GET /webadmin/api/pages when you need to check existing slugs, live placeholder pages, or previous drafts before proposing a new page.
Never Guess Block Handles
AI tools must not invent or guess block handles. Exact handles must be learned from GET /webadmin/api/block-types or GET /webadmin/api/content-contract for the current install before building a plan.
Examples of handles that commonly exist but must still be verified at runtime:
section
container
grid
card
card_body
hero
cta
plain_text
rich-text
button_link
sticky-navbar
Do not substitute nearby spellings such as plain-text, rich_text, button, navbar, or navigation_auto unless discovery confirms those exact handles.
Safe Workflow
- Run read-only discovery.
- Read OpenAPI, the content contract, and examples from the live API links.
- Build a content plan using only discovered handles and the current site/layout/locale.
- Validate with
POST /webadmin/api/content/validate. - Read validation errors and adjust the plan.
- Ask the user for explicit approval to apply the exact final plan.
- Only after approval, call
POST /webadmin/api/content/apply. - Read the created draft page id from the apply response.
- Produce the admin preview URL with
/webadmin/pages/{page}/preview. - Leave publishing to a human workflow unless the user explicitly approved an API publish operation and the token has
content.publish.
Safety Rules
- Draft-first.
- Apply only after explicit user approval.
- Do not publish through content apply.
- Do not assume page publish makes all blocks public; use
include_page_owned_blocks: trueonly after explicit approval. - Do not delete pages through content apply.
- Do not overwrite existing pages or blocks except with the explicit
replace_existing_draft_pagemode. - Do not call apply if the target path already exists unless the user explicitly approves a conflict-handling plan supported by the API.
- For existing draft replacement, include
expected_pathorexpected_updated_atand replace only page-owned slots. - Treat
page.pathas the canonical public URL. Use/contactor/docs/internal-content-api, not/p/contact;/p/...is only a legacy public redirect. - Do not try to replace Shared Slot-backed slots; leave shared header/footer assignments intact.
- Do not fetch remote pages.
- Do not use browser automation or admin UI clicks when API discovery is available.
- Do not download or import media.
- Do not create API tokens from automation unless the user explicitly asks for token administration.
- Do not print, log, or report token values.
- Report only status codes and safe summarized response data.
- Treat
401,403, and422JSON responses as API feedback and follow their discovery/documentation links.
Good Structures
Prefer structured blocks over a single large content blob.
Marketing homepage:
section -> container -> hero
section -> container -> grid -> card -> card_body
section -> container -> cta
Header/navbar:
shared_slot header
sticky-navbar -> container(flow:none) -> cluster -> navbar-brand + cluster -> navbar-navigation + header-actions
For most public pages, place wide promo blocks such as hero and cta inside section -> container. Direct full-width hero or cta blocks under main should be intentional edge-to-edge design choices, not the default.
Contact page:
section -> hero + contact_form
Use the native contact_form block for contact pages after discovery confirms the handle is available. Its visible copy is translated with title, content, submit_label, and success_message; shared settings are recipient_email, send_email_notification, and store_submissions. The renderer emits the native CSRF-protected public form, CMS-owned hidden generated anti-spam check field, and /contact-messages submit endpoint. AI/operator tools should not create the check field manually and should not use Trusted HTML, raw forms, or mailto: as substitutes.
Bad Structures
- Do not put a full page into one
rich-textblock. - Do not put a full page into one trusted
htmlblock when structured blocks can represent it. - Do not build contact forms with Trusted HTML, raw form markup, or
mailto:links whencontact_formis available. - Do not guess handles.
- Do not overwrite published content.
- Do not mutate an existing live page when a new separate draft page is safer.
- Do not paste tokens into prompts or reports.
Minimal Draft Plan Example
This example assumes discovery confirmed section, container, hero, grid, card, card_body, plain_text, button_link, and cta.
{
"plan": {
"site": "default",
"locale": "en",
"layout": "default",
"page": {
"title": "Example Homepage Draft",
"path": "/example-homepage-draft",
"status": "draft"
},
"slots": {
"main": [
{
"type": "section",
"settings": {
"spacing": "lg"
},
"children": [
{
"type": "container",
"children": [
{
"type": "hero",
"translations": {
"title": "Build useful pages faster",
"subtitle": "A structured CMS workflow for practical content teams.",
"content": "Create focused draft pages from reusable blocks, then review them safely before publishing."
},
"children": [
{
"type": "button_link",
"translations": {
"title": "Start building"
},
"settings": {
"url": "/get-started",
"variant": "primary"
}
}
]
}
]
}
]
},
{
"type": "section",
"settings": {
"spacing": "lg"
},
"children": [
{
"type": "container",
"children": [
{
"type": "grid",
"children": [
{
"type": "card",
"children": [
{
"type": "card_body",
"children": [
{
"type": "plain_text",
"translations": {
"content": "Create drafts from structured content plans."
}
}
]
}
]
},
{
"type": "card",
"children": [
{
"type": "card_body",
"children": [
{
"type": "plain_text",
"translations": {
"content": "Review safely through authenticated admin preview."
}
}
]
}
]
}
]
}
]
}
]
},
{
"type": "section",
"settings": {
"spacing": "lg"
},
"children": [
{
"type": "container",
"children": [
{
"type": "cta",
"translations": {
"title": "Ready for review?",
"content": "Validate the plan, apply only after approval, then open the admin preview."
}
}
]
}
]
}
]
}
}
}
Validate first:
POST /webadmin/api/content/validate
Apply only after explicit approval:
POST /webadmin/api/content/apply
Then preview:
/webadmin/pages/{page}/preview
The preview URL is a browser/admin route. It requires an authenticated admin browser session and is not accessible with a CMS API Bearer token. If browser smoke testing lands on a login page, report that the admin browser session is missing; do not treat it as a JSON API token failure.
Existing Draft Slot Replacement
Use this mode only when the user explicitly wants to update an existing draft page instead of creating a new draft. Validate first, then apply only after approval:
{
"plan": {
"mode": "replace_existing_draft_page",
"site": "default",
"locale": "en",
"page": {
"id": 9,
"expected_path": "/contact",
"status": "draft"
},
"replace_slots": {
"main": [
{
"type": "plain_text",
"translations": {
"content": "Updated draft page copy."
}
}
]
}
}
}
Validate:
POST /webadmin/api/content/validate
Apply:
POST /webadmin/api/content/apply
The CMS removes old page-owned blocks only from the named slots and writes the new block tree in one transaction. Shared Slot-backed slots are rejected by this mode, so header/footer assignments remain untouched unless a separate supported API operation changes them.
Explicit Publish
Publishing is not part of validate/apply. Trusted operator tools with content.publish may call:
POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks
POST /webadmin/api/pages/{page}/publish defaults to:
{
"include_page_owned_blocks": false
}
With the default, the endpoint publishes only the page record. It does not publish draft or in-review blocks. Set include_page_owned_blocks: true only when the user explicitly wants all unpublished page-owned blocks for that page to publish too. The cascade includes nested child blocks under page-owned slots and excludes Shared Slot-backed slots.
POST /webadmin/api/pages/{page}/publish-page-owned-blocks publishes page-owned draft or in-review blocks without changing the page workflow status.
Never request Shared Slot cascade publishing from page publish endpoints. Shared Slot content is not included and must be reviewed and published separately.
Real Site Revisions
For real sites, first inspect the current pages and existing drafts. If a draft already exists, preview it before proposing new work. Use replace_existing_draft_page only for explicit draft-safe page-owned slot replacement. Otherwise, create a new separate draft page instead of overwriting the existing draft or live published homepage.
For QuizTem-style homepage revisions, use the existing draft as reference material only unless the user explicitly approves a supported update flow. The safe default for new work is:
- Preview the existing draft.
- Build a better structured plan with discovered block handles.
- Validate the plan.
- Ask for explicit apply approval.
- Create a new separate draft page.
- Open
/webadmin/pages/{page}/previewfor human review.