---
title: "Fetch Funnel Structure"
method: GET
path: "/funnels/{id}/structure"
tags: ["Funnel"]
---

# Fetch Funnel Structure

`GET /funnels/{id}/structure`

## Request

- Base URL: `https://myworkspace.myclickfunnels.com/api/v2`
- URL: `https://myworkspace.myclickfunnels.com/api/v2/funnels/{id}/structure`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Authorization code: `https://accounts.myclickfunnels.com/oauth/authorize`
    - Token URL: `https://accounts.myclickfunnels.com/oauth/token`
- TypeScript: <https://skmtc.dev/myclickfunnels/apis/clickfunnels-api/docs/funnels/:id/structure/get.ts> (a function with typed inputs; its response is checked against the schema)

A funnel's steps as a single, flat, ordered list — the same top‑to‑bottom flow you see in the funnel builder. Use it to read or visualize how a funnel is laid out.

Each entry in `steps` is one of three kinds:

- **`show_page_step`** — a page. Includes `page` (its `name`, `url`, and the `external` / `sdk_token` flags for externally‑hosted SDK pages) and `show_page_step_id` — the id you hand back as `funnel.show_page_step_id` to swap a page onto this step.
- **`split_test_step`** — an A/B test: a `variants` list, each with a `weight` and its own `steps`.
- **`conditional_split_step`** — routing by a saved contact filter: a `branches` list, always `[matched, unmatched]`, each with its own `steps`.

Splits can nest — a split placed inside a branch shows up inside that branch's `steps`.

**Two things to know when reading it:**

1. **Follow the array order, not `sort_order`.** `sort_order` only numbers a step within its own list, so it repeats across branches and after splits — in the example below the top level runs `0, 1, 0, 1`. The array order is the real sequence. (Separately: when you *create* a step, the `sort_order` you send positions it among the funnel's top‑level steps.)
2. **Branches come back together.** A branch lists only its own steps; afterwards the flow continues at the step right after the split, and every branch ends up there. In the example below, both branches lead on to `Order Form → Thank You`. A split with nothing after it ends the funnel.

The `200` example below is this funnel:

```text
Entry
└─ Conditional Split
   ├─ matched:     VIP Welcome   → Split Test ( Premium Offer A 50% / Premium Offer B 50% )
   └─ unmatched: Guest Welcome → Conditional Split ( Returning Customer / New Customer )
→ Order Form → Thank You          (every path comes back together here)
```

Related: the [Pages skill](https://accounts.myclickfunnels.com/.well-known/pages/skill.md#positioning-a-page-within-a-funnel) (create, position, and swap pages) and the [Funnels skill](https://accounts.myclickfunnels.com/.well-known/funnels/skill.md) (add split tests and conditional splits). When migrating externally-hosted pages to a new domain, this is the read that inventories them: see [Migrate an External Page Domain](https://accounts.myclickfunnels.com/.well-known/sdk/migrate-external-page-domain/skill.md#2-read-and-recursively-inventory-the-funnel).

## Path parameters

- `id` string, required

## Response `200`

OK

- object
  - `funnel` object
    - `id` integer: Funnel ID
    - `public_id` string: Funnel public ID
    - `name` string: Funnel name
  - `steps` object[]: The funnel's visible steps in order (no internal container steps).
    - `id` integer
    - `public_id` string
    - `step_type` string
    - `name` string
    - `sort_order` integer: Position within this step's own container (the top-level sequence, or a single branch/variant) — not globally unique across the flattened list. Walk `steps` in array order to read the visible sequence.
    - `convergence_step_id` integer, nullable: Split steps only. Id of the step where this split's branches/variants reconverge — the first step that runs after the split, which every path continues to (in the example below all paths rejoin at the Order Form, id 696). null when nothing follows the split. The referenced step always appears in this tree.
    - `show_page_step_id` string: show_page_step only — the function public id accepted by `funnel.show_page_step_id` on Create/Update Page.
    - `page` object, nullable: show_page_step only.
      - `id` integer
      - `public_id` string
      - `name` string
      - `url` string
      - `external` boolean
      - `sdk_token` string, nullable: Always present; `null` unless `external` is true.
    - `branches` object[]: conditional_split_step only. Always `[matched, unmatched]`; each branch carries its own flat `steps` array.
      - `branch` 'matched' | 'unmatched'
      - `steps` object[]
    - `variants` object[]: split_test_step only. Each variant carries a `weight` and its own flat `steps` array.
      - `weight` integer
      - `steps` object[]

## Other responses

- `401`: Unauthorized
- `404`: Not Found

## Changes

- **2026-11-03** `511d88b30aea`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/myclickfunnels/apis/clickfunnels-api/changes/funnels/:id/structure/get.md)

---

[API](https://skmtc.dev/myclickfunnels/apis/clickfunnels-api.md) - [All operations](https://skmtc.dev/myclickfunnels/apis/clickfunnels-api/llms.txt) - [OpenAPI document](https://skmtc.dev/myclickfunnels/apis/clickfunnels-api/revisions/511d88b30aea?raw)
