Skip to main content
Blog endpoints sit under /api/brands/{brand}/blogs/ with brandAccess middleware. Authenticate with EF-Access-Key.

List Blogs

GET /api/brands/{brand}/blogs
per_page
number
Results per page (1–100, default: 25)
q
string
Search by name
sort
string
newest, oldest, created_at, updated_at
cURL
curl https://app.elasticfunnels.io/api/brands/{brand_id}/blogs \
  -H "EF-Access-Key: your_api_key_here"
{
  "current_page": 1,
  "data": [
    {
      "id": 2,
      "name": "Health Tips Blog",
      "slug": "health-tips",
      "domain_id": 7,
      "status": "published",
      "comments_enabled": false,
      "article_url_pattern": "slug_only",
      "created_at": "2024-10-01T00:00:00.000000Z"
    }
  ],
  "per_page": 25,
  "total": 2,
  "last_page": 1
}

List Blogs (Unpaginated)

GET /api/brands/{brand}/blogs/all
Returns { id, name } for all blogs with a saved config — useful for dropdowns.

Get Blog

GET /api/brands/{brand}/blogs/{blog}
{
  "id": 2,
  "name": "Health Tips Blog",
  "domain_id": 7,
  "brand_template_id": null,
  "slug": "health-tips",
  "article_url_pattern": "slug_only",
  "article_url_segment": null,
  "category_url_segment": "category",
  "tag_url_segment": "tag",
  "search_url_segment": "search",
  "comments_enabled": false,
  "comments_require_email_confirmation": false,
  "seo_settings": [],
  "template": null
}

Create Blog

POST /api/brands/{brand}/blogs
name
string
required
Blog name
domain_id
number
ID of the domain this blog lives on
slug
string
URL slug (kebab-case, max 255). Must be unique per brand + domain.
brand_template_id
number
ID of the template to apply (context=blog)
article_url_pattern
string
slug_only, segment, or category
article_url_segment
string
URL prefix for articles (max 64)
category_url_segment
string
URL prefix for category pages (default: category, max 64)
tag_url_segment
string
URL prefix for tag pages (default: tag, max 64)
search_url_segment
string
URL prefix for search results (default: search, max 64)
comments_enabled
boolean
Enable comment system for articles
comments_require_email_confirmation
boolean
Require email confirmation before comments appear
seo_settings
object
SEO metadata object (meta title, description, OG tags, Twitter card fields)
cURL
curl -X POST https://app.elasticfunnels.io/api/brands/{brand_id}/blogs \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Health Tips Blog",
    "domain_id": 7,
    "slug": "health-tips",
    "article_url_pattern": "slug_only"
  }'
{
  "blog": {
    "id": 2,
    "name": "Health Tips Blog",
    "slug": "health-tips",
    "domain_id": 7,
    "comments_enabled": false,
    "brand_id": 42,
    "created_at": "2024-12-11T10:00:00.000000Z"
  }
}
name is always required — even on PUT/PATCH updates. A partial update that omits name will return a 422 validation error.

Update Blog

PUT /api/brands/{brand}/blogs/{blog}
Same body as Create. name is still required.

Delete Blog

DELETE /api/brands/{brand}/blogs/{blog}
{ "blog": { /* soft-deleted blog object */ } }

Clone Blog

Creates a copy of a blog within the same brand.
POST /api/brands/{brand}/blogs/{blog}/clone
title
string
Name for the cloned blog (max 255). Defaults to "<original name> (Copy)" if omitted.
cURL
curl -X POST https://app.elasticfunnels.io/api/brands/{brand_id}/blogs/2/clone \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"title": "Health Tips Blog v2"}'
{
  "id": 3,
  "blog": { /* cloned BrandBlog model */ }
}

Export Blogs

POST /api/brands/{brand}/blogs/export
filters
array
Filter conditions (same as list query params)
selected_ids
array
Limit export to specific blog IDs
columns
array
Columns to include
{
  "success": true,
  "message": "Export started. You will receive an email when it is ready."
}

Blog Categories

List Categories

GET /api/brands/{brand}/blogs/{blog}/categories
[
  {
    "id": 1,
    "blog_id": 2,
    "name": "Nutrition",
    "slug": "nutrition",
    "hero_image": null,
    "seo_settings": {}
  }
]

Create Category

POST /api/brands/{brand}/blogs/{blog}/categories
name
string
required
Category name (max 255)
slug
string
URL slug. Auto-generated from name if omitted; appends numeric suffix on collision.
hero_image
string
Image URL (max 2048 chars)
seo_settings
object
SEO metadata (meta title, description, OG tags, Twitter card)
cURL
curl -X POST https://app.elasticfunnels.io/api/brands/{brand_id}/blogs/2/categories \
  -H "EF-Access-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "Nutrition", "slug": "nutrition"}'
{
  "id": 1,
  "blog_id": 2,
  "name": "Nutrition",
  "slug": "nutrition"
}

Update Category

PUT /api/brands/{brand}/blogs/{blog}/categories/{category}
Same body as Create (all fields optional on update).

Delete Category

DELETE /api/brands/{brand}/blogs/{blog}/categories/{category}
{ "deleted": true }

Notes

  • Blog slugs must be globally unique per brand_id + domain_id combination
  • The clone endpoint copies the blog’s config, html, css, and interactions to the new blog. Slug uniqueness is handled automatically with a numeric suffix
  • The builder (GET/POST .../blogs/{blog}/builder) and articles CRUD endpoints are managed through the page builder and article editor controllers respectively