The Sections API enables flexible content modeling within pages through a hierarchical section system. Sections represent discrete content blocks that can be text, images, or groups containing other sections.
Sections are the building blocks of page content, implementing a common interface while supporting multiple content types. The system supports three main section types: TextSection, ImageSection, and GroupSection, each optimized for different content needs.
All sections implement the base Section interface:
interface Section { id: ID! slug: String! name: String!}Rich text content sections with markdown support:
type TextSection implements Section { id: ID! slug: String! name: String! markdown: Markdown! plaintext: String!}
Fields:
markdown(Markdown!) - Rich markdown content of the sectionplaintext(String!) - Plain text version auto-generated from markdown
Image content sections for visual elements:
type ImageSection implements Section { id: ID! slug: String! name: String! source: String}
Fields:
source(String) - URL or path to the image source
Container sections that group other sections hierarchically:
type GroupSection implements Section { id: ID! slug: String! name: String! children: [Section!]! child(section: SlugOrId!): Section}
Fields:
children([Section!]!) - All child sections contained in this groupchild(section: SlugOrId!)- Find a specific child section by slug or ID
Add a new section to a page at a specified position:
mutation AddSection( $page: SlugOrId! $section: SectionInput! $parent: SlugOrId $position: Int) { addSection( page: $page section: $section parent: $parent position: $position ) { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name } } ... on ImageSection { source } }}
Parameters:
page- Target page to add the section tosection- Section configuration (see SectionInput)parent- Optional parent section for nested placementposition- Optional zero-based index position
Update an existing section's content or slug. The ref accepts either a slug or section ID. Edit is a partial update (PATCH): only the fields you provide are changed; omitted fields retain their existing values.
mutation EditSection( $page: SlugOrId! $ref: SlugOrId! $section: SectionInput!) { editSection(page: $page, ref: $ref, section: $section) { id slug name ... on TextSection { markdown plaintext } }}
Parameters:
page- The page containing the section (slug or ID)ref- The section to edit — accepts either a slug ({ slug: "introduction" }) or a section ID ({ id: "sct_..." })section- Fields to update; unset fields are preserved
Delete a section from a page:
mutation RemoveSection($page: SlugOrId!, $ref: SlugOrId!) { removeSection(page: $page, ref: $ref) { id slug sections { id slug name } }}Reposition a section within a page:
mutation MoveSection( $page: SlugOrId! $ref: SlugOrId! $to: Destination!) { moveSection(page: $page, ref: $ref, to: $to) { id slug sections { id slug name } }}Union input type for creating sections of different types:
input SectionInput { group: GroupSectionInput text: TextSectionInput}
Note: Only one field should be specified per section.
Input for creating or updating text sections. All fields are optional — when used with editSection, omitting a field preserves the existing value rather than clearing it.
input TextSectionInput { slug: String markdown: Markdown}
Fields:
slug- New slug for the section. Omit to keep the existing slug.markdown- New markdown content. Omit to keep the existing content.
Input for creating group sections with child sections:
input GroupSectionInput { slug: String children: [SectionInput!]}Specifies where to move a section:
input Destination { parent: SlugOrId index: Int!}
Fields:
parent- Parent section to move under (null for root level)index- Zero-based position within the parent
query GetPageWithSections($pageRef: SlugOrId!) { page(ref: $pageRef) { id slug title sections { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name ... on TextSection { markdown } } } ... on ImageSection { source } } }}query GetSection($pageRef: SlugOrId!, $sectionRef: SlugOrId!) { page(ref: $pageRef) { section(ref: $sectionRef) { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name } } } }}query GetTextSection($pageRef: SlugOrId!, $textRef: SlugOrId!) { page(ref: $pageRef) { text(ref: $textRef) { id slug name markdown plaintext } }}Change a section's slug by passing only slug in the input — existing content is preserved.
Edit a text section's slug:
mutation { editSection( page: { slug: "my-page" } ref: { slug: "introduction" } section: { text: { slug: "new-introduction" } } ) { id slug }}
Edit slug using a section ID as the ref:
mutation { editSection( page: { slug: "my-page" } ref: { id: "sct_O1otxVDlcAIQvdCy" } section: { text: { slug: "new-introduction" } } ) { id slug }}
Edit a group section's slug:
mutation { editSection( page: { slug: "my-page" } ref: { slug: "tutorial-steps" } section: { group: { slug: "guide-steps" } } ) { id slug }}
In all cases the markdown (or children) field is omitted and the existing value is retained.
mutation { addSection( page: { slug: "my-page" } section: { text: { slug: "introduction" markdown: "# Introduction\n\nThis is the introduction section with **bold** text." } } ) { id slug ... on TextSection { markdown plaintext } }}mutation { addSection( page: { slug: "my-page" } section: { group: { slug: "tutorial-steps" children: [ { text: { slug: "step-1" markdown: "## Step 1\n\nFirst, do this..." } } { text: { slug: "step-2" markdown: "## Step 2\n\nThen, do that..." } } ] } } ) { id slug ... on GroupSection { children { id slug name } } }}mutation { moveSection( page: { slug: "my-page" } ref: { slug: "introduction" } to: { parent: { slug: "tutorial-steps" } index: 0 } ) { id sections { id slug name } }}Update content only (slug is preserved):
mutation { editSection( page: { slug: "my-page" } ref: { slug: "introduction" } section: { text: { markdown: "# Updated Introduction\n\nThis content has been updated with new information." } } ) { id slug ... on TextSection { markdown plaintext } }}
Rename only (content is preserved):
mutation { editSection( page: { slug: "my-page" } ref: { slug: "introduction" } section: { text: { slug: "new-introduction" } } ) { id slug }}
Reference by ID (slug or ID are both valid refs):
mutation { editSection( page: { slug: "my-page" } ref: { id: "sct_O1otxVDlcAIQvdCy" } section: { text: { markdown: "# Updated content" } } ) { id slug ... on TextSection { markdown } }}Sections support hierarchical organization through GroupSection containers:
- Root Level: Sections directly attached to a page
- Nested Levels: Sections contained within GroupSection parents
- Deep Nesting: Groups can contain other groups for complex structures
When adding sections with a parent parameter, the section becomes a child of that parent GroupSection. The position parameter controls the order within the parent's children array.
The platform supports rich content through different section types:
- Text Content: Markdown with auto-generated plaintext for search/preview
- Visual Content: Images with flexible source handling
- Structural Content: Groups for organizing related sections
Each type is optimized for its specific use case while maintaining a consistent interface for management operations.