Pages are the site’s tree of web pages. Every page sits under a parent, keeps its content in revisions, and renders through the layout its live revision names. Books, blog posts, FAQ and custom entity records keep their content in revisions too; the traits below say what is true of pages in particular.
API ReferenceContent
Pages
The site’s page tree: list pages, read one by id or by URL, create, edit, roll back, duplicate and delete. A page keeps its content in revisions, so every edit makes a revision, and the request decides whether it goes live.
About pages
Each page has a parent and a position among its siblings, and its path is the chain of slugs. The home page is the root and has no slug.
The Pages moduleContent lives in revisions. One is live; the others are history or drafts. An edit makes a revision, and the request decides whether it goes live.
Revisions, publishing and approvalpublished is a date and time, not a flag. publishAt and unpublishAt schedule a page.
Each revision names a layout, and the layout’s areas hold the content. Changing the layout does not move content between areas.
The layout modelA custom URL replaces the slug path. It is set once the page exists, never in the request that creates it.
Taxonomy, URLs and SEOA translation is a page of its own, linked to the page it translates through sourcePage.
Published pages are in the site search index. Area content is searchable only when it is mapped to a search field.
How indexing worksKey fields
id- integer
- The page id.
name- string
- The live revision’s name. Filter and sort on
activeRevision.name. slug- string
- One segment of the path. The home page has none.
fullPath- string
- The path on the site, honouring a custom URL. Computed: not filterable or sortable.
parent- Page
- The parent page;
nullfor the home page. position- integer
- Order among siblings.
published- datetime
- When the page went, or goes, public;
nullwhen unpublished. activeRevision- PageRevision
- The live revision: its
name,layoutandareasContent. revisions- PageRevision[]
- Every revision, oldest first.
customUrl- CustomUrl
- The custom URL, when one is set.
List pages#
/cdna-api/pages/pages
Lists pages in the order you ask for. Without limit every match comes back, so page through a large tree.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- A list of pages.
totalCountcounts every match, beforelimit. - Model
- Page, in the Reference
Parameters
propertiesquery- selector
- The fields and relations to return, such as
{id,name,fullPath}. A long selector can go in the body of a GET request instead, withX-Body-Has-Parameters: 1. parent.idquery- filter
- Any stored field, or a relation with a dot, filters the list. Prefix the name with
!(not),>or<,%(contains) or|(any of a comma-separated list). orderByquery- string
field:ASCorfield:DESC, comma-separated. Stored fields only:fullPathis computed and answers 500.limitquery- integer
- Records per response. There is no default.
offsetquery- integer
- Records to skip.
pagewithlimitworks too. retrieveUnpublishedquery- 1
- Include unpublished pages.
Filter on stored fields, named exactly as in the page's model, not a computed field or >=. Compare the totalCount with the unfiltered list's to confirm a filter applied.
Example
GET /cdna-api/pages/pages?parent.id=72&orderBy=position:ASC&properties={id,name,fullPath} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json{
"result": "success",
"totalCount": 2,
"data": [
{
"id": 818,
"name": "API Reference",
"fullPath": "/developer-docs/api-reference"
},
{
"id": 1878,
"name": "Reference",
"fullPath": "/developer-docs/reference"
}
]
}Show a page#
/cdna-api/pages/page/{id}
Reads one page by its id. Admin callers get it whether it is published or not.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- One page, directly under
data. - Model
- Page, in the Reference
Parameters
idpathrequired- integer
- The page id.
propertiesquery- selector
- The fields and relations to return, such as
{id,name,fullPath}. A long selector can go in the body of a GET request instead, withX-Body-Has-Parameters: 1.
Dates come back in UTC (+00:00), whatever the site’s time zone.
Example
GET /cdna-api/pages/page/818?properties={id,name,fullPath,published,activeRevision{id,layout{id,name}}} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json{
"result": "success",
"data": {
"id": 818,
"name": "API Reference",
"fullPath": "/developer-docs/api-reference",
"published": "2026-08-31T00:00:00+00:00",
"activeRevision": {
"id": 2215,
"layout": {
"id": 70,
"name": "Hub Module Index"
}
}
}
}{
"result": "error",
"message": "Page or record not found"
}Learn more
Show a page by its URL#
/cdna-api/pages/page/{path}
Finds a page by its path, the way the public site does: a custom URL first, then the chain of slugs. Nested paths work as they are.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- One page, from the site the hostname belongs to.
Parameters
pathpathrequired- string
- The page’s path without the leading slash, such as
developer-docs/api-reference. propertiesquery- selector
- The fields and relations to return, such as
{id,name,fullPath}. A long selector can go in the body of a GET request instead, withX-Body-Has-Parameters: 1.
Example
GET /cdna-api/pages/page/developer-docs/api-reference?properties={id,name,fullPath} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json{
"result": "success",
"data": {
"id": 818,
"name": "API Reference",
"fullPath": "/developer-docs/api-reference"
}
}Create a page#
/cdna-api/pages/page
Creates a page and its first revision in one request. The first revision is the live one.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- The new page and a message, with status 200, not 201.
Parameters
parentbody- id
- The parent page. A page without one is a home page, which cannot have a slug.
slugbody- string
- Made from the revision name when left out.
revisions.namebodyrequired- string
- The page title.
revisions.layoutbodyrequired- id
- Without a layout the page has no areas to fill.
revisions.areasbody- object
- Area values by name, in the form each area’s input type takes.
publishedbody- datetime
truepublishes now, a future datetime schedules, and leaving it out keeps the page unpublished.
A custom URL cannot be set in the request that creates the page. Send it in a second request, once the page exists.
Example
POST /cdna-api/pages/page?properties={id,slug,published,activeRevision{id,name}} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
{
"parent": 1,
"slug": "api-sandbox",
"revisions": {
"name": "API sandbox",
"layout": 30,
"areas": {
"pageSections": [
{
"layout": 40,
"name": "Section A",
"areas": {
"body": "<p>Section A</p>"
}
}
]
}
}
}{
"result": "success",
"data": {
"id": 1885,
"slug": "api-sandbox",
"published": null,
"activeRevision": {
"id": 3169,
"name": "API sandbox"
}
},
"message": "The Page has been added successfully."
}Learn more
Edit a page#
/cdna-api/pages/page/{id}
Changes a page. Content changes go into a revision: patchRevision copies one and changes only what you send, which is what an edit almost always wants.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- A message, with status 200. Ask for fields with
propertiesin the query string.
Parameters
patchRevision.originRevisionbody- id
- The revision to copy. Send the live revision’s id: without it the newest revision is copied, which may not be the live one.
patchRevision.activeRevisionbody- boolean
truemakes the new revision live. Without it the revision is saved and the site does not change.areaContent(name)body- value
- Replaces one area and keeps the rest.
patchAreaCollectionElement(area, n)body- object
- Changes element n of a collection and keeps the others.
revisionsbody- object
- A whole new revision holding only the areas you send. Areas left out are empty.
slug, published, parentbody- page fields
- Changed in the same request as the content.
revisions with an id edits that revision in place, even the live one, and leaves no history. Use patchRevision.
Example
PUT /cdna-api/pages/page/1885?properties={id,activeRevision{id}} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
{
"patchRevision": {
"originRevision": 3182,
"activeRevision": true,
"areaContent(navSection)": "API sandbox",
"patchAreaCollectionElement(pageSections, 2)": {
"areaContent(body)": "<p>Updated through the API</p>"
}
}
}{
"result": "success",
"data": {
"id": 1885,
"activeRevision": {
"id": 3183
}
},
"message": "The Page has been saved successfully."
}{
"result": "error",
"validationErrors": {
"patchRevision.patchAreaCollectionElement(pageSections, 9)": [
{
"message": "layout.area.element_not_found",
"code": "bc165108-5691-e95a-acc2-d62e63766f81",
"propertyPath": "patchRevision.patchAreaCollectionElement(pageSections, 9)"
}
]
},
"message": "layout.area.element_not_found"
}Learn more
Make an earlier revision live#
/cdna-api/pages/page/{id}
Rolls a page back, or forward, to a revision it already has. No new revision is made.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
Parameters
idpathrequired- integer
- The page id.
activeRevisionbodyrequired- id
- A revision of this page. List them with
properties={revisions{id,created}}.
Publishing is separate: making a revision live never changes published.
Example
PUT /cdna-api/pages/page/1885?properties={id} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
{
"activeRevision": 3171
}{
"result": "success",
"data": {
"id": 1885
},
"message": "The Page has been saved successfully."
}Delete a page#
/cdna-api/pages/page/{id}
Deletes a page, its revisions and the pages under it.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
Parameters
idpathrequired- integer
- The page id.
Deleting a large page can outlast a client’s timeout and still finish. Send the request again: a 404 means the first one worked.
Example
DELETE /cdna-api/pages/page/1885 HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json{
"result": "success",
"data": [],
"message": "The Page has successfully been deleted."
}Duplicate a page#
/cdna-api/pages/duplicate-page/{id}
Copies a page next to the original. The copy is unpublished, its name starts with “Copy of” and its slug ends in -copy-1, -copy-2 and so on.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
Parameters
idpathrequired- integer
- The page to copy.
Example
POST /cdna-api/pages/duplicate-page/507 HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json{
"result": "success",
"data": {
"page": {
"id": 507,
"name": "Copy of Create an Outstanding Experience",
"slug": "en-gb-copy-1",
"fullPath": "/en-gb-copy-1",
"parent": 36,
"published": false
}
}
}Move a page#
/cdna-api/pages/pages/move/{id}
Moves a page to a new place in the tree: under another parent at a position from 1. The pages around it shift to make room, and close up where it left. Its URL follows its new parent.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
- Returns
- The saved page under
data.page, and amessage.
Parameters
idpathrequired- integer
- The page id.
parentbody- integer
- The new parent page.
positionbody- integer
- Its place among its new siblings, from 1.
Example
PUT /cdna-api/pages/pages/move/1885 HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
{
"parent": 72,
"position": 1
}Check that a page slug is free#
/cdna-api/pages/pages/check-slug
Answers {"result":"success"} when no page under the parent uses the slug. A slug in use, or one with characters a slug cannot have, answers HTTP 200 too, with "result": "error" and a message. Without parent the message is the untranslated key message.error.slug.parent_empty.
- Access
- Admin users and integrations, with an OAuth access token or an API key.
Parameters
slugbodyrequired- string
- The slug to check.
parentbodyrequired- integer
- The parent the slug must be unique under.
idbody- integer
- A page to leave out of the check, when renaming it.
sitebody- integer
- The site to check in.
Example
POST /cdna-api/pages/pages/check-slug HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
{
"slug": "api-reference",
"parent": 72
}{
"result": "error",
"message": "A record with this slug already exists"
}{
"result": "success"
}{
"result": "error",
"message": "Invalid name for slug"
}