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