### create_blog_category
Creates a blog category, which is the label posts are grouped and browsed under. slug is required and is the category's URL segment; a duplicate is refused rather than renamed, so a retry cannot create a second one. There is no tool that renames or removes a category: both are dashboard actions.
**Scope:** `write_blogs`
Shopper-facing label, for example Guides.
URL segment, unique in this store, for example guides.
Where it sits in the category list. Lower comes first.
### create_blog_post
Writes a blog post as a DRAFT. Nothing is visible to shoppers until set_blog_post_status publishes it. slug is required and is the post's URL segment; a duplicate is refused rather than renamed, so retrying a call that already worked cannot publish the same article twice. Give the prose as body_html and it is converted to the document the storefront renders; give body only when sending back a document read from get_blog_post.
**Scope:** `write_blogs`
URL segment, unique in this store, for example spring-lookbook. Required; a duplicate is refused rather than renamed.
The headline shoppers read.
The article as a ProseMirror document, which is what get_blog_post returns. Use it to send an existing body back unchanged. Give this or body_html, never both.
The article as HTML: paragraphs, headings, lists, quotes, code, links, images. It is converted to the document format the storefront renders, so anything outside that set is flattened rather than dropped silently. Give this or body, never both.
From list_blog_categories. Omit to leave the post uncategorised.
Absolute http(s) URL of the header image. Use add_media first for local files.
Short summary for the blog listing and link previews.
Shown on the listing. Omit rather than guessing zero.
Absolute http(s) URL of the social sharing image.
### diff_before_publish
Shows exactly what publishing would change for shoppers: which pages have unpublished edits and what those edits are, plus which builder sections would be switched on, off, added, removed or reordered. Reads only, changes nothing. Call this before publish_template or publish_store_layout, and when a merchant asks whether it is safe to publish.
**Scope:** `read_storefront`
Include the line-by-line markup changes. Defaults to true. Set false for a short summary of which pages changed and by how much.
Limit the page comparison to one template, for example home. Omit to compare every page.
### get_blog_post
Reads one blog post, including its body as the ProseMirror document the storefront renders. Call it before editing a post, so the edit starts from what is actually there and the body can be sent back to update_blog_post unchanged where it is not the part being corrected. A connection holding read_blogs alone can only read a published post.
**Scope:** `read_blogs`
From list_blog_posts or create_blog_post.
### get_template
Returns the current draft markup of one template, so an edit starts from what is actually there.
**Scope:** `read_storefront`
The template name, one of: header, home, collection, product, search, cart, 404, footer. Each kind is bound with its own object only; get_commerce_schema says which.
### list_blog_categories
Lists this store's blog categories with their ids, which is where the category_id create_blog_post and update_blog_post file a post under comes from.
**Scope:** `read_blogs`
How many. Defaults to 50.
### list_blog_posts
Lists this store's blog posts, newest first, with each one's id, slug and status. Call this to answer anything about what the store has written, and to get the post_id every other blog tool needs. A connection holding read_blogs alone sees published posts only; one that also holds write_blogs, the authoring client, sees drafts and archived posts too and can narrow to one status.
**Scope:** `read_blogs`
How many, 1 to 100. Defaults to 20.
How many to skip, for the next page. Defaults to 0.
Only posts whose title, excerpt or slug contains this text.
Only draft, published or archived posts. Omit for every status. Requires write_blogs: it selects among unpublished work.
### list_template_revisions
Lists the past published versions of one page, newest first, so a bad publish can be undone. Each entry records what the page looked like BEFORE that publish replaced it, so the newest entry is the version to go back to if the last publish was wrong. Use restore_template_revision with the id.
**Scope:** `read_storefront`
The template name, for example home.
### preview_template
Renders a template and SHOWS the result. The rendered page comes back as something a client can display to the merchant directly, and any client can fetch it by URI, so this is how a page gets LOOKED at rather than only described. It also reports what the render did: the bound HTML, which of your bindings resolved and which came back empty, the page size against its budget, and any reason it could not be served. Call this after every edit and BEFORE publish_template. Nothing is saved and shoppers see nothing. It binds against the store's own products when it has any, and against sample data when it does not, and always says which. A binding to a path that does not exist renders as empty rather than as an error, so this is the only way to find a mistyped path.
**Scope:** `read_storefront`
The template name, one of: header, home, collection, product, search, cart, 404, footer. Each kind is bound with its own object only; get_commerce_schema says which.
ISO 4217 code the prices are rendered in, for example "EUR". Omit for the store default.
Force the data source. "store" fails if the store has published nothing, which is how you check a template against real data rather than a substitute. "sample" uses synthetic data in which every property is populated, which is how you check that a binding is spelled correctly when the store's own record happens to be sparse. Omit for the default: real data when there is any, sample when there is not.
The product or collection handle to render against. Omit to let the store pick one.
Render the translated copy, for example "fr-FR". Omit for what the merchant authored. Worth one call on a translated store: translated strings are longer, and a layout that holds in English can break in German.
Markup to preview WITHOUT saving it. Omit to preview the saved draft. Passing markup here is the fast loop: edit, preview, edit again, and only call update_template once it renders the way you want.
The search term to render a search template against, for example "jacket". Omit for the LANDING state, the page a shopper sees before they have searched anything. A search page renders three states and this is the only way to see the other two: pass a term that matches products for the results state, and one that matches nothing for the empty state. Preview all three before publishing, because the CSS that chooses between them cannot be checked from the landing state alone. Ignored by every other template kind.
### publish_template
Promotes a template's draft to the version shoppers see. Nothing else changes.
**Scope:** `write_storefront`
The template name, one of: header, home, collection, product, search, cart, 404, footer. Each kind is bound with its own object only; get_commerce_schema says which.
### restore_template_revision
Puts a past version of a page back, as a DRAFT. Nothing changes for shoppers until publish_template is called, so the old markup can be previewed first. This is how a bad publish is undone.
**Scope:** `write_storefront`
The revision id from list_template_revisions.
### set_blog_post_status
Publishes a post, takes it back to draft, or archives it. Every move is reversible and each one snapshots the post first, so this is also how a post is retired: there is no delete tool, because deleting a post destroys its body and every revision of it and 404s every link, feed and syndicated copy pointing at that URL. Archiving removes it from the blog and destroys nothing.
**Scope:** `write_blogs`
From list_blog_posts or create_blog_post.
published makes it live; draft takes it off the blog and back to editing; archived retires it without deleting it.
### update_blog_post
Edits a blog post. Only the fields given are changed; everything omitted keeps its stored value, so a call that sends only a title cannot blank the article. Does not change whether shoppers can see it: set_blog_post_status does that. Editing a published post changes what is live immediately.
**Scope:** `write_blogs`
From list_blog_posts or create_blog_post.
Replaces the whole article, given as a ProseMirror document from get_blog_post.
Replaces the whole article, given as HTML. It is not merged with what is there, so read the post first if only part of it is changing. Give this or body, never both.
From list_blog_categories. An empty string un-files the post.
Absolute http(s) URL.
Absolute http(s) URL.
The post's URL segment. Changing it breaks every link already pointing at the old one.
Replaces the whole tag list.
### update_template
Saves markup as the DRAFT of one template. Shoppers keep seeing the published version until publish_template runs. Unsafe markup is rejected with the specific reason, so read the error and fix it.
**Scope:** `write_storefront`
The full template markup, with data-mc bindings.
The template name, one of: header, home, collection, product, search, cart, 404, footer. Each kind is bound with its own object only; get_commerce_schema says which.