API reference
The API does what the AI connector does, at plain web addresses. Send your key in the Authorization header; send and get JSON.
curl https://brightpage.ca/api/v1/sites \
-H "Authorization: Bearer bpk_…"
Make a key in your account, ticking the sites it may use. Addresses take a site’s id or its name after /s/, and a page’s id or address (home for the home page). Changes are saved as drafts, kept in page History, and written to your site’s log. Publishing a site or post and sending a newsletter wait for you to confirm a link, unless you add "confirm": true. Up to 120 requests a minute per key. Errors come back as { "error": "…" } with a plain sentence.
GET /api/v1/sites
List the sites this connection can use, with their addresses and status.
MCP tool: list_sites · reads only
GET /api/v1/sites/:site
A site’s settings (name, theme, header, footer, business details) and its list of pages.
MCP tool: get_site · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).
GET /api/v1/templates
The templates a new site can start from.
MCP tool: list_templates · reads only
POST /api/v1/sites
Make a new site from a template. It starts as a draft at brightpage.ca/s/<handle>.
MCP tool: create_site · changes your site
nameneeded string: The site’s name, e.g. "Cedarline Renovations".handleneeded string: Its free address after brightpage.ca/s/: 3–30 lowercase letters, numbers or dashes.templateneeded string: A template key from list_templates.languagestring: The site’s language: en, fr or es. Its sample text starts in that language. Leave out for the account’s language.
PATCH /api/v1/sites/:site
Change a site’s name, language, header, footer, top bar, business details, logo or analytics tool ids. Fields left out stay as they are.
MCP tool: update_site_settings · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).namestring: Site name.languagestring: The language the site speaks to visitors: en (English), fr (Canadian French) or es (Latin American Spanish). Forms, booking, dates and Brightpage’s own words follow it; the owner’s text is not translated.headerobject: { tagline, button_label, button_url }footerobject: { about, note, copyright, socials: { instagram: "https://…", … } }announcementobject: The bar across the top: { on, text, link_label, url }businessobject: { address, phone, email, hours } (shown to Google)toolsobject: Analytics and pixel ids, e.g. { google_analytics: "G-…" }logostring: A picture id from the site’s pictures.
PUT /api/v1/sites/:site/second-language
Give a site a second language (a two-language site, e.g. English and French) with a switch for visitors, or turn it off. Each page gets its own version in that language: read it with get_page and save it with save_page (lang). Pages not translated yet show visitors the main version; blog posts stay in the main language. Turning it off keeps the translations.
MCP tool: set_second_language · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).languageneeded string: The second language (not the site’s main one), or "" to turn it off.wordsobject: Optional: the header, footer and top-bar words in that language: { header: { tagline, button_label }, footer: { about, note, copyright }, announcement: { text, link_label } }. Empty ones show the main language’s.
PATCH /api/v1/sites/:site/design
Change a site’s theme: palette, fonts, buttons, header style and spacing. See list_block_types for the palettes and fonts.
MCP tool: set_design · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).palettestring: A palette key, e.g. "forest".fontsstring: A font pair key, e.g. "classic".buttonsstring: square, rounded or pillbuttonColorstring: accent or brandheaderstring: bar, centered or splitspacingstring: compact, regular or roomy
POST /api/v1/sites/:site/copy-look
Give a site the same look (palette, fonts, buttons, design values) as another of your sites.
MCP tool: copy_site_look · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).from_siteneeded string: The site to copy the look from.
GET /api/v1/blocks
Every block type with its fields, the groups they’re in, the per-block look options, palettes and fonts.
MCP tool: list_block_types · reads only
GET /api/v1/sites/:site/pages/:page
A page’s draft: title, menu place, search settings and blocks. With lang, its version in the site’s second language (made as a copy of the page the first time).
MCP tool: get_page · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version: the site’s second language for its translation (see set_second_language). Leave out for the main one.
POST /api/v1/sites/:site/pages
Add a page. Without blocks it starts with a heading.
MCP tool: add_page · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).titleneeded string: The page’s name in the menu.slugstring: Its address, e.g. "services". Made from the title if left out.blocksarray: The page’s blocks in order: [{ type, data, style? }]. See list_block_types for every type and its fields.navboolean: Show it in the menu (default yes).
PUT /api/v1/sites/:site/pages/:page
Save a page’s title, menu place, search settings and/or its whole list of blocks (replaces them). The version before is kept in History. With lang, saves its version in the site’s second language (menu place and members stay shared).
MCP tool: save_page · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version: the site’s second language for its translation (see set_second_language). Leave out for the main one.titlestring: Name in the menu.navboolean: Show in the menu.membersboolean: Only members can open it (Members-only pages add-on).blocksarray: The page’s blocks in order: [{ type, data, style? }]. See list_block_types for every type and its fields.seoobject: { title, description, image, noindex }
POST /api/v1/sites/:site/pages/:page/blocks
Add one block to a page, at the end or at a position (0 is the top). With lang, to its version in the site’s second language.
MCP tool: add_block · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version of the page: the site’s second language changes its translation (made as a copy of the page the first time). Leave out for the main one.typeneeded string: A block type from list_block_types.dataobject: The block’s fields.styleobject: Optional look: { background, spacing, align, width, … }positioninteger: Where to put it (0 = top). Default: the end.
PATCH /api/v1/sites/:site/pages/:page/blocks/:index
Change some fields of one block (by its index on the page); other fields stay. With lang, in its version in the site’s second language.
MCP tool: update_block · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version of the page: the site’s second language changes its translation (made as a copy of the page the first time). Leave out for the main one.indexneeded integer: The block’s place on the page, from 0.dataobject: Fields to change.styleobject: Look to change.
POST /api/v1/sites/:site/pages/:page/blocks/move
Move a block to another place on its page. With lang, in its version in the site’s second language.
MCP tool: move_block · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version of the page: the site’s second language changes its translation (made as a copy of the page the first time). Leave out for the main one.fromneeded integer: Its place now.toneeded integer: Its new place.
DELETE /api/v1/sites/:site/pages/:page/blocks/:index
Remove a block from a page (it stays in History). With lang, from its version in the site’s second language.
MCP tool: remove_block · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version of the page: the site’s second language changes its translation (made as a copy of the page the first time). Leave out for the main one.indexneeded integer: The block’s place, from 0.
DELETE /api/v1/sites/:site/pages/:page
Delete a page (not the home page).
MCP tool: remove_page · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).
PUT /api/v1/sites/:site/pages/order
Put the pages in a new order (the menu follows it).
MCP tool: order_pages · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pagesneeded array: Page ids in the new order.
GET /api/v1/sites/:site/pages/:page/versions
Earlier versions of a page (every save keeps the one before). With lang, of its second-language version.
MCP tool: list_page_versions · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).langstring: Which version: the site’s second language for its translation (see set_second_language). Leave out for the main one.
POST /api/v1/sites/:site/pages/:page/versions/:version/restore
Put an earlier version of a page back (the current one is kept in History too).
MCP tool: restore_page_version · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).pageneeded string: The page: its id, or its address ("" or "home" for the home page, "about", …).versionneeded integer: A version id from list_page_versions.
POST /api/v1/sites/:site/publish
Publish the site’s drafts so visitors see them. Two steps: this returns a link the person opens to confirm.
MCP tool: publish_site · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).confirmboolean: API keys only: publish now without the link.
GET /api/v1/sites/:site/posts
The site’s blog posts: drafts, scheduled and published.
MCP tool: list_posts · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).
GET /api/v1/sites/:site/posts/:post
One blog post with its full text.
MCP tool: get_post · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).postneeded integer: The post id.
POST /api/v1/sites/:site/posts
Write a blog post or change one (as a draft; publish it with publish_post). Text: blank lines between paragraphs; ## Heading, - points, **bold**, *italic*, [link](https://…), .
MCP tool: save_post · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).postinteger: The post id to change; leave out for a new post.titlestring: Title.bodystring: The text.excerptstring: A line for cards and search; made from the text if left out.slugstring: Its address after /blog/.imagestring: Cover picture id.email_subscribersboolean: Email it to the newsletter sign-ups when it’s published.
POST /api/v1/sites/:site/posts/:post/publish
Publish a blog post now, or schedule it. Two steps: this returns a link the person opens to confirm.
MCP tool: publish_post · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).postneeded integer: The post id.atstring: When to publish, as an ISO date and time; leave out for now.confirmboolean: API keys only: publish without the link.
POST /api/v1/sites/:site/posts/:post/unpublish
Take a post off the site; it stays as a draft.
MCP tool: unpublish_post · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).postneeded integer: The post id.
DELETE /api/v1/sites/:site/posts/:post
Delete a blog post.
MCP tool: delete_post · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).postneeded integer: The post id.
GET /api/v1/sites/:site/answers
What visitors sent through the site’s forms, newest first.
MCP tool: list_form_answers · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).limitinteger: How many (up to 200, default 50).unreadboolean: Only ones not read yet.
GET /api/v1/sites/:site/subscribers
Newsletter sign-ups: how many, how many the plan can email, and the latest ones.
MCP tool: list_subscribers · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).limitinteger: How many to list (up to 500, default 50).
POST /api/v1/sites/:site/newsletters
Write a newsletter to the site’s confirmed sign-ups (saved as a draft; send it with send_newsletter). Same text marks as blog posts.
MCP tool: draft_newsletter · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).subjectneeded string: Subject line.bodyneeded string: The text.newsletterinteger: A draft to change; leave out for a new one.
POST /api/v1/sites/:site/newsletters/:newsletter/send
Send a drafted newsletter to the confirmed sign-ups. Two steps: this returns a link the person opens to confirm.
MCP tool: send_newsletter · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).newsletterneeded integer: The draft’s id.confirmboolean: API keys only: send without the link.
GET /api/v1/sites/:site/bookings
Online bookings (add-on): upcoming and from the last 90 days, with who booked and the service.
MCP tool: list_bookings · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).
GET /api/v1/sites/:site/analytics
Visitor numbers: visits, visitors, top pages, where they came from, devices, places, form sends and sign-ups.
MCP tool: get_analytics · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).daysinteger: How many days back (default 30).
GET /api/v1/sites/:site/domain
The site’s own domain, if any, and how far its setup is.
MCP tool: get_domain_status · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).
GET /api/v1/sites/:site/export
A backup of the site: settings, every page’s draft (with its versions in other languages) and every post, as JSON.
MCP tool: export_site · reads only
siteneeded string: The site: its id, or its name after /s/ (handle).
POST /api/v1/sites/:site/import
Put a backup (from export_site) into a site, replacing its pages, posts and settings as drafts.
MCP tool: import_site · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).backupneeded object: The backup JSON.
POST /api/v1/sites/:site/copy
Make a new site that’s a copy of one of yours (pages, posts and look), at a new address.
MCP tool: copy_site · changes your site
siteneeded string: The site: its id, or its name after /s/ (handle).nameneeded string: The copy’s name.handleneeded string: The copy’s free address after /s/.