Skip to content

Response Schemas ​

This page documents the common response structures and data formats used across all EngageHQ API endpoints.

Response Envelope ​

All API responses follow a consistent structure:

Success Response ​

json
{
  "success": true,
  "message": "Human-readable success message",
  "data": { /* or array */ },
  "meta": { /* pagination info, if applicable */ }
}
FieldTypeDescription
successbooleanAlways true for successful requests
messagestringHuman-readable description of the result
dataobject|arrayThe requested resource(s)
metaobjectPagination metadata (list endpoints only)

Error Response ​

json
{
  "success": false,
  "message": "Human-readable error message",
  "errors": { /* validation errors, if applicable */ }
}
FieldTypeDescription
successbooleanAlways false for errors
messagestringHuman-readable error description
errorsobject|nullValidation errors by field

Validation Error Example ​

json
{
  "success": false,
  "message": "The given data was invalid.",
  "errors": {
    "per_page": ["The per page must be between 1 and 100."],
    "type": ["The selected type is invalid."]
  }
}

Pagination ​

List endpoints return paginated results with metadata:

json
{
  "meta": {
    "current_page": 1,
    "last_page": 5,
    "per_page": 20,
    "total": 94,
    "links": [
      { "url": null, "label": "« Previous", "active": false },
      { "url": "https://api.../content?page=1", "label": "1", "active": true },
      { "url": "https://api.../content?page=2", "label": "2", "active": false },
      { "url": "https://api.../content?page=3", "label": "3", "active": false },
      { "url": "https://api.../content?page=2", "label": "Next »", "active": false }
    ]
  }
}

Pagination Fields ​

FieldTypeDescription
current_pageintegerCurrent page number (1-indexed)
last_pageintegerLast available page number
per_pageintegerItems per page
totalintegerTotal number of items across all pages
linksarrayNavigation links array
FieldTypeDescription
urlstring|nullFull URL to this page, or null if unavailable
labelstringDisplay label (may contain HTML entities)
activebooleanWhether this is the current page

Pagination Example ​

javascript
async function fetchAllContent(token) {
  let page = 1;
  let allItems = [];

  while (true) {
    const response = await fetch(
      `https://cdn.engagehq.retailsuccessplatform.com/api/v1/public/content?page=${page}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );

    const { data, meta } = await response.json();
    allItems = [...allItems, ...data];

    if (page >= meta.last_page) break;
    page++;
  }

  return allItems;
}

ID Format (Hashkeys) ​

All resource IDs are hashkeys - obfuscated identifiers with a type prefix:

ResourcePrefixExample
Contentcon_con_00000k1L2m3N4o5
Circularcir_cir_00000a1B2c3D4e5
Offerofr_ofr_00000p1Q2r3S4t5
Mediamed_med_00000x1Y2z3A4b5
Productprd_prd_00000m1N2o3P4q5
Organizationorg_org_00000j1K2l3M4n5

ID Format

IDs follow the pattern: {prefix}_{11_alphanumeric_chars}

The prefix indicates the resource type, making IDs self-documenting.

Using Hashkeys ​

Always use the hashkey when making requests:

javascript
// Correct - use the hashkey
const circular = await fetch(`/public/v1/circulars/cir_00000a1B2c3D4e5`);

// Incorrect - never use numeric IDs
const circular = await fetch(`/public/v1/circulars/123`);  // Will fail

Timestamps ​

All timestamps are in ISO 8601 format with timezone:

2024-06-01T14:30:00+00:00

Timestamp Fields ​

FormatExampleDescription
Full2024-06-01T14:30:00+00:00Date, time, and timezone
Date only2024-06-01Used in some metadata

Parsing Timestamps ​

javascript
// Parse ISO 8601 timestamp
const publishedAt = new Date(item.published_at);

// Format for display
console.log(publishedAt.toLocaleDateString());  // "6/1/2024"
console.log(publishedAt.toLocaleTimeString());  // "2:30:00 PM"

// Check if content is expired
const expiresAt = item.expires_at ? new Date(item.expires_at) : null;
const isExpired = expiresAt && expiresAt < new Date();

Content Blocks ​

Content items contain an array of content blocks in the content field. The available block types depend on the content type.

Block Categories ​

EngageHQ supports two categories of content blocks:

CategoryUsed InBlock Count
Slice TypesPages, Articles, Blog Posts8 types
Content SectionsLanding Pages, Homepages13 types

Slice Types (Pages & Articles) ​

Slice types are building blocks for standard content pages and articles.

Available Slice Types ​

TypeNameDescription
textTextRich text content with formatting
imageImageSingle image with optional caption
videoVideoEmbedded video from YouTube or Vimeo
heroHero SectionFull-width banner with text overlay
ctaCall to ActionProminent button with supporting text
gridGridMulti-column content grid
carouselCarouselImage or content slider
testimonialTestimonialCustomer quote with attribution

Slice Structure ​

Each slice follows this structure:

json
{
  "id": "slice_1234567890",
  "slice_type": "text",
  "content": {
    // Type-specific content fields
  }
}

Text Slice ​

json
{
  "id": "slice_1234567890",
  "slice_type": "text",
  "content": {
    "body": "<p>Rich text content with <strong>HTML</strong> formatting.</p>"
  }
}
FieldTypeRequiredDescription
bodystringYesHTML-formatted text content

Image Slice ​

json
{
  "id": "slice_1234567891",
  "slice_type": "image",
  "content": {
    "url": "https://cdn.example.com/images/photo.jpg",
    "alt": "Description of image",
    "caption": "Optional caption text"
  }
}
FieldTypeRequiredDescription
urlstringYesImage URL
altstringYesAlt text for accessibility
captionstringNoOptional caption below image

Video Slice ​

json
{
  "id": "slice_1234567892",
  "slice_type": "video",
  "content": {
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "title": "Product Demo Video"
  }
}
FieldTypeRequiredDescription
urlstringYesYouTube or Vimeo URL
titlestringNoVideo title

Hero Slice ​

json
{
  "id": "slice_1234567893",
  "slice_type": "hero",
  "content": {
    "headline": "Welcome to Our Store",
    "subheadline": "Discover amazing products at great prices",
    "background_image": "https://cdn.example.com/hero-bg.jpg"
  }
}
FieldTypeRequiredDescription
headlinestringYesMain heading text
subheadlinestringNoSupporting text
background_imagestringNoBackground image URL

Call to Action Slice ​

json
{
  "id": "slice_1234567894",
  "slice_type": "cta",
  "content": {
    "headline": "Ready to Get Started?",
    "description": "Join thousands of satisfied customers",
    "button_text": "Sign Up Now",
    "button_url": "/signup"
  }
}
FieldTypeRequiredDescription
headlinestringYesCTA heading
descriptionstringNoSupporting text
button_textstringYesButton label
button_urlstringYesButton link URL

Grid Slice ​

json
{
  "id": "slice_1234567895",
  "slice_type": "grid",
  "content": {
    "columns": 3,
    "items": [
      { "id": "item_1", "title": "Feature 1", "description": "..." },
      { "id": "item_2", "title": "Feature 2", "description": "..." },
      { "id": "item_3", "title": "Feature 3", "description": "..." }
    ]
  }
}
FieldTypeRequiredDescription
columnsintegerNoNumber of columns (2-4, default: 3)
itemsarrayYesArray of grid items
json
{
  "id": "slice_1234567896",
  "slice_type": "carousel",
  "content": {
    "slides": [
      { "id": "slide_1", "image": "...", "caption": "..." },
      { "id": "slide_2", "image": "...", "caption": "..." }
    ],
    "autoplay": true,
    "interval": 5000
  }
}
FieldTypeRequiredDescription
slidesarrayYesArray of slide objects
autoplaybooleanNoAuto-advance slides
intervalintegerNoMilliseconds between slides

Testimonial Slice ​

json
{
  "id": "slice_1234567897",
  "slice_type": "testimonial",
  "content": {
    "quote": "This product changed my life!",
    "author": "Jane Smith",
    "role": "CEO",
    "company": "Acme Corp",
    "avatar": "https://cdn.example.com/avatars/jane.jpg"
  }
}
FieldTypeRequiredDescription
quotestringYesTestimonial text
authorstringYesPerson's name
rolestringNoJob title
companystringNoCompany name
avatarstringNoProfile image URL

Content Sections ​

Content sections are comprehensive page-builder blocks with both content and visual settings. They are used for building pages, articles, landing pages, and homepages.

Available Section Types ​

EngageHQ provides 14 section types for building content:

TypeNameContent TypesDescription
contentContent Blockpage, article, landing, homepageRich text with optional headline and CTA
imageImagepage, article, landing, homepageSingle image with caption and link
videoVideopage, article, landing, homepageEmbedded video (YouTube, Vimeo, direct)
galleryImage Gallerypage, article, landing, homepageMultiple images with layout options
heroHero Sectionpage, landing, homepageFull-width banner with background media
ctaCall to Actionpage, article, landing, homepageConversion-focused action section
featuresFeaturespage, landing, homepageFeature/benefit grid with icons
testimonialsTestimonialspage, article, landing, homepageCustomer quotes and reviews
statsStatisticspage, landing, homepageKey numbers and achievements
teamTeam Memberspage, landingTeam member profiles
htmlCustom HTMLpage, article, landing, homepageCustom HTML code or iframe embeds
formLead FormlandingLead capture form
productsProduct Carouselpage, landing, homepageShowcase products in carousel or grid
couponsCoupon Carouselpage, landing, homepageDisplay coupons and promotional offers

Section Structure ​

Each section has both content (data) and settings (visual configuration):

json
{
  "id": "section_1737456789_abc123def",
  "type": "hero",
  "content": {
    // Type-specific content fields
  },
  "settings": {
    // Visual/layout settings
  }
}

Section IDs

Section IDs follow the pattern section_{timestamp}_{random} and are generated client-side when creating new sections.


Content Block Section ​

Rich text content with optional headline and call-to-action.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "content",
  "content": {
    "headline": "About Our Company",
    "subheadline": "Building the future of retail",
    "body": "<p>We started in 2020 with a simple mission...</p>",
    "cta_text": "Learn More",
    "cta_url": "/about",
    "cta_target": "_self"
  },
  "settings": {
    "anchor_id": "about",
    "max_width": "medium",
    "alignment": "left",
    "background_color": "",
    "text_color": "",
    "padding": "medium"
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoMain heading
subheadlinestringNoSupporting subheading
bodystringNoHTML-formatted rich text content
cta_textstringNoCall-to-action button text
cta_urlstringNoCTA button URL
cta_targetstringNoLink target (_self, _blank)

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID for navigation
max_widthstringsmall, medium, large, fullContent max width
alignmentstringleft, center, rightText alignment
background_colorstringHex colorBackground color
text_colorstringHex colorText color override
paddingstringnone, small, medium, largeVertical padding

Image Section ​

Single image with caption, alt text, and optional link.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "image",
  "content": {
    "image": {
      "url": "https://cdn.example.com/images/photo.jpg",
      "id": "med_00000x1Y2z3A4b5",
      "filename": "photo.jpg"
    },
    "alt_text": "Product showcase image",
    "caption": "Our flagship product in action",
    "link_url": "/products/featured",
    "link_target": "_self"
  },
  "settings": {
    "anchor_id": "",
    "size": "large",
    "alignment": "center",
    "image_fit": "cover",
    "border_radius": "medium",
    "shadow": "medium",
    "lightbox_enabled": true
  }
}

Content Fields ​

FieldTypeRequiredDescription
imageobjectYesImage object with url, id, filename
alt_textstringYesAlt text for accessibility
captionstringNoCaption displayed below image
link_urlstringNoOptional link when image is clicked
link_targetstringNoLink target (_self, _blank)

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
sizestringsmall, medium, large, fullImage size
alignmentstringleft, center, rightImage alignment
image_fitstringcover, contain, fillImage fit mode (default: cover)
border_radiusstringnone, small, medium, large, fullCorner rounding
shadowstringnone, small, medium, largeDrop shadow
lightbox_enabledbooleantrue, falseEnable lightbox on click

Video Section ​

Embedded video from YouTube, Vimeo, or direct URL.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "video",
  "content": {
    "headline": "See It In Action",
    "description": "Watch our product demo video",
    "video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "provider": "auto",
    "thumbnail": {
      "url": "https://cdn.example.com/video-thumb.jpg",
      "id": "med_00000x1Y2z3A4b5"
    }
  },
  "settings": {
    "anchor_id": "demo",
    "aspect_ratio": "16:9",
    "max_width": "large",
    "autoplay": false,
    "loop": false,
    "muted": false,
    "controls": true,
    "background_color": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
descriptionstringNoDescription text
video_urlstringYesVideo URL (YouTube, Vimeo, or direct)
providerstringNoauto, youtube, vimeo, direct
thumbnailobjectNoCustom thumbnail image

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
aspect_ratiostring16:9, 4:3, 1:1, 9:16Video aspect ratio
max_widthstringsmall, medium, large, fullContainer max width
autoplaybooleantrue, falseAuto-play video
loopbooleantrue, falseLoop video
mutedbooleantrue, falseMute audio
controlsbooleantrue, falseShow player controls
background_colorstringHex colorBackground color

Multiple images in grid, carousel, or masonry layout.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "gallery",
  "content": {
    "headline": "Our Gallery",
    "subheadline": "See what we've been up to",
    "images": [
      {
        "image": { "url": "https://cdn.example.com/1.jpg", "id": "med_001" },
        "alt_text": "Image 1",
        "caption": "First image caption",
        "link_url": "",
        "link_target": "_self"
      },
      {
        "image": { "url": "https://cdn.example.com/2.jpg", "id": "med_002" },
        "alt_text": "Image 2",
        "caption": "Second image caption",
        "link_url": "",
        "link_target": "_self"
      }
    ]
  },
  "settings": {
    "anchor_id": "gallery",
    "layout": "grid",
    "columns": 3,
    "gap_size": "medium",
    "aspect_ratio": "auto",
    "image_fit": "cover",
    "lightbox_enabled": true,
    "autoplay": false,
    "autoplay_interval": 5000,
    "show_arrows": true,
    "show_dots": true
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
imagesarrayYesArray of gallery image objects
FieldTypeRequiredDescription
imageobjectYesImage object with url, id
alt_textstringYesAlt text for accessibility
captionstringNoImage caption
link_urlstringNoOptional link URL
link_targetstringNoLink target

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringgrid, carousel, masonryGallery layout
columnsinteger1-6Number of columns
gap_sizestringnone, small, medium, largeGap between images
aspect_ratiostringauto, 1:1, 4:3, 16:9, 3:2Image aspect ratio
image_fitstringcover, contain, fillImage fit mode when aspect ratio is not auto (default: cover)
lightbox_enabledbooleantrue, falseEnable lightbox
autoplaybooleantrue, falseCarousel autoplay
autoplay_intervalintegerMillisecondsTime between slides
show_arrowsbooleantrue, falseShow navigation arrows
show_dotsbooleantrue, falseShow dot indicators

Hero Section ​

Full-width banner with headline, CTAs, and background image/video. Supports multiple slides for carousel behavior and linking to existing hero content items.

Available for: page, landing, homepage

Hero Sections vs Hero Content Items

Hero sections are embedded within pages, landing pages, or homepages. Hero content items are standalone content that can be linked to from hero sections or queried directly for use in carousels.

When creating standalone hero content items, use the metadata.placement field to specify where they should appear:

  • home - Home page carousel
  • page - Content pages
  • landing - Landing pages

See Hero Filtering by Placement in the Content API documentation.

Source Modes ​

Hero sections support two source modes:

ModeDescription
inlineDefine slides directly within the section (default)
linkedLink to an existing published hero content item

Inline Mode Example ​

json
{
  "id": "section_1737456789_abc123def",
  "type": "hero",
  "content": {
    "source_mode": "inline",
    "slides": [
      {
        "id": "slide_1737456789001",
        "headline": "Welcome to Our Store",
        "subheadline": "Discover amazing products at great prices",
        "body": "",
        "background_image": "https://cdn.example.com/hero-bg.jpg",
        "background_image_media": {
          "url": "https://cdn.example.com/hero-bg.jpg",
          "id": "med_00000x1Y2z3A4b5"
        },
        "background_position": "center",
        "background_type": "image",
        "background_video_url": "",
        "image_fit": "cover",
        "overlay_color": "#000000",
        "overlay_opacity": 30,
        "overlay_type": "solid",
        "overlay_gradient_direction": "to-bottom",
        "cta_primary": {
          "text": "Shop Now",
          "url": "/products",
          "style": "primary",
          "target": "_self"
        },
        "cta_secondary": {
          "text": "Learn More",
          "url": "/about",
          "style": "outline",
          "target": "_self"
        }
      },
      {
        "id": "slide_1737456789002",
        "headline": "Summer Sale",
        "subheadline": "Up to 50% off selected items",
        "background_image": "https://cdn.example.com/summer-sale.jpg",
        "background_position": "center",
        "background_type": "image",
        "image_fit": "cover",
        "overlay_color": "#000000",
        "overlay_opacity": 40,
        "overlay_type": "gradient",
        "overlay_gradient_direction": "to-bottom",
        "cta_primary": {
          "text": "Shop Sale",
          "url": "/sale",
          "style": "primary",
          "target": "_self"
        }
      },
      {
        "id": "slide_1737456789003",
        "headline": "Free Shipping This Weekend",
        "subheadline": "Click anywhere to shop the event",
        "background_image": "https://cdn.example.com/free-shipping.jpg",
        "background_position": "center",
        "background_type": "image",
        "image_fit": "cover",
        "overlay_color": "#000000",
        "overlay_opacity": 30,
        "overlay_type": "solid",
        "slide_link": {
          "url": "/promo/free-shipping",
          "target": "_self"
        }
      }
    ]
  },
  "settings": {
    "anchor_id": "",
    "height": "large",
    "text_color": "light",
    "text_alignment": "center",
    "content_width": "medium",
    "autoplay": true,
    "autoplay_interval": 5000,
    "transition": "fade",
    "show_arrows": true,
    "show_dots": true,
    "pause_on_hover": true,
    "parallax": false
  }
}

Linked Mode Example ​

Link to an existing hero content item for centralized management:

json
{
  "id": "section_1737456789_abc123def",
  "type": "hero",
  "content": {
    "source_mode": "linked",
    "linked_hero_id": "con_00000a1B2c3D4e5",
    "slides": []
  },
  "settings": {
    "anchor_id": "",
    "height": "large",
    "text_color": "light",
    "text_alignment": "center",
    "content_width": "medium"
  }
}

When using linked mode with the expand=linked_content query parameter, the linked hero's content is resolved inline. See Linked Content Expansion in the Content API documentation.

Content Fields ​

FieldTypeRequiredDescription
source_modestringNoinline (default) or linked
linked_hero_idstringNoHero content hashkey (when source_mode is linked)
slidesarrayNoArray of slide objects (when source_mode is inline)

Slide Object ​

FieldTypeRequiredDescription
idstringYesUnique slide identifier
headlinestringYesMain heading
subheadlinestringNoSupporting text
bodystringNoAdditional body text
background_imagestringNoBackground image URL
background_image_mediaobjectNoMedia library reference with url and id
background_positionstringNocenter, top, bottom, left, right, top left, top right, bottom left, bottom right (default: center)
background_typestringNoimage, video (default: image)
background_video_urlstringNoDirect video URL (when background_type is video)
image_fitstringNocover, contain, fill (default: cover)
overlay_colorstringNoOverlay color (default: #000000)
overlay_opacityintegerNoOverlay opacity 0-100 (default: 30)
overlay_typestringNosolid, gradient (default: solid)
overlay_gradient_directionstringNoto-bottom, to-top, to-left, to-right, to-bottom-right, to-bottom-left (default: to-bottom)
cta_primaryobjectNoPrimary CTA button (ignored when slide_link.url is set)
cta_secondaryobjectNoSecondary CTA button (ignored when slide_link.url is set)
slide_linkobjectNoWhole-banner link. When url is set, the entire slide is rendered as a single clickable link and CTA buttons are not rendered

CTA Button Object ​

FieldTypeRequiredDescription
textstringYesButton text
urlstringYesButton URL
stylestringNoprimary, secondary, outline, ghost
targetstringNo_self, _blank

A slide-level link that turns the entire hero slide into a single click target. When url is a non-empty string, renderers should wrap the slide in an anchor and must not render cta_primary or cta_secondary (to avoid nested-anchor accessibility issues).

FieldTypeRequiredDescription
urlstringNoDestination URL. If empty or omitted, the slide behaves as a normal slide with CTA buttons
targetstringNo_self (default), _blank

Whole-Banner vs CTA Buttons

A slide is either CTA-driven or whole-banner clickable, not both. Treat slide_link.url as the toggle: when set, hide and ignore the CTA fields; when empty, render the CTAs normally.

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
heightstringsmall, medium, large, fullSection height
text_colorstringdark, light, autoText color scheme
text_alignmentstringleft, center, rightContent alignment
content_widthstringsmall, medium, large, fullContent max width
autoplaybooleantrue, falseAuto-advance slides (default: true)
autoplay_intervalintegerMillisecondsTime between slides (default: 5000)
transitionstringfade, slide, zoom, flipSlide transition effect
show_arrowsbooleantrue, falseShow navigation arrows (default: true)
show_dotsbooleantrue, falseShow navigation dots (default: true)
pause_on_hoverbooleantrue, falsePause autoplay on hover (default: true)
parallaxbooleantrue, falseEnable parallax scrolling effect on background (default: false)

Carousel Behavior

When a hero section has multiple slides, it automatically displays as a carousel. Single-slide heroes display as static banners. Carousel settings (autoplay, transition, etc.) only apply when there are 2+ slides.


Call to Action Section ​

Prominent section designed to drive conversions.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "cta",
  "content": {
    "headline": "Ready to Get Started?",
    "subheadline": "Join thousands of satisfied customers",
    "body": "",
    "cta_text": "Sign Up Now",
    "cta_url": "/signup",
    "cta_target": "_self",
    "secondary_cta_text": "Contact Sales",
    "secondary_cta_url": "/contact",
    "secondary_cta_target": "_self"
  },
  "settings": {
    "anchor_id": "get-started",
    "layout": "centered",
    "background_style": "gradient",
    "background_color": "",
    "background_gradient_from": "#dc2626",
    "background_gradient_to": "#991b1b",
    "background_image": null,
    "background_image_media": null,
    "background_type": "image",
    "background_video_url": "",
    "background_position": "center",
    "image_fit": "cover",
    "overlay_color": "#000000",
    "overlay_opacity": 0,
    "overlay_type": "solid",
    "overlay_gradient_direction": "to-bottom",
    "parallax": false,
    "text_color": "light",
    "padding": "large",
    "border_radius": "medium"
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringYesCTA heading
subheadlinestringNoSupporting text
bodystringNoAdditional body text
cta_textstringYesPrimary button text
cta_urlstringYesPrimary button URL
cta_targetstringNoPrimary button target
secondary_cta_textstringNoSecondary button text
secondary_cta_urlstringNoSecondary button URL
secondary_cta_targetstringNoSecondary button target

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringcentered, left-aligned, right-alignedLayout style
background_stylestringnone, solid, gradient, image, videoBackground style
background_colorstringHex colorSolid background color (when background_style is solid)
background_gradient_fromstringHex colorGradient start color (when background_style is gradient)
background_gradient_tostringHex colorGradient end color (when background_style is gradient)
background_imagestringURLBackground image URL (when background_style is image)
background_image_mediaobjectMedia objectMedia library reference with url, urls, media_id
background_positionstringcenter, top, bottom, left, right, top left, top right, bottom left, bottom rightBackground position (default: center)
background_video_urlstringURLDirect video URL (when background_style is video)
image_fitstringcover, contain, fillImage/video fit mode (default: cover)
overlay_colorstringHex colorOverlay color (default: #000000)
overlay_opacityinteger0-70Overlay opacity percentage (default: 0)
overlay_typestringsolid, gradientOverlay type (default: solid)
overlay_gradient_directionstringto-bottom, to-top, to-left, to-right, to-bottom-right, to-bottom-leftGradient overlay direction (default: to-bottom)
parallaxbooleantrue, falseEnable parallax scrolling effect (default: false)
text_colorstringdark, light, autoText color scheme
paddingstringsmall, medium, largeSection padding
border_radiusstringnone, small, medium, large, fullCorner rounding

Features Section ​

Grid of features/benefits with icons and descriptions.

Available for: page, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "features",
  "content": {
    "headline": "Why Choose Us",
    "subheadline": "Everything you need to succeed",
    "features": [
      {
        "icon": "truck",
        "title": "Fast Delivery",
        "description": "Get your orders in 24 hours",
        "link_url": "/shipping",
        "link_text": "Learn more"
      },
      {
        "icon": "shield-check",
        "title": "Quality Guarantee",
        "description": "100% satisfaction guaranteed",
        "link_url": "",
        "link_text": ""
      },
      {
        "icon": "headphones",
        "title": "24/7 Support",
        "description": "We're here when you need us",
        "link_url": "/support",
        "link_text": "Contact us"
      }
    ]
  },
  "settings": {
    "anchor_id": "features",
    "layout": "grid",
    "columns": 3,
    "alignment": "center",
    "icon_style": "solid",
    "icon_size": "medium",
    "icon_color": "#dc2626",
    "icon_background": "#fee2e2",
    "card_style": "elevated",
    "background_style": "none",
    "background_color": "",
    "background_gradient_from": "",
    "background_gradient_to": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
featuresarrayYesArray of feature objects

Feature Object ​

FieldTypeRequiredDescription
iconstringNoIcon name or URL
titlestringYesFeature title
descriptionstringNoFeature description
link_urlstringNoOptional link URL
link_textstringNoLink text

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringgrid, list, alternatingLayout style
columnsinteger1-4Number of columns
alignmentstringleft, center, rightContent alignment
icon_stylestringsolid, outline, noneIcon rendering style
icon_sizestringsmall, medium, largeIcon size
icon_colorstringHex colorIcon color
icon_backgroundstringHex colorIcon background color
card_stylestringnone, bordered, elevated, filledCard style
background_stylestringnone, solid, gradientBackground style
background_colorstringHex colorSection background (when background_style is solid)
background_gradient_fromstringHex colorGradient start color (when background_style is gradient)
background_gradient_tostringHex colorGradient end color (when background_style is gradient)

Testimonials Section ​

Customer reviews and social proof.

Available for: page, article, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "testimonials",
  "content": {
    "headline": "What Our Customers Say",
    "subheadline": "Don't just take our word for it",
    "testimonials": [
      {
        "quote": "Best shopping experience ever! The quality exceeded my expectations.",
        "author_name": "John Smith",
        "author_title": "Verified Buyer",
        "author_company": "Acme Corp",
        "author_image": {
          "url": "https://cdn.example.com/avatars/john.jpg",
          "id": "med_001"
        },
        "rating": 5
      },
      {
        "quote": "Fast delivery and excellent customer service.",
        "author_name": "Jane Doe",
        "author_title": "Regular Customer",
        "author_company": "",
        "author_image": null,
        "rating": 5
      }
    ]
  },
  "settings": {
    "anchor_id": "testimonials",
    "layout": "carousel",
    "columns": 3,
    "card_style": "bordered",
    "show_rating": true,
    "show_avatar": true,
    "show_company": true,
    "avatar_size": "medium",
    "autoplay": true,
    "autoplay_interval": 5000,
    "background_style": "solid",
    "background_color": "#f9fafb",
    "background_gradient_from": "",
    "background_gradient_to": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
testimonialsarrayYesArray of testimonial objects

Testimonial Object ​

FieldTypeRequiredDescription
quotestringYesTestimonial text
author_namestringYesCustomer name
author_titlestringNoCustomer title/role
author_companystringNoCompany name
author_imageobjectNoAuthor avatar image
ratingintegerNoStar rating (1-5)

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringcarousel, gridLayout style
columnsinteger2-4Grid columns (when layout is grid)
card_stylestringnone, bordered, elevated, filledCard style
show_ratingbooleantrue, falseShow star rating
show_avatarbooleantrue, falseShow author avatar
show_companybooleantrue, falseShow company name
avatar_sizestringsmall, medium, largeAvatar size
autoplaybooleantrue, falseCarousel autoplay (when layout is carousel)
autoplay_intervalintegerMillisecondsTime between slides (when autoplay is true)
background_stylestringnone, solid, gradientBackground style
background_colorstringHex colorSection background (when background_style is solid)
background_gradient_fromstringHex colorGradient start color (when background_style is gradient)
background_gradient_tostringHex colorGradient end color (when background_style is gradient)

Statistics Section ​

Display key numbers and achievements.

Available for: page, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "stats",
  "content": {
    "headline": "By the Numbers",
    "subheadline": "Our impact in numbers",
    "stats": [
      { "value": "10000", "label": "Happy Customers", "prefix": "", "suffix": "+", "icon": "users" },
      { "value": "99", "label": "Satisfaction Rate", "prefix": "", "suffix": "%", "icon": "star" },
      { "value": "24", "label": "Hour Support", "prefix": "", "suffix": "/7", "icon": "clock" },
      { "value": "50", "label": "Store Locations", "prefix": "", "suffix": "+", "icon": "map-pin" }
    ]
  },
  "settings": {
    "anchor_id": "stats",
    "layout": "row",
    "columns": 4,
    "alignment": "center",
    "animated": true,
    "animation_duration": 2000,
    "value_size": "large",
    "value_color": "#dc2626",
    "label_color": "#6b7280",
    "background_style": "solid",
    "background_color": "#f9fafb",
    "background_gradient_from": "",
    "background_gradient_to": "",
    "dividers": true
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
statsarrayYesArray of statistic objects

Stat Object ​

FieldTypeRequiredDescription
valuestringYesThe number to display
labelstringYesDescription label
prefixstringNoText before number (e.g., "$")
suffixstringNoText after number (e.g., "%", "+")
iconstringNoOptional icon name

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringrow, stacked, inlineLayout style
columnsinteger2-6Number of columns
alignmentstringleft, centerContent alignment
animatedbooleantrue, falseAnimate numbers on scroll
animation_durationintegerMillisecondsAnimation duration
value_sizestringmedium, large, xlargeNumber size
value_colorstringHex colorNumber color
label_colorstringHex colorLabel color
background_stylestringnone, solid, gradientBackground style
background_colorstringHex colorBackground color (when background_style is solid)
background_gradient_fromstringHex colorGradient start color (when background_style is gradient)
background_gradient_tostringHex colorGradient end color (when background_style is gradient)
dividersbooleantrue, falseShow dividers between stats

Team Members Section ​

Team member profiles with photos and bios.

Available for: page, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "team",
  "content": {
    "headline": "Meet Our Team",
    "subheadline": "The people behind our success",
    "members": [
      {
        "image": {
          "url": "https://cdn.example.com/team/jane.jpg",
          "id": "med_001"
        },
        "name": "Jane Smith",
        "title": "CEO & Founder",
        "bio": "Jane founded the company in 2020 with a vision to transform retail.",
        "email": "jane@example.com",
        "phone": "",
        "social_links": {
          "linkedin": "https://linkedin.com/in/janesmith",
          "twitter": "https://twitter.com/janesmith",
          "facebook": "",
          "instagram": ""
        }
      }
    ]
  },
  "settings": {
    "anchor_id": "team",
    "layout": "grid",
    "columns": 3,
    "card_style": "elevated",
    "image_style": "circle",
    "image_size": "large",
    "show_bio": true,
    "show_social": true,
    "show_contact": false,
    "alignment": "center",
    "background_style": "none",
    "background_color": "",
    "background_gradient_from": "",
    "background_gradient_to": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
membersarrayYesArray of team member objects

Team Member Object ​

FieldTypeRequiredDescription
imageobjectNoMember photo
namestringYesMember name
titlestringNoJob title
biostringNoShort biography
emailstringNoEmail address
phonestringNoPhone number
social_linksobjectNoSocial media links
social_links.linkedinstringNoLinkedIn URL
social_links.twitterstringNoTwitter URL
social_links.facebookstringNoFacebook URL
social_links.instagramstringNoInstagram URL

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringgrid, cards, listLayout style
columnsinteger2-4Number of columns
card_stylestringminimal, elevated, borderedCard style
image_stylestringcircle, rounded, squarePhoto shape
image_sizestringsmall, medium, largePhoto size
show_biobooleantrue, falseShow biography
show_socialbooleantrue, falseShow social links
show_contactbooleantrue, falseShow email/phone
alignmentstringleft, centerContent alignment
background_stylestringnone, solid, gradientBackground style
background_colorstringHex colorSection background (when background_style is solid)
background_gradient_fromstringHex colorGradient start color (when background_style is gradient)
background_gradient_tostringHex colorGradient end color (when background_style is gradient)

Custom HTML Section ​

Embed custom HTML code, iframes, or third-party widget snippets.

Available for: page, article, landing, homepage

json
{
  "id": "section_1737456789_abc123def",
  "type": "html",
  "content": {
    "title": "Store Locator",
    "body": "<iframe src=\"https://maps.google.com/...\" width=\"100%\" height=\"450\" frameborder=\"0\"></iframe>"
  },
  "settings": {
    "anchor_id": "map",
    "max_width": "full",
    "padding": "medium"
  }
}

Content Fields ​

FieldTypeRequiredDescription
titlestringNoOptional heading displayed above the HTML content
bodystringYesRaw HTML code, iframe embeds, or widget snippets

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID for navigation
max_widthstringnarrow, medium, wide, fullContent max width
paddingstringnone, small, medium, largeVertical padding

Lead Form Section ​

Lead capture or contact form.

Available for: landing (only)

json
{
  "id": "section_1737456789_abc123def",
  "type": "form",
  "content": {
    "headline": "Get In Touch",
    "subheadline": "We'd love to hear from you",
    "description": "Fill out the form below and we'll get back to you within 24 hours.",
    "fields": [
      {
        "type": "text",
        "name": "name",
        "label": "Full Name",
        "placeholder": "Your name",
        "required": true,
        "options": [],
        "validation": "",
        "error_message": ""
      },
      {
        "type": "email",
        "name": "email",
        "label": "Email Address",
        "placeholder": "you@example.com",
        "required": true,
        "options": [],
        "validation": "",
        "error_message": "Please enter a valid email address"
      },
      {
        "type": "phone",
        "name": "phone",
        "label": "Phone Number",
        "placeholder": "(555) 123-4567",
        "required": false,
        "options": [],
        "validation": "",
        "error_message": ""
      },
      {
        "type": "select",
        "name": "interest",
        "label": "What are you interested in?",
        "placeholder": "Select an option",
        "required": true,
        "options": ["Products", "Services", "Partnership", "Other"],
        "validation": "",
        "error_message": ""
      },
      {
        "type": "textarea",
        "name": "message",
        "label": "Message",
        "placeholder": "How can we help you?",
        "required": false,
        "options": [],
        "validation": "",
        "error_message": ""
      }
    ],
    "submit_text": "Send Message",
    "success_message": "Thank you! We'll be in touch soon.",
    "success_redirect_url": "/thank-you",
    "privacy_text": "We respect your privacy and will never share your information.",
    "privacy_link_url": "/privacy",
    "privacy_link_text": "Privacy Policy"
  },
  "settings": {
    "anchor_id": "contact",
    "layout": "stacked",
    "label_position": "above",
    "field_size": "medium",
    "button_style": "primary",
    "button_width": "full",
    "button_alignment": "center",
    "show_required_indicator": true,
    "background_color": "#f9fafb",
    "border_style": "rounded",
    "max_width": "medium"
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoForm heading
subheadlinestringNoForm subheading
descriptionstringNoAdditional description
fieldsarrayYesForm field definitions
submit_textstringNoSubmit button text (default: "Submit")
success_messagestringNoMessage shown after submission
success_redirect_urlstringNoURL to redirect after submission
privacy_textstringNoPrivacy notice text
privacy_link_urlstringNoPrivacy policy URL
privacy_link_textstringNoPrivacy link text

Form Field Object ​

FieldTypeRequiredDescription
typestringYesField type (see below)
namestringYesField name (for form data)
labelstringYesField label
placeholderstringNoPlaceholder text
requiredbooleanNoWhether field is required
optionsarrayNoOptions for select/radio/checkbox
validationstringNoRegex pattern for validation
error_messagestringNoCustom error message

Form Field Types ​

TypeDescription
textSingle-line text input
emailEmail input with validation
phonePhone number input
textareaMulti-line text area
selectDropdown select (requires options)
checkboxCheckbox input
radioRadio button group (requires options)
dateDate picker

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringstacked, inline, two-columnForm layout
label_positionstringabove, floating, hiddenLabel position
field_sizestringsmall, medium, largeInput field size
button_stylestringprimary, secondary, outlineButton style
button_widthstringauto, fullButton width
button_alignmentstringleft, center, rightButton alignment
show_required_indicatorbooleantrue, falseShow * for required fields
background_colorstringHex colorSection background
border_stylestringnone, rounded, pillInput border style
max_widthstringsmall, medium, large, fullForm max width

Product Carousel Section ​

Showcase products in a carousel or grid layout for e-commerce pages.

Available for: page, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "products",
  "content": {
    "headline": "Featured Products",
    "subheadline": "Check out our top picks",
    "source": "manual",
    "products": [
      {
        "product_id": "prd_00000k1L2m3N4o5",
        "title": "Organic Apples",
        "description": "Fresh organic apples from local farms",
        "image": {
          "url": "https://cdn.example.com/products/apples.jpg",
          "id": "med_001"
        },
        "price": "$3.99",
        "compare_price": "$4.99",
        "url": "/products/organic-apples",
        "badge": "Sale"
      }
    ],
    "category_id": "",
    "tag": "",
    "limit": 8,
    "sort_by": "featured",
    "cta_text": "Shop All Products",
    "cta_url": "/products"
  },
  "settings": {
    "anchor_id": "featured-products",
    "layout": "carousel",
    "columns": 4,
    "gap_size": "medium",
    "card_style": "elevated",
    "show_image": true,
    "image_aspect_ratio": "1:1",
    "show_price": true,
    "show_compare_price": true,
    "show_rating": true,
    "show_add_to_cart": true,
    "show_quick_view": false,
    "autoplay": false,
    "autoplay_interval": 5000,
    "show_arrows": true,
    "show_dots": true,
    "background_color": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
sourcestringNoProduct source: manual, category, tag
productsarrayNoManually selected products (when source is manual)
category_idstringNoCategory hashkey (when source is category)
tagstringNoProduct tag (when source is tag)
limitintegerNoMax products to display (default: 8)
sort_bystringNoSort order: featured, newest, price_asc, price_desc
cta_textstringNoFooter CTA button text
cta_urlstringNoFooter CTA button URL

Product Item Object ​

FieldTypeRequiredDescription
product_idstringNoProduct hashkey for dynamic lookup
titlestringYesProduct title
descriptionstringNoShort product description
imageobjectNoProduct image
pricestringYesDisplay price
compare_pricestringNoOriginal/compare-at price
urlstringNoProduct detail page URL
badgestringNoBadge text (e.g., "Sale", "New")

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringcarousel, gridDisplay layout
columnsinteger2-6Number of columns
gap_sizestringnone, small, medium, largeGap between items
card_stylestringnone, bordered, elevated, filledCard style
show_imagebooleantrue, falseShow product image
image_aspect_ratiostring1:1, 4:3, 16:9, autoImage aspect ratio
show_pricebooleantrue, falseShow price
show_compare_pricebooleantrue, falseShow compare-at price
show_ratingbooleantrue, falseShow star rating
show_add_to_cartbooleantrue, falseShow add to cart button
show_quick_viewbooleantrue, falseShow quick view button
autoplaybooleantrue, falseCarousel autoplay
autoplay_intervalintegerMillisecondsTime between slides
show_arrowsbooleantrue, falseShow navigation arrows
show_dotsbooleantrue, falseShow dot indicators
background_colorstringHex colorSection background

Coupon Carousel Section ​

Display coupons and promotional offers for e-commerce pages.

Available for: page, landing

json
{
  "id": "section_1737456789_abc123def",
  "type": "coupons",
  "content": {
    "headline": "Current Offers",
    "subheadline": "Don't miss these great deals",
    "source": "manual",
    "coupons": [
      {
        "offer_id": "ofr_00000p1Q2r3S4t5",
        "code": "SUMMER20",
        "title": "Summer Sale",
        "description": "Save 20% on your entire purchase",
        "discount_text": "20% Off",
        "image": {
          "url": "https://cdn.example.com/offers/summer-sale.jpg",
          "id": "med_001"
        },
        "terms": "Minimum purchase $50. Cannot be combined with other offers.",
        "expires_at": "2024-08-31T23:59:59+00:00",
        "url": "/offers/summer20"
      }
    ],
    "offer_ids": [],
    "limit": 6,
    "cta_text": "View All Offers",
    "cta_url": "/offers"
  },
  "settings": {
    "anchor_id": "offers",
    "layout": "carousel",
    "columns": 3,
    "gap_size": "medium",
    "card_style": "bordered",
    "show_image": true,
    "show_code": true,
    "show_discount": true,
    "show_expiry": true,
    "show_terms": false,
    "show_copy_button": true,
    "show_redeem_button": true,
    "autoplay": true,
    "autoplay_interval": 6000,
    "show_arrows": true,
    "show_dots": true,
    "background_color": ""
  }
}

Content Fields ​

FieldTypeRequiredDescription
headlinestringNoSection heading
subheadlinestringNoSection subheading
sourcestringNoCoupon source: manual, offers
couponsarrayNoManually defined coupons (when source is manual)
offer_idsarrayNoOffer hashkeys (when source is offers)
limitintegerNoMax coupons to display (default: 6)
cta_textstringNoFooter CTA button text
cta_urlstringNoFooter CTA button URL

Coupon Item Object ​

FieldTypeRequiredDescription
offer_idstringNoOffer hashkey for dynamic lookup
codestringNoCoupon code to display/copy
titlestringYesCoupon title
descriptionstringNoCoupon description
discount_textstringNoDiscount display text (e.g., "20% Off")
imageobjectNoCoupon/offer image
termsstringNoTerms and conditions
expires_atstringNoISO 8601 expiration timestamp
urlstringNoOffer detail page URL

Settings ​

FieldTypeOptionsDescription
anchor_idstringAnyHTML anchor ID
layoutstringcarousel, gridDisplay layout
columnsinteger2-4Number of columns
gap_sizestringnone, small, medium, largeGap between items
card_stylestringnone, bordered, elevated, filledCard style
show_imagebooleantrue, falseShow coupon image
show_codebooleantrue, falseShow coupon code
show_discountbooleantrue, falseShow discount text
show_expirybooleantrue, falseShow expiration date
show_termsbooleantrue, falseShow terms and conditions
show_copy_buttonbooleantrue, falseShow copy code button
show_redeem_buttonbooleantrue, falseShow redeem/use button
autoplaybooleantrue, falseCarousel autoplay
autoplay_intervalintegerMillisecondsTime between slides
show_arrowsbooleantrue, falseShow navigation arrows
show_dotsbooleantrue, falseShow dot indicators
background_colorstringHex colorSection background

Rendering Content Sections ​

Basic Section Renderer ​

javascript
function renderSection(section) {
  const { type, content, settings } = section;
  const anchorId = settings.anchor_id ? `id="${settings.anchor_id}"` : '';

  switch (type) {
    case 'content':
      return `
        <section ${anchorId} class="content-block max-w-${settings.max_width} text-${settings.alignment}"
          style="background-color: ${settings.background_color || 'transparent'}; padding: var(--padding-${settings.padding})">
          ${content.headline ? `<h2>${content.headline}</h2>` : ''}
          ${content.subheadline ? `<p class="subheadline">${content.subheadline}</p>` : ''}
          ${content.body ? `<div class="prose">${content.body}</div>` : ''}
          ${content.cta_text ? `
            <a href="${content.cta_url}" target="${content.cta_target}" class="btn btn-primary">
              ${content.cta_text}
            </a>
          ` : ''}
        </section>
      `;

    case 'image':
      const imageHtml = `
        <img
          src="${content.image?.url}"
          alt="${content.alt_text}"
          class="size-${settings.size} radius-${settings.border_radius} shadow-${settings.shadow}"
        />
        ${content.caption ? `<figcaption>${content.caption}</figcaption>` : ''}
      `;
      return `
        <figure ${anchorId} class="image-section align-${settings.alignment}">
          ${content.link_url
            ? `<a href="${content.link_url}" target="${content.link_target}">${imageHtml}</a>`
            : imageHtml
          }
        </figure>
      `;

    case 'hero':
      const bgStyle = settings.background_type === 'image'
        ? `background-image: url(${settings.background_image?.url})`
        : `background-color: ${settings.background_color}`;
      return `
        <section ${anchorId} class="hero hero--${settings.height} text-${settings.text_color}"
          style="${bgStyle}; background-position: ${settings.background_position}">
          ${settings.overlay_opacity > 0 ? `
            <div class="hero-overlay" style="background-color: ${settings.overlay_color}; opacity: ${settings.overlay_opacity / 100}"></div>
          ` : ''}
          <div class="hero-content max-w-${settings.content_width} text-${settings.text_alignment}">
            <h1>${content.headline}</h1>
            ${content.subheadline ? `<p class="hero-subheadline">${content.subheadline}</p>` : ''}
            ${content.body ? `<div class="hero-body">${content.body}</div>` : ''}
            <div class="hero-ctas">
              ${content.cta_text ? `<a href="${content.cta_url}" class="btn btn-primary">${content.cta_text}</a>` : ''}
              ${content.secondary_cta_text ? `<a href="${content.secondary_cta_url}" class="btn btn-secondary">${content.secondary_cta_text}</a>` : ''}
            </div>
          </div>
        </section>
      `;

    case 'features':
      return `
        <section ${anchorId} class="features layout-${settings.layout}"
          style="background-color: ${settings.background_color || 'transparent'}">
          ${content.headline ? `<h2 class="text-${settings.alignment}">${content.headline}</h2>` : ''}
          ${content.subheadline ? `<p class="subheadline">${content.subheadline}</p>` : ''}
          <div class="features-grid columns-${settings.columns}">
            ${content.features.map(f => `
              <div class="feature card-${settings.card_style}">
                ${f.icon ? `<div class="feature-icon icon-${settings.icon_style} icon-${settings.icon_size}"
                  style="color: ${settings.icon_color}; background: ${settings.icon_background}">${f.icon}</div>` : ''}
                <h3>${f.title}</h3>
                ${f.description ? `<p>${f.description}</p>` : ''}
                ${f.link_url ? `<a href="${f.link_url}">${f.link_text || 'Learn more'}</a>` : ''}
              </div>
            `).join('')}
          </div>
        </section>
      `;

    case 'stats':
      const statsBg = settings.background_style === 'gradient'
        ? `background: linear-gradient(to right, ${settings.background_gradient_from}, ${settings.background_gradient_to})`
        : `background-color: ${settings.background_color || 'transparent'}`;
      return `
        <section ${anchorId} class="stats layout-${settings.layout}"
          style="${statsBg}">
          ${content.headline ? `<h2>${content.headline}</h2>` : ''}
          <div class="stats-grid columns-${settings.columns} ${settings.dividers ? 'with-dividers' : ''}">
            ${content.stats.map(s => `
              <div class="stat text-${settings.alignment}">
                ${s.icon ? `<span class="stat-icon">${s.icon}</span>` : ''}
                <span class="stat-value size-${settings.value_size}" style="color: ${settings.value_color}">
                  ${s.prefix}${settings.animated ? `<span data-count="${s.value}">0</span>` : s.value}${s.suffix}
                </span>
                <span class="stat-label" style="color: ${settings.label_color}">${s.label}</span>
              </div>
            `).join('')}
          </div>
        </section>
      `;

    case 'testimonials':
      const testimonialsBg = settings.background_style === 'gradient'
        ? `background: linear-gradient(to right, ${settings.background_gradient_from}, ${settings.background_gradient_to})`
        : `background-color: ${settings.background_color || 'transparent'}`;
      return `
        <section ${anchorId} class="testimonials layout-${settings.layout}"
          style="${testimonialsBg}">
          ${content.headline ? `<h2>${content.headline}</h2>` : ''}
          <div class="testimonials-container ${settings.layout === 'grid' ? `columns-${settings.columns}` : ''}">
            ${content.testimonials.map(t => `
              <div class="testimonial card-${settings.card_style}">
                ${settings.show_rating && t.rating ? `
                  <div class="testimonial-rating">${'★'.repeat(t.rating)}${'☆'.repeat(5 - t.rating)}</div>
                ` : ''}
                <blockquote>"${t.quote}"</blockquote>
                <div class="testimonial-author">
                  ${settings.show_avatar && t.author_image ? `
                    <img src="${t.author_image.url}" alt="${t.author_name}" class="avatar-${settings.avatar_size}" />
                  ` : ''}
                  <div>
                    <strong>${t.author_name}</strong>
                    ${t.author_title ? `<span>${t.author_title}</span>` : ''}
                    ${settings.show_company && t.author_company ? `<span>${t.author_company}</span>` : ''}
                  </div>
                </div>
              </div>
            `).join('')}
          </div>
        </section>
      `;

    default:
      console.warn(`Unknown section type: ${type}`);
      return '';
  }
}

// Render all sections in content
function renderContent(sections) {
  return sections.map(renderSection).join('\n');
}

Vue Component Example ​

vue
<template>
  <component
    :is="getSectionComponent(section.type)"
    :content="section.content"
    :settings="section.settings"
    :id="section.settings.anchor_id || undefined"
  />
</template>

<script setup>
import { defineAsyncComponent } from 'vue';

const props = defineProps({
  section: { type: Object, required: true }
});

const sectionComponents = {
  content: defineAsyncComponent(() => import('./sections/ContentSection.vue')),
  image: defineAsyncComponent(() => import('./sections/ImageSection.vue')),
  video: defineAsyncComponent(() => import('./sections/VideoSection.vue')),
  gallery: defineAsyncComponent(() => import('./sections/GallerySection.vue')),
  hero: defineAsyncComponent(() => import('./sections/HeroSection.vue')),
  cta: defineAsyncComponent(() => import('./sections/CtaSection.vue')),
  features: defineAsyncComponent(() => import('./sections/FeaturesSection.vue')),
  testimonials: defineAsyncComponent(() => import('./sections/TestimonialsSection.vue')),
  stats: defineAsyncComponent(() => import('./sections/StatsSection.vue')),
  team: defineAsyncComponent(() => import('./sections/TeamSection.vue')),
  form: defineAsyncComponent(() => import('./sections/FormSection.vue')),
  products: defineAsyncComponent(() => import('./sections/ProductsSection.vue')),
  coupons: defineAsyncComponent(() => import('./sections/CouponsSection.vue')),
};

function getSectionComponent(type) {
  return sectionComponents[type] || null;
}
</script>

Platform Elements ​

In addition to built-in section types, content sections may include platform elements -- dynamic components registered by consuming platforms and resolved client-side. Platform elements are stored with type: "platform_element" and include platform_key and element_key fields to identify which component to render.

json
{
  "id": "section_1711234567_abc123def",
  "type": "platform_element",
  "source": "platform",
  "platform_key": "ecom360",
  "element_key": "popular-sale-items",
  "content": {},
  "config": {
    "max_items": 12,
    "layout": "carousel"
  },
  "settings": {
    "anchor_id": "",
    "padding": "medium"
  }
}

Platform Element Fields ​

FieldTypeDescription
typestringAlways "platform_element"
sourcestringAlways "platform"
platform_keystringThe platform that owns this element (e.g., ecom360)
element_keystringThe specific element identifier (e.g., popular-sale-items)
contentobjectReserved for future use (currently empty)
configobjectEditor-configured values specific to this element
settingsobjectStandard section settings (padding, max_width, etc.)

Your renderer should check section.type === 'platform_element' and resolve to a platform-specific component using platform_key and element_key.

Full Documentation

See the Platform Elements reference for the registration API, config schema format, and detailed storage structure.


Open Graph Data ​

Content items may include Open Graph metadata for social sharing:

json
{
  "og_data": {
    "title": "Summer Sale Announcement",
    "description": "Don't miss our biggest summer sale event",
    "image": "https://cdn.example.com/images/og-summer.jpg",
    "type": "article"
  }
}
FieldTypeDescription
titlestringOG title (fallback to content title)
descriptionstringOG description
imagestringOG image URL (1200x630 recommended)
typestringOG type (typically "article" or "website")

Using OG Data ​

html
<!-- In your page's <head> -->
<meta property="og:title" content="{{ content.og_data.title }}" />
<meta property="og:description" content="{{ content.og_data.description }}" />
<meta property="og:image" content="{{ content.og_data.image }}" />
<meta property="og:type" content="{{ content.og_data.type || 'article' }}" />

HTTP Status Codes ​

StatusMeaningWhen Used
200OKSuccessful request
400Bad RequestInvalid parameters or missing context
401UnauthorizedMissing or invalid token
403ForbiddenValid token but no access to resource
404Not FoundResource doesn't exist or isn't visible
422Unprocessable EntityValidation errors
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error

Changelog
DateChange
2026-03-24Added platform elements section type and schema documentation.
2026-03-24Added custom types schema documentation.
2026-03-13Added image fit mode, video background, gradient overlay, parallax, and expanded position options.
2026-03-10Added Custom HTML content block type.
2026-03-08Added placement filter to schemas.
2026-02-23Updated for CloudFront CDN delivery.
2026-02-11Added hero placement schema.
2026-02-10Fixed admin UI and API schema discrepancies.
2026-02-04Added section settings schema.
2026-01-28Expanded documentation.
2026-01-21Added location_id parameter.
2026-01-15Initial publication.

EngageHQ Public Content Delivery API