This release adds three new resources, moves several endpoints out of beta, and changes how page and blog-post markup is sent. See the full API Changelog for context.


Entirely new generally available functionality

  • Split Test Steps — Create A/B split tests inside a funnel with weighted variants. Full CRUD: list, create, get, update, delete.
  • Page markup inline — Pass markup on create/update and request it with ?expand=markup on any endpoint if needed. Markup is validated before the page is written. Works similarly for blog posts.
  • Attach/detach products to a page step — Set show_page_step.product_ids on page create/update; new detach endpoint atomically removes products from the step.
  • Blogs API — Public read/write for blogs and blog posts. Manage blogs: list, get, update. Manage blog posts: list, create, get, update, delete. Pass markup on create/update and ?expand=markup on get to work with post content.

Now generally available (out of beta)

  • Funnels APICreate and update are now generally available.
  • Pages APICreate and update are now generally available.
❗️

While getting things out of BETA, some functionality was removed or improved, the most important bits are:

  • Removed GET/POST /api/v2/pages/:page_id/markup and POST /markup/validate. Use ?expand=markup together with page[markup] on the page endpoints instead.
  • Page create renamed the funnel attachment field funnel.after_step_idfunnel.after_show_page_step_id.

New BETA functionality

  • Conditional Split Steps (BETA) — Create filter-based branches inside a funnel. Full CRUD: list, create, get, update, delete.
  • Refine Filters (BETA) — Save reusable filters (contacts, products, etc.) and reference them from other endpoints (e.g. conditional splits). Full CRUD: list, create, get, update, delete.
🚧

BETA endpoints and functionality are subject to breaking changes or removal until they graduate to GA. Any such changes will be announced beforehand and as they happen.



The GET /funnels/{id}/stats and GET /pages/{id}/stats endpoints are now generally available — no feature gate required.

Both endpoints accept a timerange_start / timerange_end window (defaults to the last 30 days, clamped to a 90-day maximum; future end dates clamp to now; inverted windows reset to the default 30 days).

Breaking changes for beta users

  • The legacy stats_timerange_start / stats_timerange_end query params have been removed. Use timerange_start / timerange_end instead.
  • Page stats responses now return summary, funnel, and step as null for pages that are not part of a funnel (previously returned zeroed numeric values).
  • Funnel Stats steps now need to be expanded.

Funnel stats — default response

{
  "funnel": { "id": 3, "public_id": "xYzAbC", "name": "Sales Funnel" },
  "currency": "USD",
  "timerange": {
    "from": "2026-03-22T12:00:00Z",
    "to": "2026-04-21T12:00:00Z"
  },
  "summary": {
    "earnings_per_click": "12.34",
    "upfront_sales": "567.89",
    "upfront_sales_count": 42,
    "recurring_sales": "100.00",
    "average_cart_value": "12.34",
    "pageviews": 999
  },
  "page_public_ids": ["NnAdPE", "kJzvQi"]
}

Pass expand[]=steps to replace page_public_ids with a steps array containing per-step metrics:

{
  "funnel": { "id": 3, "public_id": "xYzAbC", "name": "Sales Funnel" },
  "currency": "USD",
  "timerange": { "from": "2026-03-22T12:00:00Z", "to": "2026-04-21T12:00:00Z" },
  "summary": { "...": "(same as default)" },
  "steps": [
    {
      "name": "Order Page",
      "current_path": "/order",
      "views_all": 100,
      "views_unique": 80,
      "optins": 3,
      "optin_rate": 0.0375,
      "sales_count": 5,
      "sales_rate": 0.0625,
      "sales_value": "500.00",
      "recurring_sales_count": 2,
      "recurring_sales_value": "100.00",
      "earnings_per_view": "5.00",
      "earnings_per_unique_view": "6.25"
    }
  ]
}

Page stats — funnel-linked page

{
  "currency": "USD",
  "timerange": { "from": "2026-03-22T12:00:00Z", "to": "2026-04-21T12:00:00Z" },
  "page": {
    "id": 100,
    "public_id": "abc123",
    "name": "Order Page",
    "current_path": "/order-canonical",
    "type": "funnel_page"
  },
  "funnel": { "id": 3, "public_id": "xYzAbC", "name": "Sales Funnel" },
  "step": {
    "name": "Order Page",
    "current_path": "/order",
    "views_all": 100,
    "views_unique": 80,
    "optins": 3,
    "optin_rate": 0.0375,
    "sales_count": 5,
    "sales_rate": 0.0625,
    "sales_value": "500.00",
    "recurring_sales_count": 2,
    "recurring_sales_value": "100.00",
    "earnings_per_view": "5.00",
    "earnings_per_unique_view": "6.25"
  },
  "summary": { "...": "(mirrors step metrics)" }
}

Page stats — standalone page (not in a funnel)

{
  "currency": "USD",
  "timerange": { "from": "2026-03-22T12:00:00Z", "to": "2026-04-21T12:00:00Z" },
  "page": {
    "id": 200,
    "public_id": "def456",
    "name": "Landing Page",
    "current_path": "/landing",
    "type": "user_page"
  },
  "funnel": null,
  "step": null,
  "summary": null
}

New dedicated stats endpoints are now available for funnels and pages. Use GET /funnels/{id}/stats and GET /pages/{id}/stats to retrieve performance statistics directly from the API. Additionally, page markup can now be read via GET /pages/{id}/markup and fully replaced via POST /pages/{id}/markup. These endpoints are currently available in closed beta — contact us to request access.

Previously, reactivating a Stripe or external subscription would fire both subscription.activated and subscription.reactivated events. The subscription.activated event is now sent only on the first activation — reactivations (from canceled or churned) fire only the subscription.reactivated event. This aligns Stripe and external order behavior with PAI orders and removes the need to deduplicate these events in your integration, which, in some cases, may not be easily feasible or may be error-prone.

The Email APIs have graduated from BETA and are now generally available. This includes four endpoints:

  • Emails::Broadcast — Create, manage, and send email broadcasts
  • Emails::Settings — Read your workspace's configured system and marketing from/reply-to addresses
  • Emails::Template — Manage email templates used by broadcasts
  • Emails::Topic — Manage email topics for subscriber preference management

All endpoints are now stable and ready for production use.

ClickFunnels now supports signing in with Google via OAuth 2.0. Users can connect their Google account from their profile settings and use it to log in, with automatic account linking for verified email addresses.

The Contacts API now exposes email_suppression_reason, is_active, and an email_engagement object containing last_email_sent_at, last_email_opened_at, and last_email_clicked_at. Email engagement data is returned when you pass expand[]=email_engagement in your request. An is_active filter is also available on the contacts index endpoint.

In some cases involving specific Stripe invoice sync timing, the subscription.first_payment_received webhook event could fail to fire, which is now fixed.

Additionally, the V2 order API and webhook payloads now include a recurring_invoices_paid_count field, which lets you identify first-time vs. renewal payments without needing a separate webhook.