createWebPage
Create a new web page with SEO meta, hero banner, and custom content. Automatically refreshes cache and validates filename uniqueness for error-free publishing.
Instructions
Create a page - Create a list_seo page record. Writes live data.
Cache refresh is automatic. Response includes auto_cache_refreshed: true after successful writes; no manual refreshSiteCache call needed. If auto_cache_refreshed: false, check auto_cache_refresh_error and retry refreshSiteCache once.
Required fields: seo_type. filename is required for every seo_type EXCEPT data_category (the WRAPPER generates a 10-char lowercase alphanumeric placeholder slug for that type and auto-creates a 301 redirect to the canonical post-type URL; the public URL routes via the post type's data_filename, not list_seo.filename). When seo_type=data_category, linked_post_type is also required (auto-validated at runtime).
Filename uniqueness — enforced by the wrapper, no exceptions. BD does NOT enforce unique filename server-side, but duplicates break the platform (two pages at the same URL render non-deterministically). The wrapper auto-pre-checks listWebPages for an existing slug before forwarding the create. If a row exists, the create is rejected with the existing seo_id so the agent can updateWebPage instead, or pick a unique slug. There is no agent-facing bypass; for seo_type=data_category the wrapper generates the slug itself (10-char lowercase alphanumeric — statistically unique across 36^10, no pre-check needed).
Thin-content warning: if no title, h1, meta_desc, or content is set on a seo_type=content create, a _thin_content_warning field is attached to the response. The page is still created and is publicly live — Google may index it as thin content. Fix: provide at least one of those fields on the create call, or updateWebPage immediately after, or deleteWebPage if the create was premature.
Asset field routing (mandatory - Froala strips mismatched content silently):
content- body HTML. No<style>/<script>tags. Supports[widget=Name]shortcodes +%%%token%%%.content_css- raw CSS rules. NO<style>wrapper. Scope to a unique page class; never target.container/.froala-table/.image-placeholder(reserved). Do NOT use@import(causes FOUC/CLS - usecontent_head<link>tag instead).content_footer_html- JavaScript, pixels, analytics embeds (<script>tags OK here). IIFE-wrap + scope.content_head- head-only deps (<link>,<meta>, JSON-LD, external stylesheets, fonts).content_footer- MISLEADING NAME. NOT footer HTML. Page-access gate enum:""(public),"members_only","digital_products".Hero banner ->
enable_hero_section+hero_*+h1_*/h2_*fields.
All asset fields accept raw content verbatim. No CDATA, no <parameter>/<invoke>/<function_calls> scaffolding, no entity-escaped HTML — forbidden anywhere in the value, not just as wrappers. Server strips these as a safety net; do not rely on it.
SVG/canvas prohibited in content - Froala strips them. Charts/diagrams go in a custom Widget, embedded via [widget=Name] shortcode.
seo_type values: home (system-seeded; cannot CREATE homepage, only updateWebPage), content (generic static page), profile_search_results (member search override — apply Rule: Member search SEO pages), data_category (post search), custom_widget_page, password_retrieval_page, unsubscribed.
Hero section - when enable_hero_section = 1 or 2, apply Rule: Hero readability bundle (atomic — all listed values must be sent together). Notes:
All color fields RGB ONLY (
rgb(0, 0, 0)) - hex not accepted.Hero
h1_*/h2_*fields style ONLY the hero banner; H1/H2 TEXT comes from the record's top-levelh1/h2fields.Hero image: content-relevant Pexels stock photo (free license, no attribution). See Rule: Image URLs (imported field — bare URL, no query string). Never
picsum.photos/lorempixel/placekitten.Hero gap-fix CSS (
seo_type=contentONLY): add.hero_section_container + div.clearfix-lg {display:none}tocontent_cssto close BD's 40px clearfix gap. Never add this rule on any otherseo_type- onprofile_search_results/data_categorythe clearfix provides needed spacing before live search-results; hiding it causes results to butt-join the hero.Hero is cache-gated — but
createWebPage/updateWebPageauto-refresh handles it; no separate call needed.Homepage hero is BENIGN:
seo_id=1stores hero fields but the homepage template does NOT render them. Skip hero fields on homepage unless user explicitly asks.
profile_search_results SEO pages - thin-content remedy workflow:
Used to override BD's auto-generated dynamic search URLs (e.g. california/beverly-hills/plumbers) with static custom SEO copy. Creating a list_seo row with a matching filename takes over the public URL.
CRITICAL - filename MUST be a real slug BD's dynamic router recognizes. Arbitrary slugs render HTTP 404 publicly even when the record is created successfully. See Rule: Member search SEO pages for the canonical slug hierarchy (country/state/city/top/sub, strict order, any subset valid) and the live-lookup endpoints for each segment. Wrapper validates segments at runtime — country slug is derived from country_name (lowercase + spaces→hyphens). For arbitrary-URL static pages use seo_type=content.
Workflow for "add SEO to [category] in [location]":
Resolve each human name to its slug via the relevant
list*endpoint (exact-match=).For ambiguous inputs (e.g. "Beverly Hills plumbers" - could be
beverly-hills/plumbersorcalifornia/beverly-hills/plumbers), ask user which variant.Pre-check:
listWebPages property=filename property_value=<slug> property_operator==. Exists ->updateWebPage. Missing ->createWebPagewith the required defaults listed in step 4.Required defaults on create and every update (unless user overrides):
seo_type=profile_search_resultscustom_html_placement=4(Below Body Content - safest for boilerplate intro without disrupting live results)form_name="Member Search Result"(sidebar - Master Default; do NOT useMember Profile Page, that's for profile pages)menu_layout=3(Left Slim sidebar position)enable_hero_section=1+ content-relevant Pexelshero_image+ the readability safe-defaults from Rule: Hero readability bundle (atomic — all listed values must be sent together). Most end-users don't know to ask for a hero; thin-SEO pages underperform without one. User can opt out withenable_hero_section=0. (Cache flush is automatic post-write.)
Auto-generate SEO meta for the specific combo - don't leave blank:
title- 50-60 chars ideal, <=70 max. Pattern:"[Category] in [City], [State] | [Site Name]".meta_desc- 150-160 chars ideal, <=170 max. 1-2 sentence pitch with location + CTA.meta_keywords- ~200 chars, comma-separated (no spaces).facebook_title- 55-60 chars, differ fromtitle(more conversational).facebook_desc- 110-125 chars, punchier thanmeta_desc.Do NOT auto-set
facebook_image(needs uploaded asset).
H1/H2 double-render trap: if hero enabled AND
contentcontains<h1>/<h2>, both render. Either seth1/h2fields and omit fromcontent, or put incontentand leave fields blank. Never both.No max-width wrappers in
contentorcontent_cssonprofile_search_resultspages. BD's layout already provides the outer container; addingmax-width: 960px; margin: autodouble-constrains to a narrow strip. Let content flow at natural container width.custom_html_placementis only meaningful onprofile_search_results(anddata_category). Ignored oncontentpages.
SEO content for categories: route to createWebPage seo_type=profile_search_results (NOT updateTopCategory.desc / updateSubCategory.desc - those are internal labels, not rendered).
list_seo EAV fields — auto-routed by the wrapper, no special handling. Pass any field on createWebPage / updateWebPage directly; if it's an EAV-stored field (e.g. hero_*, h1_*, h2_*, linked_post_category, disable_*), the wrapper routes the write through users_meta automatically. Response includes an eav_results array confirming which EAV fields were written. Reads merge automatically via getWebPage/listWebPages. On deleteWebPage: BD does NOT cascade — run orphan cleanup per Rule: users_meta orphans (listUserMeta filtered by database=list_seo+database_id=<deleted seo_id>, then deleteUserMeta each match).
See also: listWebPages, updateWebPage, createRedirect (preserve SEO on slug changes).
Returns: { status: "success", message: {...createdRecord}, auto_cache_refreshed: true|false, auto_cache_refresh_error?: "...", _admin_edit_url: "..." } including seo_id. auto_cache_refreshed reports whether the automatic cache flush succeeded; if false, auto_cache_refresh_error explains why and the agent should retry refreshSiteCache manually once. _admin_edit_url is a centralized-admin deep-link to the WebPage editor for this seo_id — surface it to the user so they can jump straight to the admin edit screen for the page just created.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| seo_type | Yes | Page type identifier. User-selectable values: - `content` = Single Web Page (USE for custom/landing/static/about/contact - the default) - `data_category` = Post Search Results - `profile_search_results` = Member Search Results - `custom_widget_page` = Custom Widget as Web Page - `password_retrieval_page` = Password Retrieval Page - `unsubscribed` = Unsubscribed Page For "landing page", "static page", "about page", "contact page", any generic custom page -> always `content`. BD has additional internal values (`home`, `profile`, `payment`, etc.) that are system-seeded - do NOT create via API. | |
| filename | No | URL slug (e.g. home, about-us). Must be unique across web pages, top categories, sub categories, plan public URLs, and member profile slugs — wrapper auto-rejects collisions. Either pick a unique slug or `updateWebPage` the existing record. **OPTIONAL on `seo_type=data_category`** — the WRAPPER generates a 10-char lowercase alphanumeric placeholder slug if omitted (or rewrites a non-conforming agent-supplied value), and auto-creates a 301 redirect from that slug to the canonical post-type URL. The public URL routes via the post type's `data_filename` + category, not `list_seo.filename`. REQUIRED on every other seo_type. | |
| nickname | No | Human-readable label shown in admin panel | |
| title | No | **Page Meta Title** - Supports template tokens: `%%%website_name%%%`, `%industry%`, `%profession%`, etc. ~30-60 chars recommended. HTML title tag - supports template tokens like %%%website_name%%% | |
| meta_keywords | No | **Meta Keywords** - Supports template tokens (comma-separated). Meta keywords - supports template tokens | |
| meta_desc | No | **Meta Description** - Supports template tokens. ~150-160 chars recommended for search snippets. Meta description - supports template tokens | |
| seo_text | No | **Wildcard URL Rewrite.** `1` = any URL within this directory routes to this web page (catch-all behavior). Misnamed field - NOT SEO copy; SEO copy goes in `content` + meta fields. | |
| h1 | No | **H1 Heading** - Supports template tokens. Rendered as the page's main heading. H1 heading - supports template tokens | |
| h2 | No | **H2 Heading** - Supports template tokens. H2 heading - supports template tokens | |
| breadcrumb | No | **OMIT** — BD auto-generates the breadcrumb trail. Never set this yourself; a manual value overrides BD's generated trail and breaks the page. | |
| content | No | Main page body - Froala rich-text editor. **Shortcodes:** `[form=<form_name>]` embeds a BD form; `[widget=<widget_name>]` embeds a widget; `%%%template_tokens%%%` for site vars. **HTML only** - Froala strips `<style>`, `<script>`, `<form>`, `<input>`, `<select>`, `<textarea>`, `contenteditable=`, AND inline `style="..."` attributes on save. Route all non-body assets to their dedicated fields: CSS -> `content_css` (target classes, not inline styles), JS -> `content_footer_html`, head deps (`<link>`, fonts, `<meta>`, JSON-LD) -> `content_head`. SVG/canvas also stripped; for charts/diagrams use a custom Widget embedded via `[widget=Name]` shortcode. | |
| content_css | No | Custom CSS for this page. Paste raw CSS rules directly - NO `<style>` wrapper. Renders in page `<head>` at load. Scope every selector to a unique page class/ID (e.g. `.my-about-page h2 { ... }`) - bare `body`/`h1`/`p` affect the whole site. Never target reserved BD classes: `.container`, `.froala-table`, `.image-placeholder`. Never `@import` (FOUC/CLS) - load external stylesheets/fonts via `<link>` tag in `content_head`. **Admin Froala editor gotcha** - editor applies `content_css` but does NOT run `content_footer_html` JS. Hide-by-default CSS (scroll reveals, tab panels, accordion collapsed, modal hidden, slider non-active slides) will permanently hide content in the editor. Gate such rules behind a `.js-ready` class that `content_footer_html` JS adds on load: `.my-page.js-ready .reveal { opacity:0 }` NOT `.my-page .reveal { opacity:0 }`. The paired JS rule lives in the `content_footer_html` field. | |
| content_footer_html | No | Page-scoped JavaScript + script embeds - rendered before `</body>`. `<script>` tags accepted here (unlike `content`). jQuery loaded globally. Wrap JS in an IIFE `(function($){ ... })(jQuery);` and scope selectors to a unique page class. Also for third-party script embeds (analytics pixels, chat widgets, schema markup). NOT for extra body HTML - `content` is the body field. **If `content_css` uses a `.js-ready` gate for hide-by-default effects** (scroll reveals, tab panels, accordion collapse, modal hidden, slider non-active), JS MUST add that class to the page wrapper as the FIRST line (before any other init code): `document.querySelector('.my-page')?.classList.add('js-ready');`. The admin Froala editor applies CSS but does NOT run this field's JS, so without the gate, hide-rules make content permanently invisible in the editor. | |
| content_head | No | Page-scoped `<head>` dependencies - rendered inside `<head>`. Use for: `<link>` tags (external stylesheets, preconnect hints, canonical overrides, Google Fonts), `<meta>` tags beyond standard SEO fields, verification tags, JSON-LD structured data (`<script type="application/ld+json">`), head-required third-party scripts (rare - prefer `content_footer_html` for most JS). | |
| content_footer | No | **MISLEADING NAME - NOT page footer HTML.** Misnamed relic column; BD repurposed as the **page-access gate**: - `""` (default) = Public For Everyone - `"members_only"` = Logged-in members only (non-members hit login/signup wall) - `"digital_products"` = Only buyers of digital-product items Finer rules (which members, which plans) live in other fields. Do NOT put HTML here. Page body -> `content`; scripts -> `content_footer_html`. No dedicated "below-body HTML" field - put below-body markup inside `content` itself. | |
| content_menu | No | Menu section this page belongs to | |
| content_order | No | Sort order within menu/section | |
| content_group | No | Admin-panel grouping label | |
| content_layout | No | **Full Screen Page Width override.** OMIT for normal pages (BD's default container width). Set to `1` for full-bleed pages — individual sections in `content` can then break edge-to-edge (background bands, hero strips, viewport-wide images). **For full-bleed sections, set `content_layout=1` FIRST.** Do NOT fake full-bleed with negative-margin/9999px-padding tricks in `content_css` — breaks horizontal scroll, fights `overflow: hidden` parents, prevents future layout changes. Anti-pattern. Pattern with `content_layout=1`: scoped CSS in `content_css` gives each section its own edge-to-edge background; inner `<div class="container">` (or page-scoped max-width wrapper) keeps readable copy centered. | |
| content_sidebar | No | Sidebar configuration or widget shortcode | |
| menu_layout | No | Sidebar position + width (integer). Only effective when the page has a sidebar set via `form_name` - ignored without sidebar. NOT a navigation menu layout despite the field name. - `1` = Left Wide (BD default when unspecified) - `2` = Right Wide - `3` = Left Slim - `4` = Right Slim Ordering is NOT sequential by side - left positions are `1` and `3`, right are `2` and `4`. **Default on `profile_search_results` pages:** `3` (Left Slim). On `content` pages, omit unless user specifies (BD defaults to `1`). | |
| show_form | No | **Apply NoIndex,NoFollow.** `1` = adds `<meta name="robots" content="noindex,nofollow">` to the page. Auto-applied to protected pages. **NOT a form-render toggle** despite the field name — BD repurposed this column. To render a form in the body, use `[form=<form_name>]` inside `content`. | |
| form_name | No | **SIDEBAR name** for this page - BD's field is misnamed; controls sidebar slot, NOT a contact form. NOT for rendering forms on this page — to embed a form in the body, use `[form=<form_name>]` inside `content`. Pass exact sidebar `name` string. `""` = no sidebar. Valid values: a Master Default Sidebar OR a custom sidebar `name` from `listSidebars`. See **Rule: Sidebars** for the canonical Master Default list and selection workflow. `menu_layout` controls position when `form_name` is set. **Default on `profile_search_results` pages:** `Member Search Result` (NOT `Member Profile Page` - that's for profile/detail pages, not search results). | |
| hide_header_links | No | **Hide Main Menu** - 1 = hides the main navigation menu on this page. | |
| hide_header | No | **Hide Header** - 1 = hides the full site header on this page. | |
| hide_footer | No | **Hide Footer** - 1 = hides the site footer on this page. | |
| hide_top_right | No | **Hide Top Header Menu** - 1 = hides the top-right nav cluster (account/login links). | |
| facebook_title | No | **Social Media Title (Open Graph)** - Title shown when the page is shared on Facebook/LinkedIn/etc. Open Graph title for social sharing | |
| facebook_desc | No | **Social Media Description (Open Graph)** - Description shown on social shares. Open Graph description | |
| facebook_image | No | **Social Media Shared Image** - URL/filename of the OG image. BD recommends at least 200×200px. Open Graph image URL | |
| org_template | No | **OMIT** — internal layout reference. No public lookup endpoint; setting an arbitrary value can render the page against a nonexistent layout. | |
| allowed_products | No | Comma-separated plan/product IDs (empty = all plans) | |
| custom_html_placement | No | Render position of `content` HTML relative to dynamic search results. Only meaningful on `seo_type=profile_search_results` (and `data_category`); ignored on `content` pages. - `0` = Inside Tab (content + members in separate nav tabs) - `1` = Above Member Results (within results container, sidebar-width) - `2` = Below Member Results (within results container) - `3` = Above Body Content (full page width, spans sidebar+results) - `4` = Below Body Content (full page width, below sidebar+results) <- **recommended default for AI-generated SEO pages** For boilerplate SEO intro/FAQ/local copy bolstering thin pages, `4` renders full-width below the live results without disrupting member-facing UX. | |
| enable_hero_section | No | Hero banner master switch: - `0` = disabled (all other `hero_*`/`h1_font_*`/`h2_font_*` ignored at render; stored values preserved for later toggle-back) - `1` = enabled all devices - `2` = enabled desktop, hidden mobile **On hero off→on transition (`0`/unset → `1`/`2`), wrapper auto-fills the hero readability bundle** — `hero_top_padding=100`, `hero_bottom_padding=100`, `hero_column_width=5`, `hero_content_overlay_color=rgb(0, 0, 0)`, `hero_content_overlay_opacity=0.5`, `hero_content_font_color=rgb(255, 255, 255)`, `hero_content_font_size=18`, `h1_font_color=rgb(255, 255, 255)`, `h2_font_color=rgb(255, 255, 255)` — for any of those 9 fields you OMITTED. BD's per-field defaults render an unreadable hero (10px content text on a 0.4-opacity overlay, default top/bottom padding 70/60 — visually too cramped for most banner imagery); the bundle is the canonical readable recipe. User-supplied values pass through untouched. Filled fields are echoed in `_hero_bundle_autofilled`. **`hero_image` is required** on transition — wrapper rejects if missing (no safe default; walk the image-sourcing ladder). On no-transition updates (hero already on), no auto-fill fires. **Homepage benign** - `seo_type=home` ignores hero fields entirely regardless of value. BD stores but never renders on homepage; skip all `hero_*` fields on homepage updates. | |
| hero_hide_banner_ad | No | When `1`, suppresses the site-wide "Below Header Banner Ad" on THIS page only (useful when the hero visually replaces that slot). `0` (default) keeps the banner ad in its normal position. | |
| hero_image | No | Hero background image. Accepts BD-hosted relative path (`/images/bg202.webp`) OR external URL (`https://cdn.example.com/banner.jpg`) — external URLs render hotlinked on WebPages, no `auto_image_import` needed. **LANDSCAPE only — never portrait/vertical; source via `https://www.pexels.com/search/<term>/?orientation=landscape`; bare URL, no `?query`, must end in `.jpg`/`.jpeg`/`.png`/`.webp` — see **Rule: Image URLs**.** Query strings get truncated/mangled in BD's form-urlencoded parsing and the stored URL becomes invalid. Recommended dimensions: 1800 × 600 px. | |
| hero_background_image_size | No | Controls how the hero background image scales/crops across devices. `mobile-ready` (recommended) = responsive behavior tuned for mobile, `standard` = fixed-ratio behavior. | |
| hero_content_overlay_color | No | Semi-transparent color layer between hero background image and text, for legibility over busy images. **RGB format ONLY** - `rgb(0, 0, 0)` or `rgb(255, 255, 255)`. Hex (`#000000`) NOT accepted. Combine with `hero_content_overlay_opacity` to control strength. Wrapper auto-fills `rgb(0, 0, 0)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_content_overlay_opacity | No | Opacity of `hero_content_overlay_color` layer, 0.1 increments from `0.0` (transparent) to `1` (opaque). Admin UI labels 0-10. BD field default `0.4` is too transparent — wrapper auto-fills `0.5` on hero off→on transition (part of **Rule: Hero readability bundle**). EAV-routed by the wrapper — pass on `updateWebPage` directly, no manual `updateUserMeta` needed. | |
| hero_top_padding | No | Top padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `70` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_bottom_padding | No | Bottom padding inside the hero banner, in pixels. Accepts multiples of 10 from `0` to `200`. BD field default `60` — wrapper auto-fills `100` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_column_width | No | Hero text-content column width as Bootstrap 12-col span. `3`=25%, `4`=30%, `5`=40%, `6`=50%, `7`=60%, `8`=70%, `9`=75%, `10`=80%, `11`=90%, `12`=100%. Narrower = more side padding around the text block. BD field default `8` — wrapper auto-fills `5` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_alignment | No | Horizontal alignment of the hero title/subtitle/content text block within its column. Default `center`. | |
| h1_font_color | No | Main title (H1) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H1 text itself comes from the page's `h1` field - these `h1_*` fields control ONLY the hero's H1 styling. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| h1_font_size | No | Main title (H1) font size in pixels. Accepts integer values from `30` to `80`. OMIT to inherit BD's per-`seo_type` default. | |
| h1_font_weight | No | Main title (H1) font weight. `300`=Light, `400`=Normal (default), `600`=Bold, `800`=Extra Bold. | |
| h2_font_color | No | Sub-title (H2) font color in the hero. RGB format ONLY - e.g. `rgb(255, 255, 255)`. The H2 text itself comes from the page's `h2` field. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| h2_font_size | No | Sub-title (H2) font size in pixels. Accepts integer values from `20` to `60`. OMIT to inherit BD's per-`seo_type` default. | |
| h2_font_weight | No | Sub-title (H2) font weight. `300`=Light, `400`=Normal, `600`=Bold (default), `800`=Extra Bold. | |
| hero_content_font_color | No | Font color for the additional hero content block rendered below H1/H2 (the `hero_section_content` field). RGB format ONLY - e.g. `rgb(0, 0, 0)`. Wrapper auto-fills `rgb(255, 255, 255)` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_content_font_size | No | Font size in pixels for the additional hero content block (`hero_section_content`). Accepts integer values from `10` to `30`. BD field default `10` is too small for hero paragraph copy — wrapper auto-fills `18` on hero off→on transition (part of **Rule: Hero readability bundle**). | |
| hero_section_content | No | Additional text / HTML / widget shortcode rendered BELOW H1 and H2 in the hero section. Supports `[widget=Name]` shortcodes. EAV-routed by the wrapper — pass on `createWebPage` / `updateWebPage` directly, no manual `updateUserMeta` needed. | |
| hero_link_url | No | Hero call-to-action (CTA) button link URL. If empty, no CTA button is rendered. For internal links, a relative path is fine (e.g. `/signup`); for external, full URL with `http://` or `https://`. | |
| hero_link_text | No | Hero CTA button label. Required (non-empty) for the button to render - `hero_link_url` alone without text will not produce a button. | |
| hero_link_target_blank | No | When `1`, opens the CTA link in a new tab (`target="_blank"`). `0` (default) opens in the same tab. | |
| hero_link_size | No | CTA button size. MUST be exactly one of: `""` (empty = Normal), `btn-lg` (Large), `btn-xl` (Extra Large). Any other value (e.g. a font-size number like `16`) is stored verbatim and rendered as a broken class — BD does not validate server-side. | |
| hero_link_color | No | CTA button color variant — attention level, not literal color. MUST be exactly one of: `primary`, `info`, `success`, `warning`, `danger`, `default`, `secondary`. Any other value (e.g. a hex `#ffffff`) is stored verbatim and rendered as a broken class like `btn-#ffffff` — BD does not validate server-side. Choose by attention level needed: `primary` (main CTA), `danger` (urgent/can't-miss), `warning` (attention), `success` (positive action), `info` (neutral-blue), `secondary` (theme secondary), `default` (low-emphasis gray). Actual rendered color comes from the site's theme palette. | |
| linked_post_type | No | Post type's `data_id` (from `listPostTypes`). REQUIRED when `seo_type=data_category`; ignored on other seo_types. See **Rule: Resource disambiguation** when the user names a post type by description rather than `data_id`. | |
| linked_post_category | No | Either the literal `post_main_page` (pins to the post type's main search-results page) OR an exact category name from the linked post type's `feature_categories` (e.g. `"Category 1"`, case-sensitive). Optional on `seo_type=data_category` — wrapper auto-defaults to `post_main_page` when omitted on a fresh data_category create or content→data_category switch. Ignored on other seo_types. Wrapper enforces pair-uniqueness on `(linked_post_type, linked_post_category)`. | |
| disable_css_stylesheets | No | Disable BD's site stylesheets on this page (frontend only). `1` = page renders without BD's global CSS (use when embedding a fully self-styled custom page or iframe target). `0` (default) = normal BD styling. EAV-stored — agent passes directly; wrapper handles routing on update. | |
| private_page_select | No | Access control setting | |
| page_render_widget | No | **OMIT** — internal widget reference for `seo_type=custom_widget_page` only. No public widget-ID lookup; setting on other page types breaks rendering. |