Skip to main content

CMS Page API

Overview

The CMS Page API provides endpoints for managing static content pages in your EverShop store. CMS pages are useful for creating informational content such as About Us, Contact Us, Terms and Conditions, Privacy Policy, and other content that doesn't fit within the product catalog structure.

Two things changed in recent releases that affect every integration:

  • Pages live at the root. A page is served at /<url_key>, not /page/<url_key>. A literal request to /page/<url_key> answers 301 and redirects to /<url_key>.
  • content is a block array, not an HTML string. It is the block-editor document that the admin page builder produces.

Endpoints

Create A CMS Page

Creates a new content page.

Request Schema (application/json)
Field NameField TypeRequired
statusstring or integer ('0', '1', 0, 1)Yes
namestringYes
url_keystring (^[a-z0-9]+(?:-[a-z0-9]+)*$)Yes
contentarray of objectYes
Field NameField TypeRequired
idstringYes
sizenumberYes
columnsarray of objectYes
Field NameField TypeRequired
idstringYes
sizenumberYes
dataobjectYes
meta_titlestringYes
meta_descriptionstringNo
meta_keywordsstringNo
POST/api/pages
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
--data-raw '<JSON DATA>'
https://<your domain>/api/pages
Sample Of Response
{
"data": {
"cms_page_id": 14,
"uuid": "e15da567a66c11edb46b60d819134f39",
"status": 1,
"created_at": "2023-02-07 10:15:32",
"updated_at": "2023-02-07 10:15:32",
"cms_page_description_id": 15,
"cms_page_description_cms_page_id": 14,
"url_key": "about-us",
"name": "About Our Company",
"content": "[{"id":"row-1","size":12,"columns":[{"id":"col-1","size":12,"data":{"blocks":[{"type":"paragraph","data":{"text":"Welcome to our company."}}]}}]}]",
"meta_title": "About Us | Our Company Story",
"meta_keywords": "about us, company history, our story, mission",
"meta_description": "Learn about our company's history, mission, and values.",
"links": [
{
"rel": "cmsPageGrid",
"href": "/admin/pages",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "edit",
"href": "/admin/pages/edit/e15da567a66c11edb46b60d819134f39",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "view",
"href": "/about-us",
"action": "GET",
"types": [
"text/xml"
]
}
]
}
}

Update A CMS Page

Modifies an existing content page. Only status is required — send just the fields you want to change.

Request Schema (application/json)
Field NameField TypeRequired
statusstring or integer ('0', '1', 0, 1)Yes
namestringNo
url_keystring (^[a-z0-9]+(?:-[a-z0-9]+)*$)No
contentarray of objectNo
Field NameField TypeRequired
idstringYes
sizenumberYes
columnsarray of objectYes
Field NameField TypeRequired
idstringYes
sizenumberYes
dataobjectYes
meta_titlestringNo
meta_descriptionstringNo
meta_keywordsstringNo
PATCH/api/pages/433ba97f-8be7-4be9-be3f-a9f341f2b89f
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
--data-raw '<JSON DATA>'
https://<your domain>/api/pages/433ba97f-8be7-4be9-be3f-a9f341f2b89f
Sample Of Response
{
"data": {
"cms_page_id": 14,
"uuid": "433ba97f-8be7-4be9-be3f-a9f341f2b89f",
"status": 1,
"created_at": "2023-02-07 10:15:32",
"updated_at": "2023-02-07 14:18:05",
"cms_page_description_id": 15,
"cms_page_description_cms_page_id": 14,
"url_key": "contact-us",
"name": "Contact Us",
"content": "[]",
"meta_title": "Contact Us | Customer Support",
"meta_keywords": "contact, customer service, support, help",
"meta_description": "Contact our customer support team.",
"links": [
{
"rel": "cmsPageGrid",
"href": "/admin/pages",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "edit",
"href": "/admin/pages/edit/433ba97f-8be7-4be9-be3f-a9f341f2b89f",
"action": "GET",
"types": [
"text/xml"
]
},
{
"rel": "view",
"href": "/contact-us",
"action": "GET",
"types": [
"text/xml"
]
}
]
}
}

Delete A CMS Page

Permanently removes a content page. Its url_rewrite row is removed with it.

Request Schema (application/json)
No request body required
DELETE/api/pages/433ba97f-8be7-4be9-be3f-a9f341f2b89f
curl
-H "Accept: application/json"
-H "Authorization: Bearer <admin JWT token>"
https://<your domain>/api/pages/433ba97f-8be7-4be9-be3f-a9f341f2b89f
Sample Of Response
{
"data": {
"cms_page_id": 14,
"uuid": "433ba97f-8be7-4be9-be3f-a9f341f2b89f",
"status": 1,
"created_at": "2023-02-07 10:15:32",
"updated_at": "2023-02-07 14:18:05",
"cms_page_description_id": 15,
"cms_page_description_cms_page_id": 14,
"url_key": "contact-us",
"name": "Contact Us",
"meta_title": "Contact Us | Customer Support",
"meta_keywords": "contact, customer service, support, help",
"meta_description": "Contact our customer support team."
}
}

The content Field

content is an array of rows. Each row has an id, a size, and a columns array; each column has an id, a size, and a data object holding the block-editor document.

{
"content": [
{
"id": "1a2b3c",
"size": 12,
"columns": [
{
"id": "4d5e6f",
"size": 12,
"data": {
"blocks": [
{ "type": "header", "data": { "text": "About Us", "level": 1 } },
{ "type": "paragraph", "data": { "text": "We build things." } }
]
}
}
]
}
]
}

Sending an HTML string fails validation with Content must be an array. Raw-HTML blocks inside the document are sanitized server-side on every save.

Asymmetric field

You send content as an array, but the REST response returns it as a JSON string. The column is text, so the array is serialized on write and echoed back verbatim. JSON.parse it before using it. The GraphQL CmsPage.content field parses it for you (and falls back to wrapping legacy raw HTML in a single block when the value is not valid JSON).

The layout column was dropped

layout is no longer part of the cms_page table. Sending it is harmless (unknown fields are dropped by the insert projection) but it is never persisted or returned.


URL Key Rules

url_key must match ^[a-z0-9]+(?:-[a-z0-9]+)*$ — lowercase letters, digits and single hyphens between segments, 1 to 255 characters. About Us, about_us, /about-us and about--us are all rejected with a 400.

Beyond the pattern, the save is rejected at the service layer when the slug would be unreachable or ambiguous. These checks run against the live route table and database, so they cannot be expressed in the payload schema:

RejectionMessage
Slug equals a single-segment storefront route (cart, checkout, search, blog, ...)URL key "cart" is reserved by a system route and would be unreachable.
Slug equals an enabled language code (fr, de, ...)URL key "fr" conflicts with an enabled language code and would be unreachable.
Slug already owned by another CMS pageURL key "about-us" is already in use by another cms page.

Collisions across entity types are allowed — a landing page and a CMS page may share a slug, and request-time precedence resolves which one renders.

Renaming Records a Redirect

Changing url_key on an existing page does three things in one transaction: it updates the page, repoints the page's url_rewrite row to the new slug, and records a 302 redirect from the old path to the new one. Old links keep working; you do not need to create the redirect yourself.


Reading Pages

There is no REST endpoint for reading CMS pages. Query them through GraphQL — see the data fetching documentation.